【问题标题】: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)

有什么建议吗?

【问题讨论】:

标签: java native


【解决方案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】:

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

  1. 检查 .c 文件和生成的文件 (.h) 中函数名称的一致性
  2. 基于操作系统的 jni 库名称。 例如:在 HelloWorld.java 中,System.loadLibrary("HelloWorld");
    • 索拉里斯:libHelloWorld.so
    • Linux:libHelloWorld.so
    • 赢:HelloWorld.dll
    • 苹果机:libHelloWorld.jnilib
  3. 运行时添加-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 应该提供的帮助。
    猜你喜欢
    • 2013-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-14
    相关资源
    最近更新 更多