如何解决包怎么找包的冲突问题题

下面举一个包冲突的例子:
你引用了&2&个三方包&a.jar&和&b.jar&,&a.jar&中又引用了一个&c.jar&,假设&c.jar&的版本号为&version-1, b.jar&中也引用了&c.jar&,假设这里的&c.jar&相对于&a.jar&中的&c.jar&为较高版本,记为&version-2&,&b.jar&中某个类引用了&c.jar&的类&classA&中的方法&method A()&,并且该方法只存在于高版本的&c.jar(version-2)&的类&classA&中,而不存在c.jar(version-1)&的类&classA&中。
当系统编译加载时,系统可能编译加载&c.jar(version-1)&,也可能编译加载&c.jar(version-2)&,当编译加载c.jar(version-2)&时,由于很多&jar&包都支持向下兼容,即高版本兼容低版本,因此不论&a.jar&调用&c.jar&还是&b.jar&调用&c.jar&一般都不会出问题。但如果此时刚好应用编译加载的是&c.jar(version-1)&中的类&classA&时,那么&b.jar&调用Method A()&时便会报上述错误,因为&Method A()&函数只存在于高版本的&c.jar&中,而此时系统编译加载的却是低版本的&c.jar 。
jar包冲突常见的异常为找不到类(java.lang.ClassNotFoundException)、找不到具体方法(java.lang.NoSuchMethodError)、字段错误(&java.lang.NoSuchFieldError)或者类错误(java.lang.LinkageError)。
常见的解决方法如下:
1、首先做法是打出工程文件的依赖树,将根据jar包依赖情况判定是不是同一个jar包依赖了多个版本,如果确认问题所在,直接exclusion其中错误的jar包即可;
2、如果通过看依赖树不能确定具体冲突的jar包,可以使用添加jvm参数的方式启动程序,将类加载的具体jar信息打印出来;-verbose:class;
3、经过上述步骤基本就可以解决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&
当遇到jar包冲突时,我们首先确定是哪个jar包冲突了,这个很容易,看我们调用的类或方法,是属于哪个Jar包。然后就是要找出冲突了,我这里使用命令
mvn dependency:tree -Dverbose -Dincludes=&groupId&:&artifactId&
填写上Jar包的groupId和artifactId,可以只有一个,但是中间的冒号不要少,这样就会输出依赖树,而且是仅包含这个Jar包的依赖树,这样那些地方依赖了这个Jar包的那个版本就一目了然了。例如,我的项目中notify-common包存在冲突,我们使用命令mvn dependency:tree -Dverbose -Dincludes=:notify-common得到依赖树输出
[INFO] com.taobao.wlb:bis-server:war:1.0-SNAPSHOT
[INFO] +- com.taobao.wlb:bis-core:jar:1.0-SNAPSHOT:compile
\- com.taobao.logistics:schedule-client:jar:1.1.1:compile
\- (com.taobao.notify:notify-common:jar:1.8.15:compile - omitted for conflict with 1.8.19.26)
[INFO] \- com.taobao.notify:notify-tr-client:jar:1.8.19.26:compile
+- com.taobao.notify:notify-common:jar:1.8.19.26:compile
\- com.taobao.notify:notify-remoting:jar:1.8.19.26:compile
\- (com.taobao.notify:notify-common:jar:1.8.19.26:compile - omitted for duplicate)
看一下依赖树中所有的叶子节点就是所有的notify-common包,我们可以看到我们依赖的bis-core中依赖了schedule-client包,它依赖了一个notify-common包,版本是1.8.15,第四行的后面也提示了这个包同其他包有冲突- omitted for conflict with 1.8.19.26)。而我们的系统依赖的notify-tr-client包所依赖的版本是1.8.19.26,于是我们知道是这里冲突了,在POM排除掉依赖,OK了。
这里我们对我们执行的命令做一个简单的说明。mvn dependency:tree -Dverbose -Dincludes=&groupId&:&artifactId&第一部分mvn dependency:tree是maven依赖的分析命令,作用是对我们的项目的依赖进行分析,并输出项目依赖树。
第二部分-Dverbose的作用是添加了verbose一个环境变量,起的作用是在分析项目依赖时输出明细,这样项目中依赖的所有引用都会被输出出来,包含了所有的间接引用,会有很多很多,我们只需要我们要找的,所以就需要第三个参数了。
第三部分-Dincludes=&groupId&:&artifactId&的作用就是进行过滤,只包含我们想要的依赖的依赖时,排除掉其它不需要的,依赖树的所有叶子节点就是我们的找的依赖包。其中的groupId和artifactId可以只填写一个,为了保证准确性,一般都会填两个(填写时不包括尖括号)。
其他方法:
1、对于maven工程,我的办法是使用eclipse来解决,点开pom.xml,切换到hierarchy dependency,右上角搜索对应的包,可以清晰地看到冲突版本
2、可以使用idea,在pom.xml中右单击 选择Diagrams-》show dependencies
3、mvn dependency:tree -Dverbose & tree.log&直接输出冲突的jar文件
阅读(...) 评论()本帖子已过去太久远了,不再提供回复功能。分享解决jar包冲突问题的方法:(看了这个你就能解决所有包冲突问题!) - CSDN博客
分享解决jar包冲突问题的方法:(看了这个你就能解决所有包冲突问题!)
1. 问题描述:(maven+eclipse环境)
&&&&&&&&& 1.1. 昨晚发布这个新功能(接入notify消息中间件)预发失败!报:nested exception is java.lang.NoSuchMethodError: org.springframework.util.ResourceUtils.toURI(Ljava/lang/S)Ljava/net/URI;
&&&&&&&&& 1.2. 但是我本地环境启动jetty没有报这个问题。
2. 解决方法:
&&&&&& 2.1. 到项目根目录执行depth.bat(mvn dependency:tree & dep.txt)意思是把mvn各个包的依赖关系整理出来,发现新接入notify包下面有个spring2.5.1的包,而spring的包在dep.txt已经存在而且是3.1.1版本。
&&&&&& 2.2. 那这样就很清楚了,预发的时候启动应用服务器可能默认使用了2.5.1包,而这个包的ResourceUtils类跟其他jar包不合,所以需要去掉这个低版本的spring包的依赖。这样可以在在pom文件里面的加上&exclusions&&exclusion&&groupId&org.springframework&/groupId&&artifactId&spring&/artifactId&&/exclusion&&/exclusions&
&&&&&& 2.3. 理应问题就这样解决了,但是我本地再测试的时候,发现应用能正常启动,但是测试发送notify消息又出现了包冲突,尼玛~ 报错:java.lang.NoSuchMethodError: com.taobao.eagleeye.EagleEye.rpcClientSend()V。
&&&&&& 2.4. 再次检查dep.txt文件发现eagleEye依赖的是1.0.0版本,而且在tddl的3.0.1.6版本下面。推断是这个eagleEyejar版本低了,但又不能把tddl的3.0.1.6版本随意提高
&&&&&& 2.5. 检查我pom文件里面notify依赖配置是&dependency&&groupId&com.taobao.hsf&/groupId&&artifactId&hsf.notify.spring&/artifactId&&version&1.4.9.6&/version&&/dependency&
&&&&&& 2.6. 推测是hsf管理的notify需要更好的eagleEye版本,而dep.txt文件显示它自己又没有依赖引用更高的eagleEye版本,导致系统默认只能使用了tddl的3.0.1.6版本下面eagleEye1.0.低版本
&&&&&& 2.7. notify官网还有另外一种依赖配置就是:&groupId&com.taobao.notify&/groupId& &artifactId&notify-tr-client&/artifactId& &version&1.8.15&/version&
&&&&&& 2.8. 试下这个,然后加上去掉spring的&exclusions&块,两个问题都就这样解决了!
&&&&&& 2.9. 为什么发布预发之前我本地可以一切正常呢?还原到以前的pom文件查了也有spring2.5.1和spring3.1.1的两个包同时存在。我这里只能推测eclipse里面jvm默认使用了高版本,2.5.1版本的spring被默认忽略了。这点望大牛补充指点。
最后的pom.xml配置:
&dependency&
&& &&& &&&&& &groupId&com.taobao.notify&/groupId&
&& &&& &&&&& &artifactId&notify-tr-client&/artifactId&
&& &&& &&&&& &version&1.8.15&/version&
&& &&& &&&&& &exclusions&
&& &&& &&&&& &!--& 因为hsf.notify.spring 1.4.9.6版本里面带有2.5.1spring,而这个项目上面都是引用3.1.1版本的spring,所以需要这里特殊去掉spring引用 --&
&&&&&&&&&&&&&&&& &exclusion&
&&&&&&&&&&&&&&&&&&& &groupId&org.springframework&/groupId&
& && &&& &&& &&& &&& &&artifactId&spring&/artifactId&
&&&&&&&&&&&&&&& &/exclusion&
&&&&&&&&&&& &/exclusions&
&/dependency&
3. 以后注意经验:
&&&&&& 3.1 以后往pom文件里面加依赖,都需要运行mvn dependency:tree查下各个包是否有冲突的问题,不能出现有两个相同包而版本不一致的情况
&&&&&& 3.2 目前我们系统由于没有使用hsf来统一管理集团内部这些二方库,所以很容易出现这个问题。以后新项目可以考虑使用hsf容器来管理这些,升级应该都更方便
&&&&&& 3.3 既然我们项目没有使用hsg统一管理包的依赖,则以后接入新二方库使用单独引用的方式,这样可以尽量减少eagleEye低版本类似问题!
&&&&&& 3.4 本地运行OK,不一定代表预发和线上就运行OK!预发环境的建立对于公司,尤其是重要项目是非常必要的!
本文已收录于以下专栏:
相关文章推荐
对于Jar包冲突问题,我们开发人员经常都会有碰到,当我们使用一些jar包中的类、方法等,或者有时遇到一些日志系统的问题(参考另一篇文章Jar包冲突导致的日志问题),我们会遇到ClassNo...
jar包冲突几乎是每个java程序员都会遇到的问题,而且特别是大工程,jar包各种依赖,经常性发生包冲突。通常会报这样几个运行时异常:
java.lang.NoSuchMehodError
方法一定要讲究方法, 胡乱的尝试是效果最差, 且最没有提高的方式.工具//打印出工程的所有jar依赖关系
mvn -U dependency:tree -Dverboselog4j, logback,...
ctrl+shift+T,连jar包中的类也可以搜索出来。
这个可以很好的查找jar包冲突的问题。
看某个class在哪些jar包中存在?
昨天写了个《IBM MQ JMS 与spring的整合》,其中这只是通过spring配置,但是真正与业务及DAO实现的时候,就得再整合一下
当把相关的MQ 相关jar引进去的时候,再运行原来项目单元...
【现象描述】tomcat启动报以下错误
java.lang.NoSuchMethodError: org.springframework.beans.factory.annotation.Injec...
1.问题先是遇到一个比较奇怪的问题:Handl nested exception is java.lang.NoSuchMethodError: org.ap...
行为描述:工程添加了个依赖包
1.在导入Android Library工程文件的时候要把library一起拷贝到workspace中,记得打上勾(新手易错...
在测试脚本编写和应用部署时,经常遇到的一个问题是:java.lang.NoSuchMethodError。这个问题产生的根本原因是运行时应用加载的jar包版本不是应用代码真正需要的版本。要解决这个问题...
他的最新文章
讲师:王禹华
讲师:宋宝华
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)

我要回帖

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

 

随机推荐