JNI UnsatisfiedLinkError 没有错误的方法名称和指定的库路径
JNI UnsatisfiedLinkError without wrong method names and with library path specified
我正在尝试按照本教程构建我的第一个 JNI 应用程序:https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html
问题摘要:运行我的应用程序运行时,出现 java.lang.UnsatisfiedLinkError 错误。
首先我写了ClassHelloJNI.java:
public class HelloJNI {
static {
System.loadLibrary("hello"); // Load native library at runtime
// hello.dll (Windows) or libhello.so (Unixes)
}
// Declare a native method sayHello() that receives nothing and returns void
private native void sayHello();
// Test Driver
public static void main(String[] args) {
new HelloJNI().sayHello(); // invoke the native method
}
}
这个 class 我编译的是:
javac HelloJNI.java
接下来我运行javah HelloJNI
这产生了以下文件 HelloJNI.h:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloJNI */
#ifndef _Included_HelloJNI
#define _Included_HelloJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloJNI
* Method: sayHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloJNI_sayHello
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
接下来我实现了HelloJNI.c:
#include <jni.h>
#include <stdio.h>
#include "HelloJNI.h"
// Implementation of native method sayHello() of HelloJNI class
JNIEXPORT void JNICALL Java_HelloJNI_sayHello(JNIEnv *env, jobject thisObj) {
printf("Hello World!\n");
return;
}
最后我编译了c class:
- gcc -I"/usr/lib/jvm/java-8-oracle/include" -I"/usr/lib/jvm/java-8-oracle/include/linux" -c -Wall -Werror -fpic HelloJNI.c
- gcc -shared -o hello.so HelloJNI.o
这将生成文件 hello.so 和 HelloJNI.o。接下来我尝试 运行 代码:
java-Djava.library.path=。你好JNI
这会产生错误:
线程 "main" 中出现异常 java.lang.UnsatisfiedLinkError:java.library.path 中没有问候
在 java.lang.ClassLoader.loadLibrary(ClassLoader.java:1864)
在 java.lang.Runtime.loadLibrary0(Runtime.java:870)
在 java.lang.System.loadLibrary(System.java:1122)
在 HelloJNI.(HelloJNI.java:3)
这似乎是 Internet 上最常见的 JNI 错误...我的方法名称似乎是正确的。我也 运行:
- 纳米 hello.so | grep 说
这给了我:00000000000006b0 T Java_HelloJNI_sayHello 这似乎是正确的,即编译器没有添加额外的字符。我只是 运行 没有我可以尝试的想法。有什么建议吗?
我的 OS:Linux Mint 13,GCC 版本 4.7.3,java 版本 1.8。0_60
==========更新===============
当我用 System.load("/usr0/home/jkinable/workspace/javaIDEA/jnitest/hello.so");
替换 System.loadLibrary("hello");
时,我的 HelloWorld 示例有效!但是,我不想使用绝对路径,所以我仍在寻找使用 System.loadLibrary("hello");
的方法?有什么建议么?我也在不同的 linux 系统上尝试了 运行ning,但我遇到了同样的问题。
事实证明,问题是由于 unix/linux 平台上的一些命名约定造成的!使用时:
System.loadLibrary("hello");
该文件不应命名为 hello.so!相反,名称应该是 libhello.so。在 Windows 上,使用 hello.dll。我很惊讶 IBM 的 JNI 教程中没有提到这个问题:http://www.ibm.com/developerworks/java/tutorials/j-jni/j-jni.html
我不确定这个问题背后的合理性是什么。你为什么要在你的文件系统上加载一个应该命名为 libhello.so 的库 "hello"(而不是 hello.so)?
我正在尝试按照本教程构建我的第一个 JNI 应用程序:https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html
问题摘要:运行我的应用程序运行时,出现 java.lang.UnsatisfiedLinkError 错误。
首先我写了ClassHelloJNI.java:
public class HelloJNI {
static {
System.loadLibrary("hello"); // Load native library at runtime
// hello.dll (Windows) or libhello.so (Unixes)
}
// Declare a native method sayHello() that receives nothing and returns void
private native void sayHello();
// Test Driver
public static void main(String[] args) {
new HelloJNI().sayHello(); // invoke the native method
}
}
这个 class 我编译的是: javac HelloJNI.java 接下来我运行javah HelloJNI 这产生了以下文件 HelloJNI.h:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloJNI */
#ifndef _Included_HelloJNI
#define _Included_HelloJNI
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloJNI
* Method: sayHello
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloJNI_sayHello
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
接下来我实现了HelloJNI.c:
#include <jni.h>
#include <stdio.h>
#include "HelloJNI.h"
// Implementation of native method sayHello() of HelloJNI class
JNIEXPORT void JNICALL Java_HelloJNI_sayHello(JNIEnv *env, jobject thisObj) {
printf("Hello World!\n");
return;
}
最后我编译了c class:
- gcc -I"/usr/lib/jvm/java-8-oracle/include" -I"/usr/lib/jvm/java-8-oracle/include/linux" -c -Wall -Werror -fpic HelloJNI.c
- gcc -shared -o hello.so HelloJNI.o
这将生成文件 hello.so 和 HelloJNI.o。接下来我尝试 运行 代码:
java-Djava.library.path=。你好JNI 这会产生错误:
线程 "main" 中出现异常 java.lang.UnsatisfiedLinkError:java.library.path 中没有问候 在 java.lang.ClassLoader.loadLibrary(ClassLoader.java:1864) 在 java.lang.Runtime.loadLibrary0(Runtime.java:870) 在 java.lang.System.loadLibrary(System.java:1122) 在 HelloJNI.(HelloJNI.java:3)
这似乎是 Internet 上最常见的 JNI 错误...我的方法名称似乎是正确的。我也 运行:
- 纳米 hello.so | grep 说
这给了我:00000000000006b0 T Java_HelloJNI_sayHello 这似乎是正确的,即编译器没有添加额外的字符。我只是 运行 没有我可以尝试的想法。有什么建议吗?
我的 OS:Linux Mint 13,GCC 版本 4.7.3,java 版本 1.8。0_60
==========更新===============
当我用 System.load("/usr0/home/jkinable/workspace/javaIDEA/jnitest/hello.so");
替换 System.loadLibrary("hello");
时,我的 HelloWorld 示例有效!但是,我不想使用绝对路径,所以我仍在寻找使用 System.loadLibrary("hello");
的方法?有什么建议么?我也在不同的 linux 系统上尝试了 运行ning,但我遇到了同样的问题。
事实证明,问题是由于 unix/linux 平台上的一些命名约定造成的!使用时: System.loadLibrary("hello"); 该文件不应命名为 hello.so!相反,名称应该是 libhello.so。在 Windows 上,使用 hello.dll。我很惊讶 IBM 的 JNI 教程中没有提到这个问题:http://www.ibm.com/developerworks/java/tutorials/j-jni/j-jni.html
我不确定这个问题背后的合理性是什么。你为什么要在你的文件系统上加载一个应该命名为 libhello.so 的库 "hello"(而不是 hello.so)?