如何解决包ios 解决手势冲突问题题

博客分类:
转载请注明出处:
描述一下具体场景:
环境:本地开发环境,windows7+Eclipse+HSF Jetty(HSF Jetty作为启动容器)
Defensor在进行增量覆盖率功能开发时,出现了一个诡异的问题————代码运行阶段,对一个类中的方法进行调用,报如下错误信息:
分析&解决过程:
1、正常情况应该调用tcc-emma-3.2.0.jar(对应本地tcc-emma工程)中的reportCommand类,此类中确实存在getProjectCoverageFromThread()方法2、那为什么会报找不到此方法?第一感觉,Jar包冲突了。3、在调用处的上方添加如下语句
reportCommand.class.getProtectionDomain().getCodeSource();
注:此行代码含义为————真实加载的具体类的路径信息。执行到上面的代码,通过eclipse的Inspect可以看到:真实加载的类路径为:
D:\.m2\repository\com\taobao\test\tcc-maven-plugin\1.0.8-SNAPSHOT\tcc-maven-plugin-1.0.8-SNAPSHOT.jar
4、目前为止,已经分析出确实是Jar包冲突问题导致运行时加载了错误的类。但是这个错误的jar包是在父工程pom依赖进来,且pom中的配置为scope=test,也就是说只有在构建工程的测试阶段才会加载此jar包,而在工程提供服务的运行阶段是不会加载此Jar的。并且通过查看最终编译打出的war包,确实也没有此jar。5、为什么会在运行期间加载了scope=test的Jar包里的类呢?分析到这里,聪明的读者应该会想到是Eclipse的问题所导致,它将测试阶段引用到的jar包也加入进了运行期class path中,而且加载的优先级高于tcc-emma工程中的同名类。6、尝试了多种方法,均无法将tcc-maven-plugin-1.0.8-SNAPSHOT.jar从加载过程中移除。最终,通过调整Eclipse中的Build class path顺序解决了这个问题,也就是明确告诉容器启动时优先加载tcc-emma工程中的同名类。见下图:
PS: 查看class真实归属的jar包位置
getClass().getClassLoader().getResource(getClass().getName().replace(, ) + )
转载请注明出处:
zhangym124
浏览: 253803 次
来自: 杭州
可以参考最新的文档:如何在eclipse jee中检出项目并转 ...
snowfigure 写道我专门登陆上来,就是想问问,这个Ve ...
我专门登陆上来,就是想问问,这个Version有啥鸟用?定义完 ...
引用整个包就好了,不用具体类
至于大数据量时导致图表渲染慢的问题,可以通过改变业务逻辑及交互 ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'博客分类:
随着业务需求的不断扩展,应用中代码量也会逐渐增长,工程中引用的二方包或者三方包也自然而然会越来越多。因此,不可避免,可能存在引用的二方包或三方包相互冲突所导致的系统问题。
本文将针对前段时间遇到的实际案例进行分析,旨在当遇到包冲突问题时该如何解决,并提供同事用
写的一个发现包冲突的小工具(十分有用!)
一 发现问题:
首先 ,让我们看下异常,这是在应用启动后,执行具体操作时所报的错误:
根据错误我们大概可以了解,工程中引用了一个名叫
的类,并调用了其中名为
的方法,但是系统在加载该方法时却表示没有找到该方法。
这是一个很明显的包冲突问题,这类情况的发生很可能是因为如下状况引起的:
如图,你引用了
中又引用了一个
的版本号为
中也引用了
,假设这里的
为较高版本,记为
中某个类引用了
,并且该方法只存在于高版本的
中,而不存在
当系统编译加载时,系统可能编译加载
,也可能编译加载
,当编译加载
时,由于很多
包都支持向下兼容,即高版本兼容低版本,因此不论
一般都不会出问题。但如果此时刚好应用编译加载的是
时便会报上述错误,因为
函数只存在于高版本的
中,而此时系统编译加载的却是低版本的
二 解决问题
当遇到这类问题我们该如何解决呢
主要有以下三步:
发现是哪个类发生了冲突;
包,即冲突类存在于哪个
发现这个冲突
包是自身系统直接引用的还是系统引用的
间接引用的。
针对上述第一步,我们使一个 用
小工具来解决。
下载后,存放到某个目录,然后将
的存放路径设定至环境变量
包所在目录。
就会检测到目录中存在冲突的
包,并以三种格式输出
两个都输出。
可以查看用法。
下,因此在环境变量
中设置的是
,定位到应用存放
包的目录下,执行
盘中将会发现一个名为
的文档,里面记录了存放
包目录下所有冲突的
。在其中我们
一把上述系统冲突的类名“
”,发现他们原来是存在于
中。 如下图:
此时,对系统有影响的冲突类和冲突
包我们都已经发现了。
通过网上百度,原来
的产品,并且
升级版本,因此在编译过程中我们应该把
编译进工程,而不能把
编译进工程。
第三步,我们看
是否是应用直接引用的。经过确认,我的项目中并没有直接引用这两个
包,因此可能是通过其他
包间接引用进来的。由于项目中是通过
包的管理。因此, 结合 maven 的命令 mvn dependency:tree 可以很容易发现这两个jar 包到底是通过哪些jar 包间接引用进来的。
+- com.know.diamond:diamond-sdk:jar:2.0.5:compile
+- net.sourceforge.htmlunit:htmlunit:jar:1.14:compile
+- rhino:js:jar:1.6R7:compile
+- nekohtml:nekohtml:jar:0.9.5:compile
\- net.sourceforge.cssparser:cssparser:jar:0.9.4:compile
+- com.taobao.diamond:diamond-utils:jar:2.0.5:compile
+- org.codehaus.jackson:jackson-core-lgpl:jar:1.4.0:compile
\- org.codehaus.jackson:jackson-mapper-lgpl:jar:1.4.0:compile
\- com.google.collections:google-collections:jar:1.0:compile
原来是 diamond-sdk:jar 间接引用了 com.google.collections:google-collections:jar. 因此我们通知 diamond-sdk:jar 的维护者进行 jar 包升级,或者在 MVN 编译过程中强制禁止 google-collections:jar 编译进工程。如下:
&dependency&
&groupId&com.know.diamond&/groupId&
&artifactId&diamond-sdk&/artifactId&
&version&2.0.5&/version&
&exclusions&
&exclusion&
&groupId&com.google.collections&/groupId&
&artifactId&google-collections&/artifactId&
&/exclusion&
&/exclusions&
&/dependency&
OK,重新编译工程,启动,问题解决。
浏览: 37575 次
遇到同样的问题了,文章写得很清晰,但是没有提供conflict ...
图怎么看????
conflictdetect.exe 能否发我一下?
你好,你的conflictdetect工具可否共享一下,不胜感 ...
正在看,写的挺不错,内容挺丰富,浅尝辄止,相当适应初学者... ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'遇到一个问题不如何解决:关于包依赖和冲突。 - 查看主题 & Ubuntu中文论坛
&[ 7 篇帖子 ]&
&文章标题 : 遇到一个问题不如何解决:关于包依赖和冲突。发表于 :
10:57帖子: 1003地址: 金山
系统: ubuntu14.04
代码:$ dpkg& -l | grep 'libstdc++6'rU& libstdc++6:amd64& & & & & & & & & & & & & & & & & & & & & & 4.9.1-12& & & & & & & & & & & & & & & & & & & & & & amd64& & & & GNU Standard C++ Library v3rF& libstdc++6:i386& & & & & & & & & & & & & & & & & & & & & & &4.8.2-19ubuntu1& & & & & & & & & & & & & & & & & & &i386& & & & &GNU Standard C++ Library v3之前的状态是iU和iF,由于用dpkg卸载了一次成为了rU和rFlibstdc++6:i386 是以前装的,没有问题的。libstdc++6:amd64 是昨晚通过昨晚下载下来的libstdc++6_4.9.1-12_amd64.deb文件通过dpkg安装的,安装时由于遇到依赖关系没有成功。现在由于libstdc++6:amd64安装时未满足依赖关系以及和libstdc++6:i386的冲突,导致apt 和软件中心都不能用了,比如:代码:$ sudo apt-get& remove firefoxReading package lists... DoneBuilding dependency tree& & & &Reading state information... DoneYou might want to run 'apt-get -f install' to correct these:The following packages have unmet dependencies:libstdc++6 : Depends: gcc-4.9-base (= 4.9.1-12) but 4.9-ubuntu1 is to be installed& & & & & & & Breaks: libstdc++6:i386 (!= 4.9.1-12) but 4.8.2-19ubuntu1 is to be installed&libstdc++6:i386 : Breaks: libstdc++6 (!= 4.8.2-19ubuntu1) but 4.9.1-12 is to be installed&xul-ext-unity : Depends: firefox (&= 10.0) but it is not going to be installed&xul-ext-webaccounts : Depends: firefox (&= 9.0) but it is not going to be installedE: Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution).如果卸载代码:$ sudo apt-get& remove libstdc++6:amd64Reading package lists... DoneBuilding dependency tree& & & &Reading state information... DoneYou might want to run 'apt-get -f install' to correct these:The following packages have unmet dependencies:appmenu-qt : Depends: libstdc++6 (&= 4.1.1) but it is not going to be installedappmenu-qt5 : Depends: libstdc++6 (&= 4.1.1) but it is not going to be installed..... 不知如何是好?libstdc++6:i386 和 libstdc++6冲突了如果卸载 libstdc++6:amd64
apt觉得是在卸载libstdc++6:i386, 而libstdc++6:i386是被许多包依赖着的。
&文章标题 : Re: 遇到一个问题不如何解决:关于包依赖和冲突。发表于 :
16:10帖子: 1849
系统: Arch debian win7
代码:sudo apt-get -f install这个执行下看看呢
_________________拥有丰富API接口和广泛程序支持的dropbox云同步,,开始就比别人多500兆,我的空间也会增加。谢啦==========我的作品==========
&文章标题 : Re: 遇到一个问题不如何解决:关于包依赖和冲突。发表于 :
10:57帖子: 1003地址: 金山
系统: ubuntu14.04
zhw2101024 写道:代码:sudo apt-get -f install这个执行下看看呢不行啊代码:$ sudo apt-get install -fReading package lists... DoneBuilding dependency tree& & & &Reading state information... DoneCorrecting dependencies... failed.The following packages have unmet dependencies:&libstdc++6 : Depends: gcc-4.9-base (= 4.9.1-12) but 4.9-ubuntu1 is installed& & & & & & & Breaks: libstdc++6:i386 (!= 4.9.1-12) but 4.8.2-19ubuntu1 is installed&libstdc++6:i386 : Breaks: libstdc++6 (!= 4.8.2-19ubuntu1) but 4.9.1-12 is installedE: Error, pkgProblemResolver::Resolve generated breaks, this may be caused by held packages.E: Unable to correct dependencies
&文章标题 : Re: 遇到一个问题不如何解决:关于包依赖和冲突。发表于 :
3:29帖子: 1554
这种问题一般都是你自己搞得源列表中有错误或冲突了,别随便使用sudo apt-get -f install,要首先明确问题出在哪里。。。代码:cat /etc/apt/sources.list
_________________16.04--&14.04
&文章标题 : Re: 遇到一个问题不如何解决:关于包依赖和冲突。发表于 :
10:57帖子: 1003地址: 金山
系统: ubuntu14.04
引用:这种问题一般都是你自己搞得源列表中有错误或冲突了,别随便使用sudo apt-get -f install,要首先明确问题出在哪里sources.list文件没做过修改系统原来有libstdc++6(4.8.2-19ubuntu1)昨晚下载安装了libstdc++6_4.9.1-12_amd64.deb现在冲突了卸又卸不掉
&文章标题 : Re: 遇到一个问题不如何解决:关于包依赖和冲突。发表于 :
3:29帖子: 1554
ok,明白了。可以尝试用aptitude而不是apt通过忽略包依赖关系的方法卸载掉你自己安装的包。代码:sudo apt-get install aptitude自己看一下aptitude的man page,里面有好几种方式解决包依赖的问题,推荐首先尝试--safe-resolver。如不行可以尝试类似这样的命令:代码:sudo aptitude -fy remove your-problem-package注意命令提示,不要误删了一大堆必需的包!!!
_________________16.04--&14.04
&文章标题 : Re: 遇到一个问题不如何解决:关于包依赖和冲突。发表于 :
10:57帖子: 1003地址: 金山
系统: ubuntu14.04
引用:ok,明白了。可以尝试用aptitude而不是apt通过忽略包依赖关系的方法卸载掉你自己安装的包。谢谢回复不过刚才apt和软件中心都废掉了:即不能用sudo apt-get install 安装任何软件现在问题解决了方法如下:单独下载一个libstdc++6(4.8.2-19ubuntu1)amd64位的.deb文件,然后安装之代码:$ sudo dpkg -i libstdc++6_4.8.2-19ubuntu1_amd64.deb昨晚安装的libstdc++6_4.9.1-12_amd64.deb就被覆盖了代码:$ dpkg& -l | grep 'libstdc++6'ii& libstdc++6:amd64& & & & & & & & & & & & & & & & & & & & & & 4.8.2-19ubuntu1& & & & & & & & & & & & & & & & & & &amd64& & & & GNU Standard C++ Library v3ii& libstdc++6:i386& & & & & & & & & & & & & & & & & & & & & & & & 4.8.2-19ubuntu1& & & & & & & & & & & & & & & & & & &i386& & & & &GNU Standard C++ Library v3两个版本一致了,就没有冲突了。这里刚开始libstdc++6:i386的状态是ri。我用sudo apt-get --reinstall install libstdc++6:i386重装了一下,就ii了
显示帖子 : 全部帖子1天7天2周1个月3个月6个月1年&排序 作者发表时间文章标题 升序降序&
&[ 7 篇帖子 ]&
正在浏览此版面的用户:没有注册用户 和 2 位游客
您 不能 在这个版面发表主题您 不能 在这个版面回复主题您 不能 在这个版面编辑帖子您 不能 在这个版面删除帖子您 不能 在这个版面提交附件
选择一个版面
------------------
公告/注意事项
& &新闻和通知
& &校园社团支持
& && &华东校区
& && &华南校区
& && &华北校区
& && &华中校区
& && &东北校区
& && &西北校区
& && &港澳台校区
& && &国外校区
& &软件推荐
& &非常任务
系统安装区
& &教学和常见问答
& && &课堂教学和培训
& &初学者园地 - 17.10 Artful Aardvark
& &系统安装和升级
& && &新立得和软件源
& && &Wubi安装讨论
& &启动和引导
& &网卡问题以及网络和拨号
& && &校园网拨号
& &笔记本、UMPC支持
& &手机和平板
& && &Ubuntu移动应用开发
& &常用硬件支持
& &系统架构支持
配置美化区
& &字体美化和中文支持
& && &个人配置文件存放点
& &桌面特效
& &窗口管理器
& &屏幕抓图
& &办公、图像、机械电子设计等
& && &Vim和Emacs
& &因特网相关软件
& &影音多媒体
& &Wine及其分支
& &游戏和游戏模拟器
& &虚拟机和虚拟化
& &其它类软件
& &开源模板库
服务器管理
& &服务器基础应用
& &数据库管理
& &服务器维护和硬件相关
& &Ubuntu VPS
参与Ubuntu开发
& &软件和文档翻译
& &编译或打包
& &Ubuntu错误报告
程序设计区
& &Shell脚本
& &GTK+和QT
& &软件/网站开发
& && &Python/Php/Perl
& && &C/C++/Java
& &内核及嵌入式开发
& &开源小工具
& &Ubuntu 18.04 LTS
& &Ubuntu 16.04 LTS
& &Ubuntu 14.04 LTS
& &Ubuntu 12.04 LTS
& &Ubuntu 10.04 LTS
& &老旧版本支持
衍生发行版
& &Ubuntu GNOME
& &Kubuntu
& &Xubuntu & Lubuntu
& &Ubuntu中文衍生版
& && &UbuntuKylin
& &Ubuntu国外衍生版
& && &Mint
& &Ubuntu衍生版制作
& &其它类Unix OS发行版
& && &Arch发行版
& && &Debian发行版
& && &OpenSUSE发行版
& && &Deepin
& &深度PK版
& &Ubuntu故事和感慨
& &Full Circle开源杂志
分享交流区
& &同城交流
& &线下活动专版
& &Ubuntu宣传推广
& &论坛管理
& && && &Ubuntu中文网上商店如何在 WebSphere 中解决 jar 包冲突
此内容是该系列 # 部分中的第 # 部分: /developerworks/cn/library/?series_title_by=**auto**敬请期待该系列的后续内容。此内容是该系列的一部分:敬请期待该系列的后续内容。
大型的基于 WebSphere 的项目开发中,同一个 WebSphere Application Server(以下简称 WAS)上会部署多个应用程序,而这多个应用程序必然会共用一些 jar 包,包括第三方提供的工具和项目内部的公共 jar 等。把这些共用的 jar 包提取出来在多个应用程序之间共享,不仅可以统一对这些 jar 包进行维护,同时也提高了 WAS 的性能。但是随着应用的不断扩大,新的应用程序的不断增加,新的应用程序会希望使用一些更高版本的共享 jar 包,而由于系统运行维护的需要,老的应用程序仍然希望用老版本的共享 jar 包,这样就必然造成了共享 jar 包的版本冲突。jar 包版本冲突问题是在大型应用项目的开发中经常遇到的问题,本文试图从 WebSphere 的类加载器入手,讨论几种在不同情况下解决 jar 包冲突问题的办法。WebSphere 中类加载器介绍Jar 包冲突实际上是应用程序运行时不能找到真正所需要的类,而影响类的查找和加载的是 JVM 以及 WebSphere 中的类加载器(class loader),为此,我们首先介绍一下 WebSphere 中的类加载器以及一些相关的概念。WebSphere 中类加载器层次结构Java 应用程序运行时,在 class 执行和被访问之前,它必须通过类加载器加载使之有效,类加载器是 JVM 代码的一部分,负责在 JVM 虚拟机中查找和加载所有的 Java 类和本地的 lib 库。类加载器的不同配置影响到应用程序部署到应用程序服务器上运行时的行为。JVM 和 WebSphere 应用程序服务器提供了多种不同的类加载器配置, 形成一个具有父子关系的分层结构。WebSphere 中类加载器的层次结构图 1 所示:图 1:WebSphere 中类加载器的层次结构如上图所示,WebSphere 中类加载器被组织成一个自上而下的层次结构,最上层是系统的运行环境 JVM,最下层是具体的应用程序,上下层之间形成父子关系。JVM Class loader:位于整个层次结构的最上层,它是整个类加载器层次结构的根,因此它没有父类加载器。这个类加载器负责加载 JVM 类, JVM 扩展类,以及定义在 classpath 环境变量上的所有的 Java 类。WebSphere Extensions Class loader:WebSphere 扩展类加载器 , 它将加载 WebSphere 的一些 runtime 类,资源适配器类等。WebSphere lib/app Class loader:WebSphere 服务器类加载器,它将加载 WebSphere 安装目录下 $(WAS_HOME)/lib/app 路径上的类。 在 WAS v4 版本中,WAS 使用这个路径在所有的应用程序之间共享 jar 包。从 WAS v5 开始, 共享库功能提供了一种更好的方式,因此,这个类加载器主要用于一些原有的系统的兼容。WebSphere "server" Class loader:WebSphere 应用服务器类加载器。 它定义在这个服务器上的所有的应用程序之间共享的类。WAS v5 中有了共享库的概念之后,可以为应用服务器定义多个与共享库相关联的类加载器,他们按照定义的先后顺序形成父子关系。Application Module Class Loader:应用程序类加载器,位于层次结构的最后一层,用于加载 J2EE 应用程序。根据应用程序的类加载策略的不同,还可以为 Web 模块定义自己的类加载器。关于 WebSphere 的类加载器的层次结构,以下的几点说明可能更有助于进一步的理解类的查找和加载过程:每个类加载器负责在自身定义的类路径上进行查找和加载类。一个子类加载器能够委托它的父类加载器查找和加载类,一个加载类的请求会从子类加载器发送到父类加载器,但是从来不会从父类加载器发送到子类加载器。一旦一个类被成功加载,JVM 会缓存这个类直至其生命周期结束,并把它和相应的类加载器关联在一起,这意味着不同的类加载器可以加载相同名字的类。如果一个加载的类依赖于另一个或一些类,那么这些被依赖的类必须存在于这个类的类加载器查找路径上,或者父类加载器查找路径上。如果一个类加载器以及它所有的父类加载器都无法找到所需的类,系统就会抛出 ClassNotFoundExecption 异常或者 NoClassDefFoundError 的错误。类加载器的委托模式类加载器有一个重要的属性:委托模式(Delegation Mode,有时也称为加载方式:Classloader mode)。委托模式决定了类加载器在查找一个类的时候, 是先查找类加载器自身指定的类路径还是先查找父类加载器上的类路径。类加载器的委托模式有两个取值:Parent_First:在加载类的时候,在从类加载器自身的类路径上查找加载类之前,首先尝试在父类加载器的类路径上查找和加载类。Parent_Last:在加载类的时候,首先尝试从自己的类路径上查找加载类,在找不到的情况下,再尝试父类加载器类路径。有了委托模式的概念,我们可以更加灵活的配置在类加载器的层次结构中类的加载和查找方式。表 1 中给出了在 WebSphere 的类加载器层次结构中各个类加载器的委托模式的定义,并给出了不同的类加载器内类的生命周期。注意:在上表中,"JVM Class loader" 因为在类加载器的最顶层,它没有父类加载器,因此其委托模式为 N/A,"WebSphere Extensions Class loader"和"WebSphere lib/app Class loader"的委托模式固定为表中的取值,不可配置,其它的类加载器的委托模式都是可以配置的。WebSphere 中的类加载器策略WebSphere 中对类加载器有一些相关的配置,称为类加载器策略(class loader policy)。类加载器策略指类加载器的独立策略(class loader isolation policy), 通过类加载器策略设置,我们可以为 WAS 和应用程序的类加载器进行独立定义。每个 WAS 可以配置自己的应用程序类加载器策略,WAS 中的每个应用程序也可以配置自己的 Web 模块类加载器策略,下面我们对这两种策略分别介绍。1 .应用服务器(WAS)配置:应用程序类加载器策略应用服务器对应用程序类加载器策略有两种配置:Single:整个应用服务器上的所有应用程序使用同一个类加载器。在这种配置下,每个应用程序不再有自己的类加载器。Multiple:应用服务器上的每个应用程序使用自己的类加载器。2 .应用程序配置:Web 模块类加载器策略应用程序中对 Web 模块类加载器有两种配置:Application:整个应用程序内的所有的实用程序 jar 包和 Web 模块使用同一个类加载器。Module:应用程序内的每个 Web 模块使用自己的类加载器。应用程序的类加载器仍然存在,负责加载应用程序中 Web 模块以外的其它类,包括所有的实用程序 jar 包。从上面的定义可以看出,不同的类加载器策略的配置下,类加载器的层次结构上的某些类加载器可能不存在。比如在应用程序服务器的应用程序类加载器策略定义为 single 的情况下,应用程序的类加载器将不存在,同一个应用服务器上的所有应用程序将共用同一个类加载器,这也就意味着不同的应用程序之间的类是共享的,应用程序间不能存在同名的类。在 WebSphere 中解决 jar 包冲突Jar 包冲突问题实际上就是应用程序希望用某一个确定版本的 jar 包中的类,但是类加载器却找到并加载了另外一个版本的 jar 包中的类。在上一部分介绍了 WebSphere 中类加载器的基本概念和相关配置之后,我们来看如何在 WebSphere 中解决 jar 包冲突。在 WAS v5 版本之前,使用共享 jar 包的方式是将 jar 包放在 $(WAS_HOME)/lib/app 路径下,从上一部分中,我们可以看到,这个路径正是"WebSphere lib/app Class loader" 类加载器的类查找路径,WebSphere 会查找这个路径以取得相应得 jar 包中的 Java 类,从而做到在 WebSphere ND 上的多个应用程序之间共享 jar 包的目的。但是这样做的一个缺点就是这些共享 jar 包暴露给 WebSphere ND 上所有的应用程序,对于那些希望使用 jar 包其它版本的应用程序,这些 jar 包也同样存在在了它们的类加载器类路径上,因此,就不可避免的会造成版本的冲突。在 WAS v5 版本及之后,增加了共享库(shared library)的概念,推荐的在多个应用程序间共享 jar 包并避免 jar 包冲突的方式是使用共享库。具体分析引起 jar 包冲突的情况,主要有三种:多个应用程序间 jar 包冲突:多个应用程序间由于使用了共享 jar 包的不同版本而造成 jar 包版本冲突。应用程序中多个 Web 模块间 jar 包冲突:同一个应用程序内部,不同的 Web 模块间同时使用一个 jar 包的不同版本而造成 jar 包版本冲突。应用程序中同一个 Web 模块内 jar 包冲突:同一个应用程序内部,同一个 Web 模块内,由于需要同时使用同一个 jar 包的两个版本而造成的 jar 包冲突本部分根据这三种 jar 包冲突的情况,讨论三种解决 jar 包冲突的办法,并具体讨论三种解决办法的实现步骤和适用情况:共享库方式解决 jar 包冲突:主要解决应用程序间的 jar 包冲突问题打包到 Web 模块中解决 jar 包冲突:主要解决应用程序中多个 Web 模块间 jar 包冲突问题命令行运行方式解决 jar 包冲突:主要解决应用程序中同一个 Web 模块内 jar 包冲突问题共享库方式解决 jar 包冲突在 WAS v5 中,提供了一种很好的机制,使得 jar 包只存在于需要这个 jar 包的应用程序的类加载器的路径上,而其它的应用程序不受它的任何影响,这就是共享库(Shared library)。共享库可以用在应用服务器级别和应用程序级别,使用应用程序级别的共享库,其好处就是在不同的应用程序之间使用共享 jar 包的不同版本。我们可以为一些通用 jar 包的每个不同版本定义成不同的共享库,应用程序希望使用哪个版本,就把这个版本的共享库放到应用程序的类加载器的类路径上,这种方式有效的解决了应用程序之间 jar 包冲突的问题。下面举例介绍定义和使用共享库的具体方法,本例中,假设存在 xerces.jar 包版本冲突。1 . 定义共享库系统管理员可以在 WebSphere 的 Admin console 中定义共享库,可以分别在 Cell、Node 以及 server 的级别上定义。步骤一 : 进入 Admin console,选择 Environment & Shared Library & new。如图 2 所示: 图 2:WebSphere Admin Console 中进入共享库页面
步骤二: 给出共享库的名字,并指定共享的文件和目录。多个不同的文件 / 目录之间通过"Enter"键分隔,且不能有路径分隔符,如":"和";"等。如图 3 所示: 图 3:WebSphere Admin Console 中添加共享库
步骤三:点击 Apply 或者 OK 之后,就添加了一个名字为 Xerces V2.0 的共享库。记住添加完成后一定要在 admin console 保存配置。如图 4 所示: 图 4:WebSphere Admin Console 中共享库列表2 .安装应用程序进入 Admin console,选择 Applications & Install New Application 安装应用程序。请参照 IBM WebSphere 的 Admin console 使用手册进行安装新的应用程序,此处不再详细介绍。3 .将共享库关联到应用程序步骤一:进入 Admin console,选择 Applications & Enterprise applications ,并选择需要使用共享库的应用程序。注意:因为要改变应用程序的设置,所以如果应用程序已经运行,需要先停掉应用程序。如图 5 所示: 图 5:WebSphere Admin Console 中选择需要配置的应用程序
点击应用程序,进入后,选择 Libraries。如图 6 所示: 图 6:WebSphere Admin Console 中选择应用程序库属性步骤三 : 点击 Add,为应用程序添加共享库。如图 7 所示: 图 7:WebSphere Admin Console 中应用程序添加库
步骤四 : 从下拉列表中选择所需要的共享库,点击 OK。如图 8 所示: 图 8:WebSphere Admin Console 中应用程序添加库页面指定所用的共享库
这样,Xerces V2.0 共享库定义的 xerces 版本就存在于了应用程序类加载器的类加载路径上。注意,在添加完成后要保存服务器的设置。4 .设置应用程序的类加载器的委托模式为 Parent_Last为了进一步防止共享库定义的 jar 包的其它版本已经存在于 JVM 或者 WebSphere 的类加载器路径上,还需要设置应用程序的类加载器的委托方式为 Parent_Last。步骤一:进入 Admin console,选择 Applications & Enterprise applications & ,选择需要配置的应用程序。如图 9 所示: 图 9:WebSphere Admin Console 中选择需要配置的应用程序
步骤二:点击进入应用程序,设置类加载器的委托模式为 Parent_Last。注意:在配置完成后,要保存配置,最后启动应用程序。如图 10 所示: 图 10:WebSphere Admin Console 中为应用程序设置类加载器委托模式
通过上面的配置,即使 xerces 的其它版本已经存在于系统中,应用程序在运行时,其类加载器也会首先查找并加载指定的共享库中的 xerces 版本。这样我们就通过使用共享库的方式,解决了 jar 包版本冲突问题。打包到 Web 模块中解决 jar 包冲突共享库的方式,只是在应用程序的层次上,在多个应用程序之间解决了共享 jar 包造成的版本冲突问题,如果一个应用程序的内部,其中一个 Web 模块使用了一个 jar 包的 A 版本,而另一个 Web 模块使用这个 jar 包的 B 版本,在这种情况下造成的 jar 包冲突,共享库的方式是无法解决的,我们可以考虑将其中一个在多个应用程序间共享的 jar 包版本,比如 A 版本,定义成共享库,或者放在"WebSphere lib/app Class loader"类加载器路径上供多个应用程序使用,而将 B 版本的 jar 包打包到使用它的 Web 模块中的方式来解决冲突。其次,目前很多在线的系统是 WAS v4 的遗留系统,其上运行的应用程序已经使用了"WebSphere lib/app Class loader"类加载器,将 jar 包放在 $(WAS_HOME)/lib/app 目录下进行共享。如果由于其中某个应用程序的升级或者新增加某个应用程序,需要使用某个共享 jar 包的其它版本,在这种情况下,为了减少对系统的影响,也可以考虑将这个共享 jar 包的新版本打包到升级(或新增)的应用程序中的方式来解决 jar 包冲突。由于 Web 模块的 WebContent/WEB-INFO/lib 目录在应用程序 Web 模块的类加载器查找路径上,因此,我们可以把 jar 包放在这个目录下,Web 模块的类加载器将自动查找并加载这个 jar 包中的类。步骤一:在 WSAD IE 集成开发环境中,将冲突 jar 包放在 Web 模块的 WebContent/WEB-INFO/lib 目录下。如图 11 所示: 图 11:WSAD IE 中为 Web 模块添加库步骤二:在 Admin console 中,将应用程序部署到 WebSphere server 上之后,进入 Applications & Enterprise Applications, 选择相应的应用程序,并确认应用程序不在运行状态 ( 参见前面章节中选择应用程序的步骤 )。点击进入应用程序,确认应用程序的类加载器的委托模式为 Parent_First, 应用程序的类加载器策略为 Module。如图 12 所示: 图 12:WebSphere Admin Console 中应用程序属性配置页面步骤三:在同一个页面上,选择 Web Modules,点击进入。如图 13 所示: 图 13:WebSphere Admin Console 中选择应用程序 Web 模块属性步骤四:点击相应的包含冲突 jar 包的 Web 模块,设置 Web 模块的类加载器的委托模式为 Parent_Last。注意:在设置完成后要保存服务器配置,并启动应用程序。如图 14 所示: 图 14:WebSphere Admin Console 中为 Web 模块指定类加载器委托模式将冲突 jar 包打包到 Web 模块中,并设置相应 Web 模块的类加载器的委托模式为 Parent_Last,应用程序在运行过程中加载类的时候,这个 Web 模块的类加载器会首先查找 WebContent/WEB-INFO/lib 目录下的 jar 包进行类的加载;而对于其它的 Web 模块,由于其类加载器的委托模式仍然为缺省的 Parent_First,它们的类加载器仍然首先从应用程序的共享库或者 WebSphere 的共享路径上加载 jar 包中的类,从而解决了 jar 包冲突的问题。命令行运行方式解决 jar 包冲突不论是设置共享库,还是将冲突 jar 包打包到应用程序中,其解决的问题都是在应用程序的一个 Web 模块中只使用了冲突 jar 包的一个版本的情况。我们在开发中曾经遇到过这样的情况:应用程序的 Web 模块中已经使用了 1.4 版本的 xerces.jar,由于 Web 功能的扩展,在这个模块中又引入一个新的第三方工具,而这个第三方工具需要使用 2.0 版本的 xerces.jar 才能正常工作,这种情况下的 jar 包冲突如何解决呢?在前面类加载器的部分已经介绍过,每个应用程序的一个 Web 模块最多只能有一个类加载器,而 Web 模块的类加载器中加载的类的生命周期为整个应用程序的运行期,也就是说,Web 模块加载器不可能同时加载一个类的两个版本,同时,Web 模块的类加载器的委托模式也是在应用程序运行前设置的,在应用程序运行期内无法改变的,因此,上面描述的在一个 Web 模块中同时使用两个版本的 jar 包的问题,象前两种方法那样配置运行在一个 JVM 内的类加载器的设置的方法是无法解决的。唯一的解决办法就是在应用程序运行的 JVM 外,启动另外一个 JVM 来运行调用冲突 jar 包的代码,因为两个不同的 JVM 可以加载各自的类,从而解决 jar 包冲突问题。这种情况下,原来使用 jar 包的老版本的方式(包括 jar 包放置路径,共享库设置方式,类加载器的委托模式等)不变,将对 jar 包新版本的调用通过命令行运行方式实现。具体做法是:将对 jar 包新版本内功能的调用,封装到一个可以单独运行的类中,在 Web 模块中以命令行方式运行这个类。同时把这个类以及 jar 包的新版本放在任意一个 was 可访问的路径上(比如 /usr/WebSphere),在命令行的 classpath 参数中包含这个路径(比如 /usr/WebSphere)。下面通过举例说明命令行运行方式的编程过程,在本例中,假设 TestEar 应用程序的 Web 模块 TestWar 中,已经使用了 conflict_v1.jar,由于新添功能需要使用 conflict_v2.jar 中的 exampleCall() 功能。冲突 jar 包 conflict_v2.jar 提供的功能:代码 1:冲突 jar 包 conflict_v2.jar 功能 Package com.ibm.
Public class ConflictClass{
Public static String exampleCall(string param){
}不存在冲突问题时的编码举例:如果没有 jar 包冲突问题,则对这个功能的调用是简单的,只需要将 conflict_v2.jar 放在应用程序自身或者其父类加载器的查找路径上,然后在 Web 模块中直接调用即可,如下:代码 2:不存在冲突时的调用方式 Public String methodA(String param){
String rs = ConflictClass.exampleCall(param);
}存在冲突后的命令行运行方式编码举例针对 jar 包冲突问题,我们需要在 Web 模块中做如下的修改:步骤一:将冲突 jar 包放在 was 可访问的路径上,比如 /usr/WebSphere/conflict_v2.jar。步骤二:将对包含冲突代码的调用封装到一组可单独运行的类中,它们将调用冲突 jar 包的功能,并将结果以系统输出的方式打印到系统标准输出上。 将这些类封装到一个单独的 jar 文件中,比如 workAroundConflict.jar,并将其放在 was 可访问的路径上,比如 /usr/WebSphere/workAroundConflict.jar。 Package com.ibm.
Import com.ibm.ConflictC
Public class WorkAround{
Public static void main(String[] args){
String param1=args[0];
String returnStr=ConflictClass.exampleCall ();
System.out.println("&RTStr&"+returnStr+"&/RTStr&");
} 代码 3:将对冲突代码的调用写入一个单独的类 WorkAround
步骤三:在 Web 模块中通过命令行方式调用封装的类,通过 classpath 指定所有依赖的 jar 包和类路径。运行封装类,从系统标准输出中取得运行结果。 Public static String methodA (String param){
String rtStr = "";
String lStr="&RTStr&";
String rStr="&RTStr&";
//put all the dependency jar here
String classPath=
"/usr/WebSphere/conflict_v2.
/usr/WebSphere/workaroundConflict. ……";
String className="com.ibm.test.WorkAround";
String cmdLine="java -classpath " +classPath +" " +className + " "+
Process process = Runtime.getRuntime().exec(cmdLine,null);
process.waitFor();
BufferedReader br= new BufferedReader(
new InputStreamReader(process.getInputStream()));
while ((s = br.readLine())!=null) {
if (null == out)
//get result from out
if (null != out){
int lIndex = out.lastIndexOf(lStr);
int rIndex = out.lastIndexOf(rStr);
rsStr = out.substring(lIndex+lStr.length, rIndex);
} catch (Exception e){
e.printStackTrace();
return rsS
} 代码 4:在应用程序中通过命令行方式运行 WorkAround
命令行运行方式通过启动另外一个 JVM 的方式运行冲突代码,在一个不同的 JVM 中加载冲突的类,从而解决了 jar 包冲突问题。但是命令行运行方式毕竟不是一个很好的方式,它存在以下的弊端:命令行运行方式只适用于对冲突 jar 包的使用只是运行一段代码,或者只要求返回简单的字符串结果的情况。对于复杂的交互,命令行方式无法做到。但是如果在别无他法的情况下,可以适当地划分封装对冲突代码调用的 jar 包的包含范围,尽量将命令行运行的代码接口简单化。命令行运行方式因为启动了另外一个 JVM 来运行,降低了 WebSphere 的性能。因此,命令行方式只适用于一些极为特殊的情况下解决 jar 包冲突问题。结论本文对基于 WebSphere 的大型项目开发中遇到的 jar 包冲突问题,结合 WebSphere 中类加载器的概念,给出了三种解决办法以及相应的操作步骤和实现代码,并分析了各种方式所适用的具体情况。项目开发过程中的 jar 包冲突,主要存在以下三种情况:多个应用程序间的 jar 包冲突应用程序内多个 Web 模块间的 jar 包冲突应用程序内同一个 Web 模块内部 jar 包冲突通过对类加载器的分析我们知道,解决 jar 包冲突问题的根本在于合理配置类加载器。在深入理解 WebSphere 中类加载器的层次结构的基础上,我们给出了"共享库解决 jar 包冲突"以及"打包到 Web 模块中解决 jar 包冲突"的办法,通过合理地配置 WebSphere 中类加载器及其委托模式,可以解决大多数的 jar 包冲突问题。但是由于这个层次结构中类加载器只配置到 Web 模块,因此,对于 Web 模块内部的 jar 包冲突问题,类加载器的配置是无法解决的,为此我们给出了"命令行运行方式解决 jar 包冲突"的办法。表 2 中列出了在不同的 WAS 版本下,三种解决 jar 包冲突问题的办法所适用的 jar 包冲突情况。表 2:Jar 包冲突解决办法适用的 jar 包冲突情况总结
相关主题IBM WebSphere Application Server V5 ClassloaderNamingSpace Guide。IBM WebSphere Application Server V5.1 System Management and Configuration。
添加或订阅评论,请先或。
有新评论时提醒我
static.content.url=/developerworks/js/artrating/SITE_ID=10Zone=WebSphereArticleID=428695ArticleTitle=如何在 WebSphere 中解决 jar 包冲突publish-date=}

我要回帖

更多关于 svn如何解决冲突问题 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信