我正在通过JNI运行库(我没有写它),并在内部调用另一个DLL。我得到一个错误说“找不到依赖库”,除非我把另一个DLL的路径放在系统PATH变量上(我在Windows XP上)。我希望能够在java命令行上处理这个问题,我已经尝试将它添加到-Djava.library.path并添加到类路径中,两者都没有用(我希望-Djava.library.path可以工作)但不是类路径,但都没有工作)。有没有办法做到这一点?
感谢,
杰夫
答案 0 :(得分:19)
答案 1 :(得分:6)
通过在所有DLL上以反向依赖顺序使用System.load(),我能够在不将任何DLL放在PATH上的情况下工作。为了清楚起见,我在所有依赖DLL上调用System.load(),而不仅仅是JNI DLL。您不必在Windows附带的DLL上调用System.load()(它们位于PATH上)。
我在一个网络应用程序中这样做,其中一个jar包含了解压缩的DLL。你的情况似乎更简单,所以我认为它应该有效。我一般都遵循这里的解决方案:How to make a JAR file that includes DLL files?
答案 2 :(得分:2)
这对我帮助很大。 还管理加载使用cygwin构建的JNI dll:
首先:
/* conditioned if OS is windows because also need it to work in Linux env. */
System.loadLibrary("cygwin1");
然后:
System.loadLibrary("mylib");
在Windows上,这需要设置java.library.path以匹配两个库位置。
如果从Eclipse运行,则此设置可能会被java构建路径中的“本机库位置”替换(在JRE库设置中)。
然而,仍然觉得这有点棘手。
答案 3 :(得分:0)
我已经使用JNA成功地将一个文件夹注入到PATH变量中。如果您希望在应用程序旁边部署依赖DLL而不会污染全局环境或弄乱显式DLL加载顺序,则可以将其用作解决方法。
然而,我不清楚类加载器生命周期如何影响它。我只在NetBeans模块系统下尝试过这种技术,但是如果你查看loadLibrary的ClassLoader类代码,你会看到它缓存了一些路径变量。可能需要也可能不需要创建新的类加载器来加载库。
缺点是你需要使用JNA或JNI。此外,它似乎是一个相当严重的黑客。有关如何使用JNA设置环境变量的示例,请参阅here。
答案 4 :(得分:0)
对我来说,制作一个静态版本是可行的,它可以编译为:
g++ -static
它将依赖库添加到构建本身中。
答案 5 :(得分:0)
我有类似的问题。我的要求是在Windows环境中加载以下库:
System.loadLibrary("ibex-java");
以我为例,我已将-Djava.library.path=C:\projetos\platform\windows\ibex
配置到存储所有必需dll的文件夹。
C:\projetos\platform\windows\ibex>dir
21/08/2020 14:49 <DIR> .
21/08/2020 14:49 <DIR> ..
21/08/2020 07:47 <DIR> ibex
21/08/2020 14:49 128.108 ibex-java.dll
21/08/2020 14:49 8.554 ibex-java.dll.a
21/08/2020 14:49 6.582.641 ibex.dll
21/08/2020 14:49 5.577.792 ibex.dll.a
21/08/2020 07:47 938.157 libgcc_s_dw2-1.dll
21/08/2020 14:49 6.349.752 libibex.a
21/08/2020 07:47 1.508.122 libstdc++-6.dll
但是,当我尝试加载该库时,抛出了以下错误:
Caused by: java.lang.UnsatisfiedLinkError: C:\platform\windows\ibex\ibex-java.dll: Can't find dependent libraries
我们可以看到,所有相关的dll位于库路径的同一文件夹中。但是,单行System.loadLibrary("ibex-java");
无法自动加载它们。解决此问题的一种方法是将库路径放在Windows的PATH
环境变量中,但是我不喜欢这个想法。
就我而言,我找到了一个更好的解决方案,找到了DLL依赖项并手动加载了这些库。例如:
System.loadLibrary("libgcc_s_dw2-1");
System.loadLibrary("libstdc++-6");
System.loadLibrary("ibex");
System.loadLibrary("ibex-java");