先创建文件helloworld.java,代码如下
//-------helloworld.java文件
public class helloworld{
public static void main(String[] args){
//System.out.println(System.getProperty("java.library.path"));
//System.setProperty("java.library.path",".");
System.loadLibrary("NativeMethodTest");
NativeMethodTest nmt = new NativeMethodTest();
int nValue = nmt.intMethod(3);
System.out.println(nValue);
}
}
class NativeMethodTest
{
public native int intMethod(int n);
}
//-------------------------------------------------------------
前提工作就不多说了,网上可以查到如何在linux下用命令行安装JDK,当然,一般是到java官网下周对应的jdk包,网上能找到很详尽的操作流程;
请先认真阅读上面的代码块
打开终端,切换到目标文件夹下,即要编辑和编译的文件所在目录;
按照一般的方式如下(会出现各种问题,环境是ubuntu18)
1.javac helloworld.java
2.javac -h ./ helloworld.java
3.gcc -shared -fPIC -I/usr/java/jdk-12.0.1/include -I/usr/java/jdk-12.0.1/include/linux NativeMethodTest.c NativeMethodTest.h -o libNativeMethodTest.so(此处要说明下,编译java的so库,可能要关联一些jni文件,橘黄色部分,可根据实际的jdk安装目录路径进行调整)
4.java helloworld
遇到的问题:
1.原先以为生成头文件需要用javah命令,又是装jre,又是配置各种环境,折腾得够呛,最后才知道java在版本10之后不支持javah指令,改成 javac -h;
2.java.lang.UnsatisfiedLinkError: Directory separator should not appear in library name,原因是在loadLibrary的路径中不能出现文件路劲符号;
3.java.lang.UnsatisfiedLinkError: no xxxxx in java.library.path,原因是在java默认的so库目录下没有找到索要加载的so库文件,即便该so文件与当前执行的java程序在同一个目录下也不行,解决方法是在/etc/profile文件最后加入LB_LIBRARY_PATH=目标so库的路径,保存之后执行source /etc/profile使修改生效;不同系统下解决方法可能不同,ubuntu下设置LD_LIBRARY_PATH可能出现无效的情况,后面会给出一些解决方法;
4.执行java helloword时报错Could not find or load main class,原因还是路径问题;
5.重点注意,linux下so库名称必须为lib开头,比如libNativeMethodTest.so,而加载的时候是System.loadLibrary("NativeMethodTest");
6.所有的.class和.h文件在执行javac helloworld.java命令之后会自动生成,拷贝一份.h文件重命名为.c文件,即可编辑相应逻辑代码;
经过各种磨难,找到以下解决方案:(建议在尝试以下方式之前,先重启客户机,试下遇到的问题是否已不存在,有时候可能只是重启即可解决)
方案1:把libxxxx.so文件拷贝到已知的java.library.path目录下,比如/usr/lib,具体可在程序中使用System.out.Println(getProperty("java.library.path")方式输出;
方案2:相对复杂,但可以不用把libxxx.so文件拷贝到已知的java.library.path目录下
步骤1.首先要切换到root下,sudo su并输入密码,必须root;
步骤2.编辑~/.profile把LD_LIBRARY_PATH="要设置的路径"添加到最后一行;
步骤3.编辑~/.bashrc把LD_LIBRARY_PATH="要设置的路径"添加到最后一行;
步骤4.编辑/etc/environment,把LD_LIBRARY_PATH="要设置的路径"添加到最后一行;
步骤5.编辑/etc/X11/XSession.option,把use-ssh-agent改为no-use-ssh-agent使LD_LIBRARY_PATH对所有用户有效;
步骤6.其实最主要的是步骤4和步骤5,基本就能解决编译的问题和运行的问题;