我必须将所有依赖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个选项:

  1. 在运行应用程序时设置VM选项。

-Djava.library.path =“C:\你的目录,其中Dll存在”

例:

java -Djava.library.path =“C:\你的目录,其中Dll存在”-jar app.jar

  1. 从应用程序中加载特定的本机库:

a)将包含文件aaa.dll的目录直接放在Java项目下。

b)并将此行放在应用程序的堆栈跟踪顶部: System.loadLibrary(“aaa”)

  1. 在您的应用中使用VM选项:

System.setProperty(“java.library.path”,“C:\你的目录,其中存在Dll”);