为啥我会在本机代码中收到此 UnsatisfiedLinkError?
Posted
技术标签:
【中文标题】为啥我会在本机代码中收到此 UnsatisfiedLinkError?【英文标题】: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.有什么建议吗?
【问题讨论】:
如果您使用Linux(Ubuntu终端),那么请查看saurabhsharma123k.blogspot.in/2017/07/… 【参考方案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】:
我认为在收到此错误时有些要点会有所帮助:
-
检查 .c 文件和生成的文件 (.h) 中函数名称的一致性
基于操作系统的 jni 库名称。
例如:在 HelloWorld.java 中,
System.loadLibrary("HelloWorld");
索拉里斯:libHelloWorld.so
Linux:libHelloWorld.so
赢:HelloWorld.dll
苹果机:libHelloWorld.jnilib
运行时添加-Djava.library.path=PATH
。 PATH
放置你的 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 应该提供的帮助。以上是关于为啥我会在本机代码中收到此 UnsatisfiedLinkError?的主要内容,如果未能解决你的问题,请参考以下文章
“在 onSaveInstanceState 之后无法执行此操作” - 为啥我会从我的活动的 onResume 方法中收到此异常?