java.lang.UnsatisfiedLinkError: TestJni.print(LA;)V error on Ubuntu
java.lang.UnsatisfiedLinkError: TestJni.print(LA;)V error on Ubuntu
我知道这是一个经常出现的问题,在网上搜索后,问题仍然没有解决。 -Djava.library.path 已添加到命令中。
这是我的 java 文件
public class TestJni
{
public native void print(A a);
static{
System.loadLibrary("MyJni");
}
public static void main(String []args){
new TestJni().print(new A());
}
}
class A{
void show(){
System.out.println("In a show function");
}
}
我正在尝试创建一个实例 'a',它是 A class。
将其传递给本机方法 print 并让本机方法调用 show() 方法。
将 .java 编译成 .class
javac TestJni.java
现在我有三个文件:A.class TestJni.class TestJni.java
使用
javah -classpath . TestJni
获取 .h 文件,如下所示:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class TestJni */
#ifndef _Included_TestJni
#define _Included_TestJni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: TestJni
* Method: print
* Signature: (LA;)V
*/
JNIEXPORT void JNICALL Java_TestJni_print
(JNIEnv *, jobject, jobject);
#ifdef __cplusplus
}
#endif
#endif
通过
将其重命名为MyJni.h
mv TestJni.h MyJni.h
由
创建MyJni.c
vim MyJni.c
MyJni.c的内容是:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#include "MyJni.h"
/* Header for class TestJni */
#ifndef _Included_TestJni
#define _Included_TestJni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: TestJni
* Method: print
* Signature: (LA;)V
*/
JNIEXPORT void JNICALL Java_TestJni_print
(JNIEnv *env, jobject obj, jobject o){
jclass cls = (*env)->GetObjectClass(env, o);
jmethodID mid = (*env)->GetMethodID(env, cls, "show", "()V");
(*env)->CallVoidMethod(env, o, mid);
}
#ifdef __cplusplus
}
#endif
#endif
通过
构建.so文件
gcc -fPIC -shared -o libMyJni.so MyJni.c -I. -I$JAVA_HOME/include -I$JAVA_HOME/include/linux
现在我的目录中有 5 个文件 [A.class libMyJni.so MyJni.c MyJni.h TestJni.class TestJni.java]: /home/grid/code/tmp
运行 java 程序:
java -cp . -Djava.library.path=. TestJni
现在我得到的错误是
Exception in thread "main" java.lang.UnsatisfiedLinkError: TestJni.print(LA;)V
at TestJni.print(Native Method)
at TestJni.main(TestJni.java:10)
我在 Ubuntu 14.10 下编码,gcc 程序是默认程序。
我真的不知道出了什么问题。
请帮我改正程序。
非常感谢您!!!
您可以尝试使用 System.load
。 iirc System.loadLibrary
从默认位置加载 .so/.dll 文件。 System.load
应该使用 .so/.dll 文件的绝对路径。
删除
#ifndef _Included_TestJni
#define _Included_TestJni
...
#endif
来自源文件。您已经 #define
在 header 中添加了 include guard,因此这有效地注释掉了代码。
删除 #include "MyJni.h"
或
#ifndef _Included_TestJni
#define _Included_TestJni
//..
#endif
Exception in thread "main" java.lang.UnsatisfiedLinkError: TestJni.print(LA;)V
这通常发生在 JNI 无法在您的库中找到符号定义时。你可以使用nm
分析你调用的JNI函数,看看它是否在你的库中定义和导出。
$ nm libMyJni.so
00000000000005ac T Java_TestJni_print
0000000000200e40 a _DYNAMIC
0000000000200fe8 a _GLOBAL_OFFSET_TABLE_
w _Jv_RegisterClasses
0000000000200e20 d __CTOR_END__
0000000000200e18 d __CTOR_LIST__
我知道这是一个经常出现的问题,在网上搜索后,问题仍然没有解决。 -Djava.library.path 已添加到命令中。
这是我的 java 文件
public class TestJni
{
public native void print(A a);
static{
System.loadLibrary("MyJni");
}
public static void main(String []args){
new TestJni().print(new A());
}
}
class A{
void show(){
System.out.println("In a show function");
}
}
我正在尝试创建一个实例 'a',它是 A class。 将其传递给本机方法 print 并让本机方法调用 show() 方法。 将 .java 编译成 .class
javac TestJni.java
现在我有三个文件:A.class TestJni.class TestJni.java
使用
javah -classpath . TestJni
获取 .h 文件,如下所示:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class TestJni */
#ifndef _Included_TestJni
#define _Included_TestJni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: TestJni
* Method: print
* Signature: (LA;)V
*/
JNIEXPORT void JNICALL Java_TestJni_print
(JNIEnv *, jobject, jobject);
#ifdef __cplusplus
}
#endif
#endif
通过
将其重命名为MyJni.hmv TestJni.h MyJni.h
由
创建MyJni.cvim MyJni.c
MyJni.c的内容是:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
#include "MyJni.h"
/* Header for class TestJni */
#ifndef _Included_TestJni
#define _Included_TestJni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: TestJni
* Method: print
* Signature: (LA;)V
*/
JNIEXPORT void JNICALL Java_TestJni_print
(JNIEnv *env, jobject obj, jobject o){
jclass cls = (*env)->GetObjectClass(env, o);
jmethodID mid = (*env)->GetMethodID(env, cls, "show", "()V");
(*env)->CallVoidMethod(env, o, mid);
}
#ifdef __cplusplus
}
#endif
#endif
通过
构建.so文件gcc -fPIC -shared -o libMyJni.so MyJni.c -I. -I$JAVA_HOME/include -I$JAVA_HOME/include/linux
现在我的目录中有 5 个文件 [A.class libMyJni.so MyJni.c MyJni.h TestJni.class TestJni.java]: /home/grid/code/tmp
运行 java 程序:
java -cp . -Djava.library.path=. TestJni
现在我得到的错误是
Exception in thread "main" java.lang.UnsatisfiedLinkError: TestJni.print(LA;)V
at TestJni.print(Native Method)
at TestJni.main(TestJni.java:10)
我在 Ubuntu 14.10 下编码,gcc 程序是默认程序。 我真的不知道出了什么问题。 请帮我改正程序。 非常感谢您!!!
您可以尝试使用 System.load
。 iirc System.loadLibrary
从默认位置加载 .so/.dll 文件。 System.load
应该使用 .so/.dll 文件的绝对路径。
删除
#ifndef _Included_TestJni
#define _Included_TestJni
...
#endif
来自源文件。您已经 #define
在 header 中添加了 include guard,因此这有效地注释掉了代码。
删除 #include "MyJni.h"
或
#ifndef _Included_TestJni
#define _Included_TestJni
//..
#endif
Exception in thread "main" java.lang.UnsatisfiedLinkError: TestJni.print(LA;)V
这通常发生在 JNI 无法在您的库中找到符号定义时。你可以使用nm
分析你调用的JNI函数,看看它是否在你的库中定义和导出。
$ nm libMyJni.so
00000000000005ac T Java_TestJni_print
0000000000200e40 a _DYNAMIC
0000000000200fe8 a _GLOBAL_OFFSET_TABLE_
w _Jv_RegisterClasses
0000000000200e20 d __CTOR_END__
0000000000200e18 d __CTOR_LIST__