7

我有一个名为 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.<clinit>(HelloWorld.java:7)

有小费吗?

4

4 回答 4

15

我遇到了这个问题,并通过将我的库重命名为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库文件名的开头

于 2013-07-09T22:08:38.907 回答
13

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

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

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

于 2013-12-09T10:11:29.280 回答
7

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

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

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

于 2009-04-17T18:29:43.570 回答
2

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

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

去搞清楚!:)

再次感谢,凯伦

于 2009-04-20T16:26:02.360 回答