基本思路:A.so(支持JNI)、B.so(不支持JNI),Java -> A.so -> B.so
package com.abc.util; public class AuthCheck { static { System.loadLibrary("socall"); } public native static long valid(); public static void main(String[] args) { AuthCheck test = new AuthCheck(); System.out.println(test.valid()); } }
#include <stdio.h> #include <stdlib.h> #include <dlfcn.h> #include "com_abc_util_AuthCheck.h" JNIEXPORT jlong JNICALL Java_com_abc_util_AuthCheck_valid(JNIEnv *env, jclass jc) { long (*myadd)(); void *handle; handle=dlopen("./libnojni.so",RTLD_LAZY);//open lib file if(!handle){ fprintf(stderr, "%s\n", dlerror()); exit(EXIT_FAILURE); } dlerror(); myadd=dlsym(handle,"Valid"); // libnojni.so中有函数long Valid() long result=myadd(); dlclose(handle); //printf("%d\n",result); return result; }注意:如果libnojni.so是32位的,而你的Linux是64位的,那么以上代码运行会报错。需要统一为32或64
java com.abc.util.AuthCheck
web应用一般在web容器里,例如tomcat。此时再次调用,会出现异常:无法打开共享对象文件: 没有那个文件或目录
解决办法就是:把libsocall.so、libnojni.so放到web应用有权限访问并执行的目录下,例如tomcat你用abc用户启动,那么so文件就可以放到/home/abc下。
然后System.loadLibrary("socall");改为System.load("/home/abc/libsocall.so");然后重启tomcat
设置web应用的java.library.path应该修改tomcat的jvm参数,编辑apache-tomcat-7.0.64/bin/catalina.sh,找到# OS specific support,在此行上面加上以下内容
export JAVA_OPTS="-Djava.library.path=你so文件的存放路径",然后java调用so可以使用System.loadLibrary("socall")
==================================================================================
以下转自http://blog.csdn.net/ring0hx/article/details/3242245,内容不完全正确,仅供参考,以实践为准
System.load 和 System.loadLibrary详解
1.它们都可以用来装载库文件,不论是JNI库文件还是非JNI库文件。在任何本地方法被调用之前必须先用这个两个方法之一把相应的JNI库文件装载。