java 为什么我使用本机代码收到此 UnsatisfiedLinkError?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/761639/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 13:40:19  来源:igfitidea点击:

Why am I getting this UnsatisfiedLinkError with native code?

javanative

提问by KNewton

I have a library called HelloWorld.so and a program HelloWorld.java with this content:

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

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

Now when I try to run HelloWorld.java I get this error:

现在,当我尝试运行 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)

Any tips?

有小费吗?

采纳答案by KNewton

@mmyers Thank you for responding. We found out that all we had to do was change System.loadLibrary to System.load and pass the full path + filename as argument, worked like a charm.

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

Even before doing so, we tried using the "-D" parameter and setting LD_LIBRARY_PATH but we weren't successful.

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

Go figure! :)

去搞清楚!:)

Thanks again, Karen

再次感谢,凯伦

回答by Gonnix

I think some points are helpful when getting this error:

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

  1. Check consistency of function name in .c files and generated files (.h)
  2. Name of jni library based on OS. Ex: In HelloWorld.java,System.loadLibrary("HelloWorld");
    • Solaris: libHelloWorld.so
    • Linux: libHelloWorld.so
    • Win: HelloWorld.dll
    • Mac: libHelloWorld.jnilib
  3. When running, add -Djava.library.path=PATH. PATHto place where you put your jni library
  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 库的位置

Here is my reference: https://blogs.oracle.com/moonocean/entry/a_simple_example_of_jni

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

回答by Austin Adams

I had this problem and fixed it by renaming my library to libHelloWorld.soand following Michael Myers's suggestion. I'm on Arch Linux 64-bit.

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

HelloWorld.c:

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:

HelloWorld.java

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

Building and testing:

构建和测试:

$ 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: put libat the beginning of the library's filename

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

回答by Michael Myers

Where is HelloWorld.so located? You probably need to specify its parent directory using the command-line parameter "-Djava.library.path".

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

For example, if it's in "/path/libs/HelloWorld.so", add -Djava.library.path=/path/libsas an option when invoking java. For instance, it's "-Djava.library.path=lib"on one of my projects.

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

Edit:Dan Dyer points out that the environment variable LD_LIBRARY_PATHalso can be used for this.

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