`
longgangbai
  • 浏览: 7244412 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Linux下动态共享库加载时遇到的问题解决方案及原理

 
阅读更多

 在java调用jni或者JNA时候,报

      error while loading shared libraries: libprint.so: cannot open shared object file: No such file or directory。这便是典型的找不到动态库的错误.

 

具体说来,动态链接器ld.so按照下面的顺序来搜索需要的动态共享库:

  1.ELF可执行文件中动态段中DT_RPATH所指定的路径。这实际上是通过一种不算很常用,却比较实用的方法所设置的:编译目标代码时,可以对gcc加入链接参数“-Wl,-rpath”指定动态库搜索路径;

  2.环境变量LD_LIBRARY_PATH指定的动态库搜索路径;

  3./etc/ld.so.cache中所缓存的动态库路径(如果支持ld.so.cache的话)。这可以通过修改配置文件/etc/ld.so.conf中指定的动态库搜索路径来改变;

  4.默认的动态库搜索路径/lib;

  5.默认的动态库搜索路径/usr/lib。

  在嵌入式Linux系统的实际应用中,1和2被经常使用,也有一些相对简单的的嵌入式系统会采用4或5的路径来规范动态库。3在嵌入式系统中使用的比较少,因为有很多系统根本就不支持ld.so.cache。

  4和5的方式非常简单,只要将所需要的库放到/lib或/usr/lib就可以解决找不到库的问题,不过对于大一些的系统来说,不太方便管理。1和2的方式要稍微复杂一些。

 

 

         项目中使用到JNI来加载本地库,项目自身(web使用)和对外接口(不是web使用)都用到相同的DLL,当web使用访问正常时,接口访问就报错;相反当接口访问正常时,web使用也会报错。错误信息:java.lang.UnsatisfiedLinkError: Native Library XX.dll already loaded in another。

 

分析:这种错误在我们使用热启动方式发布某个使用了JNI技术的Web应用时,并将调用年native方法的jar包独立部署在该应用下面,当我们的Web应用有了更新以后,在调用到该jar包封装的native方法时,会抛出该错误。(以上OS为Windows,若是Linux或Unix,应该是xxx.so 报错) 这是因为Web服务器已经在第一次加载该应用时,已经load了该dll,当该应用被再次热启动时,该dll将重新被加载,于是报错。解决方案: 一、将含有JNI调用的jar包部署在Web服务器的公用lib库中。Web应用再发布时可以不用加载;二、jar包部署不变,在该Web中实现一个listener,监听是否第一次启动,若不是第一次启动,屏蔽掉该jar包所含dll的加载。

 

1、原因

        查询资料后才得知:Java虚拟机为了在JNI本地库中确保基于classloader的命名空间隔离,因而不允许一个JNI本地库被两个不同的classloader加载。而JBoss中web应用的classloader是独立的,也就是说每个web应用都有一个专属的classloader,这样就出现两个classloader加载同一JNI本地库的情况。

 

 

 

2、解决方法

         解决这个问题其实很简单,将访问到jni的代码单独提取出来,并不直接让项目自身的classLoader加载,则是让其由systemLoader加载 即可。一种方法就是将这部分代码,单独封装成一个jar,放到java的systemLoader可以加载的地方,如lib/ext目录下。然后,项目中 仍然去调用此代码。由于访问dll的代码由systemLoader加载,因此,多个项目同时访问同一个dll时,即可避免再次加载了。因为,第二个项目 在访问时,寻找到的类,已经被systemLoader加载过了,因此项目本身的classLoader就不会再去加载这个类了。

        在Weblogic中,虽然不同的web应用使用不同的classloader,但是web应用classloader的父classloader是相同的,这样根据双亲委托模型只要让父classloader加载JNI本地库就可以避免被多个classloader加载。将so放在共享目录(System.getProperty("java.library.path"))的lib目录的并采用System.loadLibrary(libName)即可。

重新Weblogic问题就可以解决。

 

HPUX环境,在WebLogic服务器中使用java调用C动态连接库异常问题总结

 

总结1:查看服务器环境变量是否设置

       SHLIB_PATH此环境变量设置为HPUX默认的查找路径,配置为动态连接库的路径。

       LD_LIBRARY_PATH此为LINUX设置的路径。

 

注意:

       此环境变量不一定非得设置,可以用java.library.path来查看当前的路径指向哪里,可以将动态连接库拷到java.library.path指定的目录即可。

 

总结2:查看so文件是否有启动权限,如果没有则会报权限问题。

       测试方法:可以使用System.loadLibrary(“XXXXX.so”)来进行测试,如果正常通过则无异常显示,如果有异常,则根据提示来进行相应的更改。

       测试时会提示是不在路径中,还是别的什么异常。

 

 基础知识:

UnsatisfiedLinkError

在把本机调用链接到对应的本机定义时,类装入器扮演着重要角色。如果程序试图装入一个不存在或者放错的本机库时,在链接阶段的解析过程会发生 UnsatisfiedLinkError。JVM 规范指定 UnsatisfiedLinkError 是:

对于声明为 native 的方法,如果 Java 虚拟机找不到和它对应的本机语言定义,就会抛出该异常。 当调用本机方法时,类装入器会尝试装入定义了该方法的本机库。如果找不到这个库,就会抛出这个错误。

本机库的装入由调用 System.loadLibrary() 方法的类的类装入器启动 —— 在清单 6 中,就是 UnsatisfiedLinkErrorTest 的类装入器。根据使用的类装入器,会搜索不同的位置:

  • 对于由 bootstrap 类装入器装入的类,搜索 sun.boot.library.path
  • 对于由扩展类装入器装入的类,先搜索 java.ext.dirs,然后是 sun.boot.library.path,然后是 java.library.path
  • 对于由系统类装入器装入的类,搜索 sun.boot.library.path,然后是 java.library.path

在清单 6 中,UnsatisfiedLinkErrorTest 类是由系统类装入器装入的。要装入所引用的本机库,这个类装入器先查找 sun.boot.library.path,然后查找 java.library.path。因为在两个位置中都没有需要的库,所以类装入器抛出 UnsatisfiedLinkageError

 

System.loadLibrary()的使用方法汇总

当使用System.loadLibrary()调用 Dll,两种方法:

1.设定环境变量。

比如:所编辑的Dll在目录“D:/cppProjects/nativecode/release”内,将这个路径复制添加到电脑的环境变量中的path变量内即可。

2.设定项目属性。(开发推荐)

右击项目名|选择属性properties|在左边列表内选择“Java Build Path”|在右边选项卡用选择“source”|点开项目名前的“+”号,选择“Native library location”,“Edit”选择上面“D:/cppProjects/nativecode/release”路径。(当然如果将dll拷贝到workspace下也可以用相对路径。也可右击“src”设定其properties内Native Library项。)

 

 

System.load 和 System.loadLibrary详解

1.它们都可以用来装载库文件,不论是JNI库文件还是非JNI库文件。在任何本地方法被调用之前必须先用这个两个方法之一把相应的JNI库文件装载。

2.System.load 参数为库文件的绝对路径,可以是任意路径。
例如你可以这样载入一个windows平台下JNI库文件:
System.load("C://Documents and Settings//TestJNI.dll");。

3. System.loadLibrary 参数为库文件名,不包含库文件的扩展名。
例如你可以这样载入一个windows平台下JNI库文件
System. loadLibrary ("TestJNI");

这里,TestJNI.dll 必须是在java.library.path这一jvm变量所指向的路径中。
可以通过如下方法来获得该变量的值:
System.getProperty("java.library.path");
默认情况下,在Windows平台下,该值包含如下位置:
1)和jre相关的一些目录
2)程序当前目录
3)Windows目录
4)系统目录(system32)
5)系统环境变量path指定目录

4.如果你要载入的库文件静态链接到其它动态链接库,例如TestJNI.dll 静态链接到dependency.dll, 那么你必须注意:
1)如果你选择
System.load("C://Documents and Settings// TestJNI.dll");
那么即使你把dependency.dll同样放在C://Documents and Settings//下,load还是会因为找不到依赖的dll而失败。因为jvm在载入TestJNI.dll会先去载入TestJNI.dll所依赖的库文件dependency.dll,而dependency.dll并不位于java.library.path所指定的目录下,所以jvm找不到dependency.dll。
你有两个方法解决这个问题:一是把C://Documents and Settings//加入到java.library.path的路径中,例如加入到系统的path中。二是先调用
System.load("C://Documents and Settings// dependency.dll"); 让jvm先载入dependency.dll,然后再调用System.load("C://Documents and Settings// TestJNI.dll");
2)如果你选择
System. loadLibrary ("TestJNI");
那么你只要把dependency.dll放在任何java.library.path包含的路径中即可,当然也包括和TestJNI.dll相同的目录。

 

 

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    LINUX安装与配置简明手册

    本书详细介绍如何在个人电脑上安装配置Caldera和Red Hat两种发行版本的Linux操作系统,并能帮助用户解决安装和配置过程中出现的各种问题。本书既能指导你进行基本的安装步骤,也能指导你定制独具特色的Linux 操作...

    RED HAT LINUX 6大全

    11.4.1 真正的解决方案 201 11.4.2 测试缓冲DNS 204 11.4.3 缓冲服务器小结 206 11.5 重要的DNS事实和概念 206 11.5.1 DNS客户和服务器截然不同 206 11.5.2 DNS术语 206 11.5.3 DNS将名字映射到IP地址及反 序操作 ...

    linux安装与配置简明手册

    本书详细介绍如何在个人电脑上安装配置Caldera和Red Hat两种发行版本的Linux操作系统,并能帮助用户解决安装和配置过程中出现的各种问题。本书既能指导你进行基本的安装步骤,也能指导你定制独具特色的Linux 操作...

    Linux服务器配置---Samba服务器配置(企业案例入门).doc

    因为禁止对共享目录sales访问,就算知道了\\192.168.72.128\sales路径也是不能访问 的 4 Samba排错 1〕Linux服务一般滴排错方法 〔1〕错误信息 一般仔细看下显示的错误信息,根据错误提示一般的问题就可以判断问题...

    citrix服务器虚拟化解决方案.pptx

    静态迁移:XenMotion XenMotion 允许迁移正在运转的虚拟机而无需中缀效力 按方案实施维护时无需停机 在不同的效力器间负载平衡虚拟机 共享存储 citrix服务器虚拟化解决方案全文共29页,当前为第5页。 高可用性:...

    Nginx服务器详解加配置教程

    目录 常见WEB服务器 1 1、Nginx简介 2 2、反向代理Web服务器的“经纪人” 2 2.1反向代理初印象 2 2.2反向代理的作用 3 3、安装及配置 5 3.1下载 5 ...4.1.1 配置Tomcat的session共享可以有三种解决方案: 13

    入门学习Linux常用必会60个命令实例详解doc/txt

    在使用mount这个指令时,至少要先知道下列三种信息:要加载对象的文件系统类型、要加载对象的设备名称及要将设备加载到哪个目录下。 (1)Linux可以识别的文件系统 ◆ Windows 95/98常用的FAT 32文件系统:vfat ;...

    易语言程序免安装版下载

     静态编译后的易语言可执行程序(exe)和动态链接库(dll),运行时不再依赖任何支持库文件,文件尺寸更小(相对以前的独立编译),PE结构更合理(取消了“易格式体”),加载速度更快,而且有效解决了“病毒误报”和...

    Intel-Linux-Processor-Microcode-Data-Files

    更新您的微代码可以帮助缓解CPU中的某些潜在安全漏洞,并解决某些功能问题,例如,这些问题可能导致无法预测的系统行为,例如挂起,崩溃,意外重启,数据错误等。要了解有关应用的更多信息适用于Intel处理器的MCU,...

    KODExplorer 芒果云-资源管理器

    - 选中文件时,移动到屏幕可视区域(解决上下左右选中文件滚动条不一致问题) ###ver2.51 `2014/6/22` ---- ####fix bug:(bug解决和程序优化) - 登陆多次密码输入错误验证码bug解决 - 修复漏洞:创建副本加入...

    工程硕士学位论文 基于Android+HTML5的移动Web项目高效开发探究

    Android 一种基于Linux的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由Google公司和开放手机联盟领导开发 IOS 由苹果公司开发的移动操作系统 Webkit 一个开源的浏览器引擎,在手机上的...

    由0晋升200%系统高手

    3.2 芝麻开门——无法进入Windows的解决方案 3.2.1 Windows XP系统还原 3.2.2 使用Windows XP故障恢复控制台 3.3 Windows XP超级替补──维护磁盘面对面 3.3.1 超级巨无霸——ERD Commander 2003 3.3.2 四...

    TCP/IP教程TCP/IP基础

    22.8 解决拨号网络连接中的问题 242 22.8.1 确认DUN配置 242 22.8.2 PPP日志 243 22.9 小结 243 第23章 Windows NT 4.0 244 23.1 Windows NT版本 244 23.2 体系结构 244 23.3 安装Windows NT 4.0 244 23.4 配置TCP/...

    TCP/IP详解

    22.8 解决拨号网络连接中的问题 242 22.8.1 确认DUN配置 242 22.8.2 PPP日志 243 22.9 小结 243 第23章 Windows NT 4.0 244 23.1 Windows NT版本 244 23.2 体系结构 244 23.3 安装Windows NT 4.0 244 23.4 配置TCP/...

    数据库基础

    第十章 其它一些常见问题及技巧 212 §10.1 一些常见问题 212 §10.1.1 Oracle与2000年问题 212 §10.1.2 如何正确插入日期数据 213 §10.1.3 在查询中只返回满足条件的部分记录 214 §10.1.4 快速大量删除数据...

    TCP/IP技术大全

    24.2 传统解决方案:NetWare 3.x到 NetWare 4.x的IP支持 263 24.2.1 IP隧道 264 24.2.2 IP中继 264 24.2.3 LAN WorkPlace 264 24.2.4 IPX-IP网关 265 24.2.5 NetWare/IP 265 24.3 NetWare 5—Novell对IP的 完全支持 ...

    TCP/IP技术大全(中文PDF非扫描版)

    本书介绍TCP/IP及其应用。TCP/IP是Internet上使用的协议,而Internet是世界上最大的互联网络。本书内容十分丰富,几乎涵盖了有关TCP/IP的各个方面,包括开放式通信模型、TCP/IP...22.8 解决拨号网络连接中的问题 242 ...

    TCP-IP技术大全

    本书介绍TCP/IP及其应用。TCP/IP是Internet上使用的协议,而Internet是世界上最大的互联网络。本书内容十分丰富,几乎涵盖了有关TCP/IP的各个方面,包括开放式通信模型、TCP/IP通信...22.8 解决拨号网络连接中的问题 ...

    防止网络尖兵,破解方法

    四、“网络尖兵”还使用了未知的方法从共享的计算机中探测到共享的信息,目前解决的办法是所有共享的客户机均要安装防火墙,把安全的级别设为最高,因条件有限,只试用了几种防火墙,发觉金山网镖V有用,把IP配置规则...

    糖果的软件

    未释放,删除时就会提示文件正在使用,解决方法是删除系统的页面文件, Win98 中是 Win386.SWP , Win2000/XP 是 pagefile.sys 。 注意要在 DOS 下删除。 8 .文件粉碎法: 使用文件粉碎机,如 File ...

Global site tag (gtag.js) - Google Analytics