JNI依赖库

时间:2009-07-06 13:44:31

标签: java java-native-interface

我正在通过JNI运行库(我没有写它),并在内部调用另一个DLL。我得到一个错误说“找不到依赖库”,除非我把另一个DLL的路径放在系统PATH变量上(我在Windows XP上)。我希望能够在java命令行上处理这个问题,我已经尝试将它添加到-Djava.library.path并添加到类路径中,两者都没有用(我希望-Djava.library.path可以工作)但不是类路径,但都没有工作)。有没有办法做到这一点?

感谢,

杰夫

6 个答案:

答案 0 :(得分:19)

  • 如果您的DLL名称为“MyNativeDLL.dll”,则应在LoadLibrary调用中使用“MyNativeDLL”。
  • 使用Dependency Walker检查MyNativeDLL.dll是否需要任何文件
  • 如果有,请将它们包含在与MyNativeDLL.dll相同的文件夹中 - 一个让它工作的尝试将其他所需文件放在System32文件夹中。

答案 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");