设为首页 收藏本站
查看: 898|回复: 0

[经验分享] mvn dependency:tree

[复制链接]

尚未签到

发表于 2017-2-28 10:10:39 | 显示全部楼层 |阅读模式
jar依赖冲突解决实践



前言
  随着功能的增多,各种中间件的引入。应用以来的各种jar的规模极具膨胀,出现jar冲突和Class冲突的问题层出不穷,让人不胜其扰。本文针对冲突,提供一个排查和定位问题的最佳实践。实践中尽量不借助第三方工具,而使用maven或者Linux的自带命令行。

Maven构建的应用的jar冲突
  目前最为最流行的项目构建和管理工具,在目前的互联网应用中被广泛使用。maven框架很大的一个便利就是对于jar的依赖管理,它自然提供了一些工具帮助开发者进行依赖分析。maven存在坐标的概念。groupId,artifactId,version三个维度定位到一个唯一的jar。


<dependency>
<groupId>com.taobao.diamond</groupId>
<artifactId>diamond-client</artifactId>
<version>3.6.0</version>
<type>jar</type>
<scope>compile</scope>
</dependency>

  对于版本,有一个很宽泛的范围
  [3.6.0,4.0.0) 要求的依赖版本>=3.6.0且<4.0.0
  [,3.6.0] 要求的依赖版本<=3.6.0
对于应用来讲,还是固定一个版本为好,夸版本有太多不可预知的情况存在。

静态代码检查
  通过mvn dependency:tree 命令查看依赖树


[INFO] \- com.alibaba.china.shared:credit_shared.ruleengine.biz:jar:1.0-SNAPSHOT:compile
[INFO]    +- com.alibaba.china.shared:credit_shared.ruleengine.api:jar:1.0-SNAPSHOT:compile
[INFO]    +- com.alibaba.china.shared:credit_shared.ruleengine.dal:jar:1.0-SNAPSHOT:compile
[INFO]    +- org.antlr:antlr:jar:3.3:compile
[INFO]    +- org.antlr:antlr-runtime:jar:3.3:compile
[INFO]    |  \- org.antlr:stringtemplate:jar:3.2.1:compile
[INFO]    +- org.mvel:mvel2:jar:2.1.3.Final:compile
[INFO]    +- org.drools:knowledge-api:jar:5.5.0.Final:compile
[INFO]    +- org.drools:drools-core:jar:5.5.0.Final:compile
[INFO]    |  \- org.drools:knowledge-internal-api:jar:5.5.0.Final:compile
[INFO]    \- org.drools:drools-compiler:jar:5.5.0.Final:compile
[INFO]       +- org.antlr:antlr:jar:2.7.7:compile
[INFO]       +- org.eclipse.jdt.core.compiler:ecj:jar:3.5.1:compile
[INFO]       \- com.thoughtworks.xstream:xstream:jar:1.4.1:compile
[INFO]          +- xmlpull:xmlpull:jar:1.1.3.1:compile
[INFO]          \- xpp3:xpp3_min:jar:1.1.4c:compile

  通过静态代码扫描的方式,能分析出来jar之间的依赖关系。举例credit_shared.ruleengine.biz-1.0-SNAPSHOT.jar依赖了antlr-3.3.jar。org.antlr:antlr-3.3.jar在maven中的坐标是


<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr</artifactId>
<version>3.3</version>
<type>jar</type>
<scope>compile</scope>  
</dependency>


依赖仲裁
  从上面的依赖树,出现了另外一个版本的jar——org.antlr:antlr:jar:2.7.7:compile,这就出现了依赖仲裁的问题。
maven 2.2.1版本仲裁规则:


  • 按照项目总POM的DependencyManager版本声明进行仲裁(覆盖),但无警告
  • 如无仲裁声明,则按照依赖最短路径确定版本
  • 若相同路径,有严格区间限定的版本优先
  • 若相同路径,无版本区间,则按照先入为主原则
  如要解决冲突问题,很多时候都用到exclusions,如A->B->D(v1),A->C-D(v2),要指定A->D(v1),则需要在声明C的依赖时候通过exclusions列表排除掉对D(v2)的依赖。
  要更好理解依赖仲裁,需要了解以下附带知识。

