我必须将所有依赖的 DLL 放入 JDK 的 bin 文件夹中吗? [英] Must I place all dependent DLLs into the JDK's bin folder?
问题描述
我的 java 应用程序依赖于一个 DLL,而那个 DLL 进一步依赖于 libstdc++-6.dll
.
我试图:
- 将
libstdc++-6.dll
放在一个文件夹中 - 并将文件夹放入 %PATH%
然后我遇到了java.lang.Unsatisfied LinkError: The specified procedure could not be found
从 Eclipse 启动应用程序时.
但是如果我把 libstdc++-6.dll
放入 JDK 的 bin 文件夹
,说 C:Javajdk1.6.0_45_32bitin代码>.它工作正常.
但是我不想污染JDK文件夹.我记得 Windows 会搜索 %PATH% 来定位依赖的 DLL.为什么我在这个问题中不能使用 %PATH%?
更新 1
Windows 中有 2 个不同的 %PATH% 环境变量.
- 用户变量
- 系统变量
我只是偶然发现:
如果我将 DLL 的文件夹放在用户 %PATH% 中,则无法找到它.
如果我将 DLL 的文件夹放到系统 %PATH% 中,它就可以工作.
为什么?
更新 2
受此线程启发:系统与用户 PATH 环境变量...只有当我将路径添加到用户 PATH 时,winmerge 才有效
我开始怀疑我的用户 %Path% 是否太长.因此,我将包含我的依赖 DLL 的文件夹路径从用户 %PATH% 的 end 移动到 beginning.它现在有效!
首先,我得出结论,实现 Windows 的 DLL 查找算法的人存在一些截断问题.我几乎认为这是另一个烦人的 Windows 错误.
但我编写了另一个具有类似 DLL 依赖项的 Windows 应用程序来证实我的猜测.该应用程序运行良好!所以我必须回顾我的结论.
我一一检查了我的用户 %PATH% 条目,并将文件夹放置到每个可能的位置.最后,我找到了根本原因.
<块引用>我在用户 %PATH% 中有一个 C:MinGWin
条目,它恰好包含一个libstdc++-6.dll (977KB)
但不幸的是,它不兼容用我需要的(825KB)
.仅当我将文件夹放在 MinGW 之前才有效.所以它实际上是 %PATH% 分辨率期间的 DLL 冲突.
现在这个问题似乎解决了.但是又出现了一个,如果我想同时使用我的 DLL 和 MinGW,我需要来回切换吗?
更新 3
请查看@AndyThomas 的评论.他提到对直接和间接 DLL 使用 System.loadLibrary()
.这样,我们只需要关心 java.library.path
属性.我认为这是一个一劳永逸的解决方案.
第一:把你需要的所有DLL文件放在同一个目录下
然后:加载本机库 - 为此,您有 3 个选项:
- 在运行应用时设置 VM 选项.
<块引用>
-Djava.library.path="C:Dll 所在的目录礼物"
示例:
<块引用>java -Djava.library.path="C:Dll 所在的目录呈现"-jar 应用.jar
- 从应用内加载特定的原生库:
<块引用>
a) 将包含文件 aaa.dll 的目录直接放在 Java 项目下.
b) 将此行放在您应用的堆栈跟踪顶部:System.loadLibrary("aaa")
- 在您的应用中使用 VM 选项:
<块引用>
System.setProperty( "java.library.path", "C:Your Directory where Dll is呈现");
My java application depends on a DLL, and that DLL further depends on libstdc++-6.dll
.
I tried to:
- placed the
libstdc++-6.dll
in a folder - and put the folder in the %PATH%
Then I meet the java.lang.Unsatisfied LinkError: The specified procedure could not be found
when launching application from Eclipse.
But if I put the libstdc++-6.dll
into the JDK's bin folder
, say C:Javajdk1.6.0_45_32bitin
. It works fine.
But I don't want to pollute the JDK folder. I remember windows will search %PATH% to locate dependent DLLs. Why can't I use the %PATH% in this issue?
Update 1
There are 2 different %PATH% environment variables in Windows.
- User variables
- System variables
I just accidentally find that:
If I put the DLL's folder to User %PATH%, it cannot be found.
If I put the DLL's folder to System %PATH%, it works.
Why?
Update 2
Inspired by this thread:System versus user PATH environmental variable...winmerge works only if I add the path to the user PATH
I start to wonder maybe my User %Path% is too long. So I moved the folder path containing my dependent DLL from the end of User %PATH% to the beginning. It works now!
At first, I conclude that one who implemented the Windows' DLL lookup algorithm has some truncation issue. And I almost consider it as another annoying Windows Bug.
But I wrote another Windows application which has similar DLL dependencies to confirm my guess. That application works fine! So I have to review my conclusion.
I checked my User %PATH% entry one by one, and place the folder to each possible location. And finally, I find the root cause.
I have a
C:MinGWin
entry in User %PATH%, which happens to contain alibstdc++-6.dll (977KB)
but unfortunately, which isn't compatible with the one I need(825KB)
. It only works if I place my folder before MinGW. So it's actually DLL collision during %PATH% resolution.
Now this issue seems resolved. But another one comes up, do I need to switch back and forth if I want to use both my DLL and the MinGW?
Update 3
Please check the comment by @AndyThomas. He mentioned using System.loadLibrary()
for both direct and indirect DLLs. This way, all we need to care about is the java.library.path
property. I think that's a once-for-all solution.
First: put all DLL files you need in the same directory
Then: Load native libs - to do so you have 3 options:
- Set VM Options while you run your app.
-Djava.library.path="C:Your Directory where Dll is present"
Example:
java -Djava.library.path="C:Your Directory where Dll is present" -jar app.jar
- Load specific native library from within the app:
a) Place the directory that contains the file aaa.dll directly under the Java project.
b) And place this line on the top of stack trace of your app: System.loadLibrary("aaa")
- Use VM options from within your app:
System.setProperty( "java.library.path", "C:Your Directory where Dll is present" );
这篇关于我必须将所有依赖的 DLL 放入 JDK 的 bin 文件夹中吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!