java JNI 实现原理 (一)虚拟机中classloader的JNILibrary
调用JNI的时候,通常我们使用System.loadLibrary(String libname)来load JNI library, 同样也可以使用System.load(String fileName)来load JNI library,两者的区别是一个只需要设置库的名字,比如如果libA.so 只要输入A就可以了,而libA.so的位置可以同过设置 java.library.path 或者
调用JNI的时候,通常我们使用System.loadLibrary(String libname)来load JNI library, 同样也可以使用System.load(String fileName)来load JNI library,两者的区别是一个只需要设置库的名字,比如如果libA.so 只要输入A就可以了,而libA.so的位置可以同过设置 java.library.path 或者 sun.boot.library.path,后者输入的是完整路经的文件名。
而不论用什么方法,最后JNI 库是通过classloader 来加载的。
static void loadLibrary(Class fromClass, String name,
boolean isAbsolute) {}
每个classloader 对象都有自己的nativeLibrary 数组,一个全局的systemNativeLibrary 数组,一个全局的已经加载过的loadLibraryNames数组,和一个正在加载过程中的记录栈nativeLibraryContext
对同一个classloader 对象可以重复加载相同的库,对不同的classloader只可以加载一次相同的库。
1. 这里定义的相同的库是指相同路经下的同一个文件
2. 这里同样指出的是同一个classloader对象,而不是同一种classloader类型,比如说如果一种classloader类型初始化成2个classloader对象,那么这两个对象就不能重复加载相同的库。
3. 重复加载,并不代表真的重复加载,而是代码中保护
for (int i = 0; i < size; i++) {
NativeLibrary lib = (NativeLibrary)libs.elementAt(i);
if (name.equals(lib.name)) {
return true;
}
}
4. 如果加载其他classloader已经加载过的库,会抛出 UnsatisfiedLinkError ERROR
在tomcat上,在不同的war包里,想加载相同的库文件,因为在 tomcat上是使用不同的classloader的对象去加载不同的war包,建议库文件放置在不同的路径通过System.load去加载。
更多推荐
所有评论(0)