我必须将所有相关的 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%
然后我在从 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 的文件夹放到用户 %PATH%,就找不到了。
如果我将 DLL 的文件夹放入系统 %PATH%,它会起作用。
为什么?
更新 2
受此主题启发:System versus user PATH environmental variable...winmerge works only if I add the path to the user PATH
我开始怀疑我的用户 %Path% 是否 太长。因此,我将包含依赖 DLL 的文件夹路径从用户 %PATH% 的 end 移动到 beginning。现在可以用了!
首先,我得出结论,实施 Windows' DLL 查找算法的人存在一些截断问题。我 几乎 认为它是另一个恼人的 Windows 错误。
但我写了另一个 Windows 应用程序,它具有类似的 DLL 依赖关系来证实我的猜测。该应用程序工作正常!所以我必须重新审视我的结论。
我一一检查了我的用户 %PATH% 条目,并将文件夹放在每个可能的位置。最后,我找到了 根本原因。
I have a C:\MinGW\bin
entry in User %PATH%, which happens to contain a
libstdc++-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.
现在这个问题似乎已经解决了。但是另一个出现了,如果我想同时使用我的 DLL 和 MinGW,是否需要来回切换?
更新 3
请查看@AndyThomas 的评论。他提到对直接和间接 DLL 使用 System.loadLibrary()
。这样,我们只需要关心 java.library.path
属性。我认为这是一劳永逸的解决方案。
第一:把所有需要的DLL文件放在同一个目录下
然后:加载本机库 - 为此,您有 3 个选择:
- 在您 运行 您的应用程序时设置 VM 选项。
-Djava.library.path="C:\Your Directory where Dll is
present"
示例:
java -Djava.library.path="C:\Your Directory where Dll is
present" -jar app.jar
- 从应用内加载特定的本机库:
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")
- 在您的应用中使用 VM 选项:
System.setProperty( "java.library.path", "C:\Your Directory where Dll is
present" );
我的 java 应用程序依赖于一个 DLL,而那个 DLL 进一步 依赖于 libstdc++-6.dll
。
我试过:
- 将
libstdc++-6.dll
放入文件夹 - 并将文件夹放入 %PATH%
然后我在从 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 的文件夹放到用户 %PATH%,就找不到了。
如果我将 DLL 的文件夹放入系统 %PATH%,它会起作用。
为什么?
更新 2
受此主题启发:System versus user PATH environmental variable...winmerge works only if I add the path to the user PATH
我开始怀疑我的用户 %Path% 是否 太长。因此,我将包含依赖 DLL 的文件夹路径从用户 %PATH% 的 end 移动到 beginning。现在可以用了!
首先,我得出结论,实施 Windows' DLL 查找算法的人存在一些截断问题。我 几乎 认为它是另一个恼人的 Windows 错误。
但我写了另一个 Windows 应用程序,它具有类似的 DLL 依赖关系来证实我的猜测。该应用程序工作正常!所以我必须重新审视我的结论。
我一一检查了我的用户 %PATH% 条目,并将文件夹放在每个可能的位置。最后,我找到了 根本原因。
I have a
C:\MinGW\bin
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.
现在这个问题似乎已经解决了。但是另一个出现了,如果我想同时使用我的 DLL 和 MinGW,是否需要来回切换?
更新 3
请查看@AndyThomas 的评论。他提到对直接和间接 DLL 使用 System.loadLibrary()
。这样,我们只需要关心 java.library.path
属性。我认为这是一劳永逸的解决方案。
第一:把所有需要的DLL文件放在同一个目录下
然后:加载本机库 - 为此,您有 3 个选择:
- 在您 运行 您的应用程序时设置 VM 选项。
-Djava.library.path="C:\Your Directory where Dll is present"
示例:
java -Djava.library.path="C:\Your Directory where Dll is present" -jar app.jar
- 从应用内加载特定的本机库:
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")
- 在您的应用中使用 VM 选项:
System.setProperty( "java.library.path", "C:\Your Directory where Dll is present" );