如何解决JNI项目中的UnsatisfiedLinkError(无法find相关的库)
我正在使用JNI的Java项目。 JNI调用我自己编写的自定义库,让我们说mylib.dll,这取决于第三方库libsndfile-1.dll。
当我运行我的程序时,它崩溃了
java.lang.UnsatisfiedLinkError: C:\...path...\mylib.dll: Can't find dependent libraries.
我search了这个网站(和其他人),我已经尝试了一些修复:
-
我跑了依赖沃克。 DW给出了一些警告 – libsndfile,MPR.DLL和SHLWAPI.DLL所需的两个库有“未parsing的导入” – 但DW FAQ表示可以安全地忽略这些警告。
-
我修复了mylib.dll中的方法名称,正如这里所build议的那样。 方法名已经被编译器弄坏了,但是我添加了链接器标志,现在dll方法名与我的jni头文件中的名称完全匹配。
-
我将所有这些DLL放在相同的目录中 – 与调用它们的.jar相同的目录 – 以确保它们位于正确的PATH上。
没有骰子。
有谁知道发生了什么事?
我正在MacBook Pro上通过Visual Studio 2010进行开发(通过Parallels)。 我正在使用东芝笔记本电脑在Windows XP中进行testing。
我很确定类path和共享库searchpath没有任何关系。 根据The JNI Book ( java.library.path
),在Windows上如果不使用java.library.path
系统属性,则该DLL需要位于当前工作目录或Windows PATH
环境variables中列出的目录中。
更新:
看起来Oracle已经从其网站上删除了PDF。 我已经更新了上面的链接,指向住在得克萨斯大学阿灵顿分校的PDF实例。
另外,您还可以阅读Oracle的JNI规范的HTML版本。 它位于Java网站的Java 8部分,所以希望能在一段时间内出现。
更新2:
至less在Java 8中(我没有检查过早的版本),你可以这样做:
java -XshowSettings:properties -version
find共享库searchpath。 在该输出中查找java.library.path
属性的值。
我想通知这个有趣的案例,经过上述所有的方法,错误仍然存在。 奇怪的是它可以在Windows 7电脑上运行,但是在Windows XP上却不行。 然后我使用依赖沃克,发现在Windows XP上没有VC ++运行时作为我的DLL的要求。 在这里安装VC ++运行时包后,它就像一个魅力。 干扰我的事情是不断的告诉不能find依赖的库,而直观的依赖于JNI的DLL在那里,但是最终certificate依赖JNI的DLL需要另一个依赖的DLL。 我希望这有帮助。
你需要加载你的JNI库。
System.loadLibrary从JVMpath(JDK binpath)加载DLL。
如果要使用path加载显式文件,请使用System.load ()
另请参见: Java中的System.load()和System.loadLibrary之间的区别
安装javacv和opencv与Eclipse兼容的时候,在XP机器上有相同的问题,事实certificate,我错过了以下文件msvcp100.dll和msvcr100.dll一旦这些被安装的项目编译和运行OK
如果你用64位JRE加载32位版本的dll,你可能会遇到这个问题。 这是我的情况。
请validation您的图书馆path是否正确。 当然,你可以使用下面的代码来检查你的库path: System.out.println(System.getProperty("java.library.path"));
启动Java应用程序时,您可以指定java.library.path :
java -Djava.library.path=path ...
我以前有完全一样的问题,最后解决了。
我把所有依赖DLL放到mylib.dll存储在同一个文件夹,并确保JAVA编译器可以find它(如果编译path中没有mylib.dll,将在编译期间报告此错误)。 您需要注意的重要的一点是,您必须确保所有依赖库与mylib.dll具有相同的版本,例如,如果您的mylib.dll是发行版本,那么您还应该将其所有依赖库的发行版本放在那里。
希望这可以帮助其他遇到同样问题的人。
我有同样的问题,我尝试了所有张贴在这里解决它,但没有为我工作。 在我的情况下,我使用Cygwin来编译DLL。 看来,JVM试图在虚拟Cygwinpath中findJRE DLL。 我将Cygwin的虚拟目录path添加到JRE的DLL中,并且现在可以工作。 我做了这样的事情:
SET PATH =“/ cygdrive / c / Program Files / Java / jdk1.8.0_45”;%PATH%
在我的情况下,我试图通过Eclipse中的连接器在Tomcat 7中运行java web服务。 当我在笔记本电脑上将战争文件部署到Tomcat 7的实例时,该应用运行良好。 该应用程序需要“IBM DB2 9.5”的jdbctypes2驱动程序。 出于某种奇怪的原因,Eclispe中的连接器无法查看或使用IBM DB2环境variables中的path,以便作为jcc客户端访问安装在笔记本电脑上的dll文件。 该错误消息要么说,它无法finddb2jcct2 dll文件或无法find该dll文件的依赖库。 最终,我删除了连接器并重build了它。 然后它正常工作。 我在这里添加这个解决scheme作为文档,因为我没有在其他地方find这个具体的解决scheme。
- 简短的回答:对于“无法find依赖库”的错误,请检查您的$ PATH(对应于下面的第3点项目符号)
- 很长的回答:
- 纯Java世界:jvm使用“Classpath”来查找类文件
- JNI世界(java /本地边界):jvm使用“java.library.path”(默认为$ PATH)来查找dll
- 纯原生世界:本地代码使用$ PATH加载其他dll
1)进入' http://tess4j.sourceforge.net/usage.html '点击 – “VS2012的Visual C ++ Redistributable”将其下载并运行(VSU_4 \ vcredist_x64.exe或VSU_4 \ vcredist_x84.exe,具体取决于您的系统configuration)
2把你的dll文件放在lib文件夹和你的库(ex \ lib \ win32-x86 \ dll文件)中。