如何在JNI项目中修复UnsatisfiedLinkError(无法找到依赖库)

问题描述 投票:72回答:12

我正在开发一个使用JNI的Java项目。 JNI调用我自己编写的自定义库,比如mylib.dll,这取决于第三方库libsndfile-1.dll。

当我运行我的程序时,它崩溃了

java.lang.UnsatisfiedLinkError:  C:\...path...\mylib.dll: Can't find dependent libraries.

我搜索了这个网站(和其他人),我尝试了一些修复:

  1. 我跑了依赖沃克。 DW给出了一些警告 - libsndfile,MPR.DLL和SHLWAPI.DLL所需的两个库都有“未解析的导入” - 但DW FAQ表示可以安全地忽略这些警告。
  2. 我修复了mylib.dll中的方法名称,如here所示。方法名称在某种程度上被编译器破坏了,但我添加了链接器标志,现在dll方法名称与我的jni头文件中的名称完全匹配。
  3. 我将所有这些DLL放在同一目录中 - 与调用它们的.jar相同的目录 - 以确保它们位于正确的PATH上。

不说。

有谁知道发生了什么事?

我正在使用MacBook pro(通过Parallels)在Visual Studio 2010中进行开发。我正在使用toshiba笔记本电脑在Windows XP上进行测试。

java windows-xp java-native-interface libsndfile
12个回答
45
投票

我很确定classpath和共享库搜索路径彼此之间几乎没有关系。根据The JNI Book(不可否认它是旧的),如果你不使用java.library.path系统属性,在Windows上,DLL需要位于当前工作目录或Windows PATH环境变量中列出的目录中。


更新:

看起来Oracle已从其网站上删除了PDF。我已经更新了上面的链接,指向生活在德克萨斯大学阿灵顿分校的PDF实例。

此外,您还可以阅读Oracle的JNI Specification HTML版本。它存在于Java网站的Java 8部分中,因此希望能够存在一段时间。


更新2:

至少在Java 8中(我没有检查过早期版本)你可以这样做:

java -XshowSettings:properties -version

找到共享库搜索路径。在该输出中查找java.library.path属性的值。


1
投票

我有同样的问题,我尝试了所有发布在这里的东西来解决它,但没有一个对我有用。在我的情况下,我正在使用Cygwin来编译dll。似乎JVM试图在虚拟Cygwin路径中找到JRE DLL。我将Cygwin的虚拟目录路径添加到JRE的DLL中,现在可以正常工作了。我做了类似的事情:

SET PATH =“/ cygdrive / c / Program Files / Java / jdk1.8.0_45”;%PATH%


1
投票

在我的情况下,我试图通过Eclipse中的连接器在Tomcat 7中运行java Web服务。当我将war文件部署到笔记本电脑上的Tomcat 7实例时,应用程序运行良好。该应用程序需要“IBM DB2 9.5”的jdbc类型2驱动程序。由于一些奇怪的原因,Eclispe中的连接器无法查看或使用IBM DB2环境变量中的路径,因此可以将我的笔记本电脑上安装的dll文件作为jcc客户端访问。该错误消息表明它找不到db2jcct2 dll文件,或者无法找到该dll文件的依赖库。最终,我删除了连接器并重建了它。然后它运作正常。我在这里添加此解决方案作为文档,因为我在其他地方找不到这个特定的解决方案。


0
投票

创建静态库对我有用,使用g++ -static进行编译。它将依赖库与构建捆绑在一起。


0
投票

安装Microsoft Visual C ++ 2010 SP1 Redistributable修复它


-2
投票
  1. 转到http://tess4j.sourceforge.net/usage.html并点击Visual C++ Redistributable for VS2012
  2. 下载并运行VSU_4\vcredist_x64.exeVSU_4\vcredist_x84.exe,具体取决于您的系统配置
  3. 将您的dll文件与您的其他库(例如lib)一起放在\lib\win32-x86\your dll files文件夹中。

17
投票

我想通知这个有趣的案例,在尝试了上述所有方法后,错误仍然存​​在。奇怪的是它适用于Windows 7计算机,但在Windows XP上则不然。然后我使用依赖walker,在Windows XP上找不到VC ++ Runtime作为我的dll要求。安装VC ++ Runtime软件包here后,它就像一个魅力。令我不安的是它一直在告诉无法找到依赖库,而直觉上JNI依赖的dll就在那里,但最终结果是JNI依赖的dll需要另一个依赖的dl。我希望这有帮助。


13
投票

您需要加载JNI库。

System.loadLibrary从JVM路径(JDK bin路径)加载DLL。

如果要加载带路径的显式文件,请使用System.load()

另见:Difference between System.load() and System.loadLibrary in Java


5
投票

请验证您的库路径是否正确。当然,您可以使用以下代码检查库路径路径:System.out.println(System.getProperty("java.library.path"));

您可以在启动Java应用程序时指定java.library.path:

java -Djava.library.path=path ...

4
投票

在将javacvopencv与Eclipse结合使用时,在XP机器上遇到了同样的问题。原来我错过了以下文件:

  • msvcp100.dll
  • msvcr100.dll

安装完成后,项目编译并运行正常。


3
投票

如果使用64位JRE加载32位版本的dll,则可能会出现此问题。这是我的情况。


2
投票
  • 简短回答:对于“找不到依赖库”错误,请检查$ PATH(对应下面的项目符号#3)
  • 答案很长: 纯java世界:jvm使用“Classpath”来查找类文件 JNI世界(java / native boundary):jvm使用“java.library.path”(默认为$ PATH)来查找dll 纯原生世界:本机代码使用$ PATH加载其他dll

2
投票

我在keepsafe找到了一篇很棒的文章,这篇文章经历了我做过的同样的事情。它对我有用,所以希望它也可以帮到你!如果您感兴趣(The Perils of Loading Native Libraries on Android)或只是使用,请阅读

compile 'com.getkeepsafe.relinker:relinker:1.2.3'

并替换

System.loadLibrary("myLibrary");

ReLinker.loadLibrary(context, "mylibrary");

1
投票

我以前有完全相同的问题,最后它解决了。

我将所有依赖的DLL放入存储mylib.dll的同一文件夹中,并确保JAVA编译器可以找到它(如果编译路径中没有mylib.dll,则在编译期间会报告此错误)。您需要注意的重要事项是您必须确保所有依赖库与mylib.dll具有相同的版本,例如,如果您的mylib.dll是发行版,那么您还应该将其所有依赖库的发行版本放在那里。

希望这可以帮助遇到同样问题的其他人。

© www.soinside.com 2019 - 2024. All rights reserved.