我正在开发一个使用JNI的Java项目。 JNI调用我自己编写的自定义库,比如mylib.dll,这取决于第三方库libsndfile-1.dll。
当我运行我的程序时,它崩溃了
java.lang.UnsatisfiedLinkError: C:\...path...\mylib.dll: Can't find dependent libraries.
我搜索了这个网站(和其他人),我尝试了一些修复:
不说。
有谁知道发生了什么事?
我正在使用MacBook pro(通过Parallels)在Visual Studio 2010中进行开发。我正在使用toshiba笔记本电脑在Windows XP上进行测试。
我很确定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
属性的值。
我有同样的问题,我尝试了所有发布在这里的东西来解决它,但没有一个对我有用。在我的情况下,我正在使用Cygwin来编译dll。似乎JVM试图在虚拟Cygwin路径中找到JRE DLL。我将Cygwin的虚拟目录路径添加到JRE的DLL中,现在可以正常工作了。我做了类似的事情:
SET PATH =“/ cygdrive / c / Program Files / Java / jdk1.8.0_45”;%PATH%
在我的情况下,我试图通过Eclipse中的连接器在Tomcat 7中运行java Web服务。当我将war文件部署到笔记本电脑上的Tomcat 7实例时,应用程序运行良好。该应用程序需要“IBM DB2 9.5”的jdbc类型2驱动程序。由于一些奇怪的原因,Eclispe中的连接器无法查看或使用IBM DB2环境变量中的路径,因此可以将我的笔记本电脑上安装的dll文件作为jcc客户端访问。该错误消息表明它找不到db2jcct2 dll文件,或者无法找到该dll文件的依赖库。最终,我删除了连接器并重建了它。然后它运作正常。我在这里添加此解决方案作为文档,因为我在其他地方找不到这个特定的解决方案。
创建静态库对我有用,使用g++ -static
进行编译。它将依赖库与构建捆绑在一起。
安装Microsoft Visual C ++ 2010 SP1 Redistributable修复它
Visual C++ Redistributable for VS2012
VSU_4\vcredist_x64.exe
或VSU_4\vcredist_x84.exe
,具体取决于您的系统配置dll
文件与您的其他库(例如lib
)一起放在\lib\win32-x86\your dll files
文件夹中。我想通知这个有趣的案例,在尝试了上述所有方法后,错误仍然存在。奇怪的是它适用于Windows 7计算机,但在Windows XP上则不然。然后我使用依赖walker,在Windows XP上找不到VC ++ Runtime作为我的dll要求。安装VC ++ Runtime软件包here后,它就像一个魅力。令我不安的是它一直在告诉无法找到依赖库,而直觉上JNI依赖的dll就在那里,但最终结果是JNI依赖的dll需要另一个依赖的dl。我希望这有帮助。
您需要加载JNI库。
System.loadLibrary从JVM路径(JDK bin路径)加载DLL。
如果要加载带路径的显式文件,请使用System.load()
另见:Difference between System.load() and System.loadLibrary in Java
请验证您的库路径是否正确。当然,您可以使用以下代码检查库路径路径:System.out.println(System.getProperty("java.library.path"));
您可以在启动Java应用程序时指定java.library.path:
java -Djava.library.path=path ...
在将javacv
和opencv
与Eclipse结合使用时,在XP机器上遇到了同样的问题。原来我错过了以下文件:
安装完成后,项目编译并运行正常。
如果使用64位JRE加载32位版本的dll,则可能会出现此问题。这是我的情况。
我在keepsafe找到了一篇很棒的文章,这篇文章经历了我做过的同样的事情。它对我有用,所以希望它也可以帮到你!如果您感兴趣(The Perils of Loading Native Libraries on Android)或只是使用,请阅读
compile 'com.getkeepsafe.relinker:relinker:1.2.3'
并替换
System.loadLibrary("myLibrary");
同
ReLinker.loadLibrary(context, "mylibrary");
我以前有完全相同的问题,最后它解决了。
我将所有依赖的DLL放入存储mylib.dll的同一文件夹中,并确保JAVA编译器可以找到它(如果编译路径中没有mylib.dll,则在编译期间会报告此错误)。您需要注意的重要事项是您必须确保所有依赖库与mylib.dll具有相同的版本,例如,如果您的mylib.dll是发行版,那么您还应该将其所有依赖库的发行版本放在那里。
希望这可以帮助遇到同样问题的其他人。