问题
https://gist.github.com/santa4nt/4a8fd626335e36c94356
MAC电脑,使用这里的例子,指定好JAVA_INC路径之后,执行脚本报错
- 报错
Exception in thread "main" java.lang.UnsatisfiedLinkError: no hello in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1122)
at HelloJNI.<clinit>(HelloJNI.java:4)
解决
makerun.sh 脚本中生成的 libhello.so 改成 libhello.dylib 即可
原因
一层一层分析
- 1 . java引用的动态库 libname hello
public class HelloJNI {
static {
System.loadLibrary("hello");
}
......
- c++生成的动态库 libhello.so
g++ -std=c++11 -shared -fPIC -I$JAVA_INC -I$JAVA_INC/linux HelloJNIImpl.cpp -o libhello.so
- 运行java时指定的 java.library.path=.
java -Djava.library.path=. HelloJNI
- 报错no hello in java.library.path
Exception in thread "main" java.lang.UnsatisfiedLinkError: no hello in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1867)
at java.lang.Runtime.loadLibrary0(Runtime.java:870)
at java.lang.System.loadLibrary(System.java:1122)
at HelloJNI.<clinit>(HelloJNI.java:4)
- 很显然,问题是没有在 java.library.path 的路径中 找到 libname 为 hello 的动态库,我们在代码里打印一下 java.library.path 和 实际匹配的 libname,发现path ok,libname 为 libhello.dylib,并非libhello.so;
查看jdk源码发现,jdk对Windows、Mac、Linux操作系统中的 libname 处理各不相同,以前只关注到了 Windows 和 Linux 的区别。
打印变量
public class HelloJNI {
static {
System.out.println(System.getProperty("java.library.path"));
System.out.println(System.mapLibraryName("hello"));
System.loadLibrary("hello");
}
......
输出结果
.
libhello.dylib
jdk源码
// Set the lib prefix and suffix based on the OS
if (osName.startsWith("Windows")) {
libPrefix = "";
libSuffix = ".dll";
} else if (osName.startsWith("Mac")) {
libPrefix = "lib";
libSuffix = ".dylib";
} else if (osName.startsWith("Linux")) {
libPrefix = "lib";
libSuffix = ".so";
}
网友评论