为什么我用本机代码得到这个UnsatisfiedLinkError?

KNe*_*ton 7 java native

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

class HelloWorld {
     private native void print();
     public static void main(String[] args) {
         new HelloWorld().print();
     }
     static {
         System.loadLibrary("HelloWorld");
     }
 }
Run Code Online (Sandbox Code Playgroud)

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

$ /usr/java1.4/bin/java HelloWorld
Exception in thread "main"
java.lang.UnsatisfiedLinkError: no HelloWorld in java.library.path
        at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1491)
        at java.lang.Runtime.loadLibrary0(Runtime.java:788)
        at java.lang.System.loadLibrary(System.java:834)
        at HelloWorld.<clinit>(HelloWorld.java:7)

有小费吗?

小智 13

我认为在收到此错误时,有些要点很有用:

  1. 检查.c文件和生成的文件中的函数名称的一致性( .h)
  2. 基于OS的jni库的名称.例如:在HelloWorld.java中,System.loadLibrary("HelloWorld");
    • Solaris上: 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


Aus*_*ams 11

我遇到了这个问题并通过将我的库重命名为libHelloWorld.soMichael 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");
}
Run Code Online (Sandbox Code Playgroud)

HelloWorld.java:

class HelloWorld {
     private native void print();
     public static void main(String[] args) {
         new HelloWorld().print();
     }
     static {
         System.loadLibrary("HelloWorld");
     }
 }
Run Code Online (Sandbox Code Playgroud)

建设和测试:

$ 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!
Run Code Online (Sandbox Code Playgroud)

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

  • tl; dr只救了我的一天 (2认同)

Mic*_*ers 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也可以用于此.

  • 另一种方法是设置LD_LIBRARY_PATH环境变量. (2认同)

KNe*_*ton 2

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

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

去搞清楚!:)

再次感谢,凯伦