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文件,放到tomcat\lib文件夹下。再在web.xml中加一个监听,在项目启动的时候就加载这个类,加载dll.

JAVA 关于JNI本地库加载的更多相关文章

  1. 你知道 Java 类是如何被加载的吗?

    前言 最近给一个非 Java 方向的朋友讲了下双亲委派模型,朋友让我写篇文章深度研究下JVM 的 ClassLoader,我确实也好久没写 JVM 相关的文章了,有点手痒痒,涂了皮炎平也抑制不住的那种 ...

  2. java调用phantomjs采集ajax加载生成的网页

    java调用phantomjs采集ajax加载生成的网页 日前有采集需求,当我把所有的对应页面的链接都拿到手,准备开始根据链接去采集(写爬虫爬取)对应的终端页的时候,发觉用程序获取到的数据根本没有对应 ...

  3. java类到底是如何加载并初始化的?

    Java虚拟机如何把编译好的.class文件加载到虚拟机里面?加载之后如何初始化类?静态类变量和实例类变量的初始化过程是否相同,分别是如何初始化的呢?这篇文章就 是解决上面3个问题的. 若有不正之处, ...

  4. 深入java虚拟机学习 -- 类的加载机制(续)

    昨晚写 深入java虚拟机学习 -- 类的加载机制 都到1点半了,由于第二天还要工作,没有将上篇文章中的demo讲解写出来,今天抽时间补上昨晚的例子讲解. 这里我先把昨天的两份代码贴过来,重新看下: ...

  5. 深入java虚拟机学习 -- 类的加载机制(三)

    类的初始化时机 在上篇文章中讲到了类的六种主动使用方式,反射是其中的一种(Class.forName("com.jack.test")),这里需要注意一点:当调用ClasLoade ...

  6. 【java虚拟机系列】java中类与对象的加载顺序

    首先了解一下Java虚拟机初始化的原理. JVM通过加装.连接和初始化一个Java类型,使该类型可以被正在运行的Java程序所使用.类型的生命周期如下图所示: 装载和连接必须在初始化之前就要完成. 类 ...

  7. 【译】12. Java反射——类的动态加载和重新加载

    原文地址:http://tutorials.jenkov.com/java-reflection/dynamic-class-loading-reloading.html 博主最近比较忙,争取每周翻译 ...

  8. Java类加载机制及自定义加载器

    转载:https://www.cnblogs.com/gdpuzxs/p/7044963.html Java类加载机制及自定义加载器 一:ClassLoader类加载器,主要的作用是将class文件加 ...

  9. java web eclipse中项目的加载过程

    java web eclipse中项目的加载过程: Tomcat默认从WEB-INF/目录下加载资源,Eclipse在发布程序的时候,并没有把User Libraries的相关资源拷贝到WEB-INF ...

随机推荐

  1. 【技术文档】jeecg3.7.3-maven搭建环境入门

    JEECG 微云快速开发平台(3.7.3)Eclipse-Maven版本手把手入门手册 官方标准开发工具:1. IDE        Eclipse Java EE IDE for Web Devel ...

  2. scala 爬虫 去除不能存储的特殊字符

    scala 爬虫 去除不能存储的特殊字符 /** * 去除不能存储的特殊字符 */ def zifuChange(str: String): String = { var bo = true var ...

  3. css:关于position和float

    在CSS中,我们是通过定位属性position来进行定位的,具体它有如下几个属性值.常见的属性有如下几个: absolute  生成绝对定位的元素,相对于static定位以外的第一个父元素进行定位.元 ...

  4. 解决Mac上安装mysqlclient的错误

       要想使用python操作mysql,那么就需要安装python操作数据库的驱动,由于mysqldb不支持python3,我选择安装mysqlclient, 命令行输入:pip3 install  ...

  5. Visual Studio for Mac 使用笔记

    无法打开控制台运行程序 Project -> Project Options -> Run -> Configurations -> Default 勾选Run on exte ...

  6. 【369】列表/字典的分拆, unpacking

    参考: python--参数列表的分拆 参考: List Comprehensions 当你要传递的参数已经是一个列表,调用的函数却接受分开一个个的参数,这个时候可以考虑参数列表拆分: 可以使用* 操 ...

  7. [福大2018高级软工教学]团队Beta阶段成绩汇总

    一.作业地址: https://edu.cnblogs.com/campus/fzu/AdvancedSoftwareEngineerning2018/homework/2465 二.Beta阶段作业 ...

  8. [C语言]逆序的三位数

    ---------------------------------------------------------------------------------------- //  main.c ...

  9. ios嵌套H5页面,出现的小bug;

    ios嵌套H5页面,点击数字时就会弹出打电话的功能:解决方法: 在head标签中添加: <meta name="format-detection" content=" ...

  10. swift 头尾式动画

    1.0 头尾式动画 UIView.beginAnimations(nil, context: nil) UIView.setAnimationDuration(1.0) // 设置执行动画所需要的时间 ...