我必须将所有依赖DLL放入JDK的bin文件夹中吗?
我的java应用程序依赖于DLL,该DLL 进一步依赖于libstdc++-6.dll
。
我尝试过了:
- 将
libstdc++-6.dll
放在一个文件夹中 - 并将文件夹放在%PATH%
然后我遇到了java.lang.Unsatisfied LinkError: The specified procedure could not be found
从Eclipse启动应用程序时java.lang.Unsatisfied LinkError: The specified procedure could not be found
。
但是如果我把libstdc++-6.dll
放到JDK's bin folder
,比如C:\Java\jdk1.6.0_45_32bit\bin
。 它工作正常。
但我不想污染JDK文件夹。 我记得windows会搜索%PATH%来定位依赖的DLL。 为什么我不能在这个问题上使用%PATH%?
更新1
Windows中有2个不同的%PATH%环境变量。
- 用户变量
- 系统变量
我只是偶然发现:
-
如果我将DLL的文件夹放到User%PATH%,则无法找到它。
-
如果我将DLL的文件夹放到System%PATH%,它可以工作。
为什么?
更新2
灵感来自这个线程: 系统与用户PATH环境变量… winmerge只有在我添加路径到用户PATH时才有效
我开始怀疑我的User%Path%可能太长了 。 所以我将包含我的依赖DLL的文件夹路径从User%PATH%的末尾移动到开头 。 它现在有效!
首先,我得出结论,实现Windows的DLL查找算法的人有一些截断问题。 我几乎认为这是另一个恼人的Windows Bug。
但我写了另一个Windows应用程序,它有类似的DLL依赖关系来证实我的猜测。 该应用程序工作正常! 所以我必须回顾一下我的结论。
我逐个检查了我的用户%PATH%条目,并将文件夹放在每个可能的位置。 最后,我找到了根本原因 。
我在User%PATH%中有一个
C:\MinGW\bin
条目,它碰巧包含一个libstdc++-6.dll (977KB)
但不幸的是,它与我需要的(825KB)
不兼容(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 app.jar
- 从应用程序中加载特定的本机库:
a)将包含文件aaa.dll的目录直接放在Java项目下。
b)并将此行放在应用程序的堆栈跟踪顶部: System.loadLibrary(“aaa”)
- 在您的应用中使用VM选项:
System.setProperty(“java.library.path”,“C:\你的目录,其中存在Dll”);