在Linux/MacOS上写Java JNI程序。使用原生应用调用Java虚拟机的接口加载虚拟机,运行Java程序。原生应用的实现文件为invoke.c,其中需要调用JNI_CreateJavaVM()函数加载虚拟机,但是在编译invoke.c时:
gcc invoke.c
出错,错误为(在MacOS上):
Undefined symbols for architecture x86_64:
“_JNI_CreateJavaVM”, referenced from:
_main in invoke-56dc3c.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
在Linux上,错误为:
undefined reference to `JNI_CreateJavaVM’
在Google上搜索了一下,发现一种解决方案,原文为英文:解决方案
1.第一种解决方案
概括的说,之所以出现这个问题,是因为我们在编译时没有指定Java VM库的链接路径,而这个库又不在系统的默认搜索路径中,因此就会说找不到引用。所以,我们在编译时指定库路径就好了。
需要的库为libjvm.so(Linux)或libjvm.dylib(MacOS)。在我的MacOS上,libjvm.dylib库的路径为/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/jre/lib/server/libjvm.dylib。因此,在下面的gcc命令行参数-LPath中的Path就是/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/jre/lib/server/。
所以编译命令可以改为:
gcc -LPath invoke.c -ljvm
切记:-ljvm参数要再invoke.c参数的后面,如果放在前面可能还会出错(在我的机器上是这样的)。
这样,编译就会成功,当前目录会生成a.out文件。
2.第二种解决方案
可以把上面命令的Path路径添加到环境变量LD_LIBRARY_PATH中。
1.打开配置文件:
$vim ~/.bash_profile
2.在文件的最后添加环境变量:
export LD_LIBRARY_PATH=Path/of/the/folder/of/libjvm.dylib
3.在当前终端更新配置:
$source ~/.bash_profile
在MacOS上,执行./a.out时,会弹出对话框说当前系统没有安装Java Runtime,我们需要先安装才能执行这个程序。因此,进入对话框给出的网站:网站链接,下载dmg,安装之后,就可以正确执行程序了。