• 转载-JAVA 关于JNI本地库加载


    转载来源:https://www.cnblogs.com/tudachui/p/9729205.html

    1.调用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 来加载的

    例:

    (1)System.load 参数为库文件的绝对路径,可以是任意路径。 

    Java代码

    (2)System.loadLibrary 参数为库文件名,不包含库文件的扩展名

    注意:这种方式,加载的dll文件须是在java.library.path这一jvm变量所指向的路径中。 
    可以通过如下方法来获得该变量的值: 

    Linux一般默认的java.library.path在/usr/lib下。

    也可以自己通过VM参数-Djava.library.path=/usr/lib来显式的指定;或者通过增加环境变量export LD_LIBRARY_PATH=~/JavaNativeTest:$LD_LIBRARY_PATH

    2.对于System.loadLibrary("NativeAgent");

    在Linux下,动态库输出的文件名要是libNativeAgent.so

    也就是说,如果System.loadLibrary("XXX");那么,在导出动态库时,动态库的名字就要是libXXX。否则,会报错:

    3.每个classloader 对象都有自己的nativeLibrary 数组,一个全局的systemNativeLibrary 数组,一个全局的已经加载过的loadLibraryNames数组,和一个正在加载过程中的记录栈nativeLibraryContext

     对同一个classloader 对象可以重复加载相同的库,对不同的classloader只可以加载一次相同的库 

    (1). 这里定义的相同的库是指相同路经下的同一个文件

    (2).  这里同样指出的是同一个classloader对象,而不是同一种classloader类型,比如说如果一种classloader类型初始化成2个classloader对象,那么这两个对象就不能重复加载相同的库。

    (3). 重复加载,并不代表真的重复加载,而是代码中保护

    4.报错处理:ava.lang.UnsatisfiedLinkError: Native Library kjdbc_jni already loaded in another classloader

    原因:

    1.java虚拟机不允许一个JNI本地库同时被两个不同的classloader加载。

    2.web服务器自动重启机制

    当tomcat重启web应用时会自动加载dll, 但是重启web应用并不是重启整个tomcat,上一次启动的jvm仍然存在(jvm依然认为dll已经被之前的classloader加载过了),就不允许重启后web应用的classloader再去加载它。

    但是手动重启tomcat,会将上一次启动的jvm关闭并重新启动,这样就可以正常加载。

    解决思路:

    虽然不同的web应用使用不同的classloader,但是所有web应用classloader的父classloader是同一个(BootstrapClassLoader)

    启动类加载器BootstrapClassLoader:是嵌在JVM内核中的加载器,该加载器是用C++语言写的,主要负载加载JAVA_HOME/lib下的类库,启动类加载器无法被应用程序直接使用。

    根据双亲委托模型,只要让父classloader加载jni本地库就可避免被多个classloader加载

    具体做法:

    将加载dll的代码抽出来,单独放到放到一个类里,写到一个static代码块,(加载这个类时就会先运行static代码块),然后将这个类变成一个jar文件,放到tomcatlib文件夹下。再在web.xml中加一个监听,在项目启动的时候就加载这个类,加载dll.


    作者: 燃烧的竹子
    出处: https://www.cnblogs.com/HittheRoad/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
  • 相关阅读:
    leetcode--Search for a Range
    leetcode--Valid Palindrome
    leetcode--Validate Binary Search Tree
    leetcode--Count and Say
    leetcode--Partition List
    C语言atof()函数:将字符串转换为double(双精度浮点数)
    程序员与科学家的区别
    mingw编译rtmp库
    使用printf输出各种格式的字符串( 转载)
    c++使用stdint.h和inttypes.h
  • 原文地址:https://www.cnblogs.com/HittheRoad/p/14989863.html
Copyright © 2020-2023  润新知