为啥我会在本机代码中收到此 UnsatisfiedLinkError?

Posted

技术标签:

【中文标题】为啥我会在本机代码中收到此 UnsatisfiedLinkError?【英文标题】:Why am I getting this UnsatisfiedLinkError with native code?为什么我会在本机代码中收到此 UnsatisfiedLinkError? 【发布时间】:2010-10-20 04:26:07 【问题描述】:

我有一个名为 HelloWorld.so 的库和一个包含以下内容的程序 HelloWorld.java:

class HelloWorld 
     private native void print();
     public static void main(String[] args) 
         new HelloWorld().print();
     
     static 
         System.loadLibrary("HelloWorld");
     
 

现在,当我尝试运行 HelloWorld.java 时出现此错误:

$ /usr/java1.4/bin/java HelloWorld 线程“主”中的异常 java.lang.UnsatisfiedLinkError:java.library.path 中没有 HelloWorld 在 java.lang.ClassLoader.loadLibrary(ClassLoader.java:1491) 在 java.lang.Runtime.loadLibrary0(Runtime.java:788) 在 java.lang.System.loadLibrary(System.java:834) 在 HelloWorld.(HelloWorld.java:7)

有什么建议吗?

【问题讨论】:

如果您使用Linux(Ubuntu终端),那么请查看saurabhsharma123k.blogspot.in/2017/07/… 【参考方案1】:

我遇到了这个问题,并通过将我的库重命名为 libHelloWorld.so 并遵循 Michael Myers 的建议来解决它。我在 Arch Linux 64 位上。

HelloWorld.c:

#include <jni.h>
#include <stdio.h>
#include "HelloWorld.h"

/* shamelessly stolen from the book 'The Java Native Interface: Programmer's
   Guide and Specification' */
JNIEXPORT void JNICALL
Java_HelloWorld_print (JNIEnv *env, jobject obj) 
    printf("Hello World!\n");

HelloWorld.java:

class HelloWorld 
     private native void print();
     public static void main(String[] args) 
         new HelloWorld().print();
     
     static 
         System.loadLibrary("HelloWorld");
     
 

构建和测试:

$ javac HelloWorld.java
$ javah -classpath . HelloWorld
$ gcc -shared -fPIC -I $JAVA_HOME/include -I $JAVA_HOME/include/linux HelloWorld.c -o libHelloWorld.so
$ java -classpath . -Djava.library.path=. HelloWorld
Hello World!

tl;dr:将 lib 放在库文件名的开头

【讨论】:

tl;博士刚刚拯救了我的一天 就像一个魅力。我的 JAVA_HOME 没有设置,所以我必须使用完整路径 -Djava.library.path=. 为我完成了这项工作,谢谢!【参考方案2】:

我认为在收到此错误时有些要点会有所帮助:

    检查 .c 文件和生成的文件 (.h) 中函数名称的一致性 基于操作系统的 jni 库名称。 例如:在 HelloWorld.java 中,System.loadLibrary("HelloWorld"); 索拉里斯:libHelloWorld.so Linux:libHelloWorld.so 赢:HelloWorld.dll 苹果机:libHelloWorld.jnilib 运行时添加-Djava.library.path=PATHPATH 放置你的 jni 库

这是我的参考资料:https://blogs.oracle.com/moonocean/entry/a_simple_example_of_jni

【讨论】:

【参考方案3】:

HelloWorld.so 在哪里?您可能需要使用命令行参数"-Djava.library.path" 指定其父目录。

例如,如果它在"/path/libs/HelloWorld.so" 中,则在调用java 时添加-Djava.library.path=/path/libs 作为选项。例如,在我的一个项目中是"-Djava.library.path=lib"

编辑:Dan Dyer 指出环境变量LD_LIBRARY_PATH 也可以用于此。

【讨论】:

.so 扩展名是否也需要明确说明? 编辑澄清(它实际上是包含 .so 文件的文件夹的路径)。 @erickson:谢谢,看起来确实更好。 另一种方法是设置 LD_LIBRARY_PATH 环境变量。【参考方案4】:

@mmyers 感谢您的回复。我们发现我们所要做的就是将 System.loadLibrary 更改为 System.load 并将完整路径 + 文件名作为参数传递,就像一个魅力一样。

甚至在这样做之前,我们尝试使用“-D”参数并设置 LD_LIBRARY_PATH,但没有成功。

去图吧! :)

再次感谢, 凯伦

【讨论】:

这太奇怪了。 loadLibrary 的行为应该相同,只是它要求库位于路径上。这就是 -Djava.libary.path 应该提供的帮助。

以上是关于为啥我会在本机代码中收到此 UnsatisfiedLinkError?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我会收到此错误? “孩子未申报?

为啥我会收到此 OpenCV 错误断言失败?

为啥我会收到此 Webpack 加载程序错误?

“在 onSaveInstanceState 之后无法执行此操作” - 为啥我会从我的活动的 onResume 方法中收到此异常?

知道为啥我会收到此错误吗?

NPM 启动错误上的 ENOENT。为啥我会收到此错误,为啥要查找“我的图片”目录?