maven classpath
  maven中有三种classpath:


  • 编译classpath:编译项目代码,依赖的jar会被引入到classpath
  • 测试classpath:编译和执行测试部分代码,如单元测试,集成测试,依赖会被引入到classpath
  • 运行classpath:实际运行代码的时候,依赖的jar会被引入到classpath

scope:依赖范围
  scope就是为了解决jar在classpath中的可见性。scope有以下几个可选项
compile:默认值,对编译classpath、测试classpath、运行classpath都有效,在三个阶段都需要指定的jar
provided:编译和测试可用,不会被传递依赖,不会被打包。例:依赖于web容器中的提供的一个jar包,在编译的时候需要加入依赖(web容器还没有介入),运行的时候由web容器来提供。如servlet-api。
test:执行单元测试时可用,不会被打包,不会被传递依赖
runtime:运行和测试时需要,但编译时不需要。最典型的例子是JDBC的驱动,编译时只需要提供驱动的API即可,在运行和测试阶段,需要加载到具体的驱动实现。
system:跟provided一致,显示制定依赖路径,一般是指定了本地的仓库之外的类库文件。可能造成不可依赖性,不推荐使用。

传递性依赖
  A->B,B->C,则A->C。这是传递性依赖。依赖是有范围的,A->B,B->C的依赖范围决定了A->C的依赖范围。

A->Ccompileprovidedtestruntime



compile
compile


runtime



provided
provided
provided

provided



test
test


test



runtime
runtime


runtime


可选依赖


    <dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr</artifactId>
<version>3.3</version>
<type>jar</type>
<scope>compile</scope>  
<optional>true</optional>
</dependency>

  A->B,B->C(可选),B->D(可选),则A不会通过传递依赖到C或者D。

非Maven项目或者不同坐标的jar出现Class冲突,
  上面介绍的是jar相同而版本不同,如antlr-3.3.jar,antlr-3.2.jar类似情况的冲突解决方案。这种情况一般出现在中间件升级。下面介绍坐标不同,如antlr-old-3.3.jar、antlr-new.jar,而jar中包含了类路径完全相同的类的情况。
出现这种情况,一般的异常提示都是“XXX类has no such method XXXX”之类的。这些异常提示基本可以定位成Class不是你要的Class,只不过Class的全路径是相同的,最大的可能也就是ClassLoader加载了另外一个jar的同名类。所以,首先要排查到该类是从哪个具体jar中来的。JVM提供了这样的功能,查看加载类的情况


java -verbose:class

  类加载情况,如SubscriptionInfo类加载自file:/home/zhao/web-deploy/jettyserver/tmp/jetty-0.0.0.0-34200-root.war--any-/webinf/WEB-INF/lib/pc2.common-1.2.5.jar


[Loaded com.alibaba.pc2.common.remote.subscription.SubscriptionInfo from file:/home/zhao/web-deploy/jetty_server/tmp/jetty-0.0.0.0-34200-root.war-_-any-/webinf/WEB-INF/lib/pc2.common-1.2.5.jar]
[Loaded com.alibaba.pc2.common.domain.productpackage.PackageInfo from file:/home/zhao/web-deploy/jetty_server/tmp/jetty-0.0.0.0-34200-root.war-_-any-/webinf/WEB-INF/lib/pc2.common-1.2.5.jar]

  而同样在pmap pid可以进程的内存镜像。 jps -v查看pid,再通过pmap pid > map.txt,从map.txt中查到


00007fa4ae174000     20K r-xs-  /home/zhao/web-deploy/jetty_server/tmp/jetty-0.0.0.0-34200-root.war-_-any-/webinf/WEB-INF/lib/pc2.common-1.2.5.jar

  得到确认后,如果是maven工程,则通过依赖树查询到是具体哪个jar依赖了这个错误引用,在pom文件中exclusions掉该jar即可。
如果是非maven工程,则通过其他方式把错误引用排除掉即可。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-348284-1-1.html 上篇帖子: 大众点评cat系统的搭建笔记 下篇帖子: 阿里云服务器Linux CentOS安装配置(一)购买阿里云服务器
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表