JNI发生UnsatisfiedLinkError错误

4

.h file

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

JNIEXPORT void JNICALL Java_NativePackage_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj)   {
printf("Hello world!\n");
return;
}

Java

package NativePackage;

public class HelloWorld {
public native void displayHelloWorld();

static {
    System.loadLibrary("hello");
}

public static void main(String[] args) {
    new HelloWorld().displayHelloWorld();
}
}

.c文件

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

JNIEXPORT void JNICALL Java_NativePackage_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj){
printf("Hello world!\n");
return;
}

我已经使用编译器编译了我的.c文件

gcc -I /Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/include/ -I  /Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/include/darwin/ -fPIC -o hello -c   HelloWorldImp.c 

然而,尝试使用java NativePackage/HelloWorld运行会产生以下错误:
java  -Djava.library.path=NativePackage/ NativePackage/HelloWorld

Exception in thread "main" java.lang.UnsatisfiedLinkError: no hello in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1857)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1119)
at NativePackage.HelloWorld.<clinit>(HelloWorld.java:7)

我正在运行MAC OS X 10.10操作系统。


应该是 java -Djava.library.path=NativePackage/ NativePackage.HelloWorld。你把 'hello' 共享库放在哪里了? - user207421
在NativePackage/目录下,我也不确定共享库的命名应该是只有hello还是libhello.so。 - Ahmed Ebaid
2
尝试使用-shared标志进行编译,在Mac OS X上库的命名方案为libXXX.dylib - Samuel Audet
谢谢Samuel,你的答案是正确的。 - Ahmed Ebaid
3个回答

5

尝试使用

System.load("/home/project/lib/libhello.so");

提供库的绝对路径。

当我遇到同样的问题时,这个方法对我很有帮助。


1
这个运行得很好,但是在OS X上命名不正确,在Linux上也是如此。另外,我遇到了编译问题。 - Ahmed Ebaid

4

看起来,使用正确的命名方案 libhello.dylib 和选项 -shared 可以使 OS X 正常工作。

gcc -I /Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/include/ -I /Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/include/darwin/  -o libhello.dylib -shared HelloWorldImp.c

在Mac中,.dylib代替了.so。 - peresisUser

0

针对 macOS Monterey 12.6.1 的最新答案

HelloWorld.c

#include <jni.h>        // JNI header provided by JDK
#include <stdio.h>      // C Standard IO Header
#include "HelloWorld.h"   // Generated
 
// Implementation of the native method sayHello()
JNIEXPORT void JNICALL Java_HelloWorld_someNativeMethod(JNIEnv *env, jobject thisObj) {
   printf("Hello World!\n");
   return;
}

HelloWorld.java

class HelloWorld {
    private native void someNativeMethod();
    public static void main(String[] args) {
        new HelloWorld().someNativeMethod();
    }
    static {
        // must be word between lib and .dylib, e.g. libMyNative.dylib
        System.loadLibrary("MyNative");
    }
}

运行

# compile java - generates HelloWorld.h and HelloWorld.class
javac -h . HelloWorld.java

# compile native c files
gcc -I "$JAVA_HOME/include" -I "$JAVA_HOME/include/darwin" -dynamiclib -o libMyNative.dylib -shared HelloWorld.c

# run all
java -Djava.library.path=. HelloWorld

在macOS Monterey 12.6.1上测试过

$ echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/amazon-corretto-17.jdk/Contents/Home

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接