微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何解决maven冲突

转载自:https://blog.csdn.net/q15102780705/article/details/120763966

 

=========================================================

 

jar包冲突产生的原因

举例说明:

  1.   依赖链路一:A -> B -> C -> G21(guava 21.0)
  2.   依赖链路二:D -> F -> G20(guava 20.0)

假设项目中同时引入了A和D的依赖,按照依赖传递机制和认依赖调节机制(第一:路径最近者优先;第二:第一声明优先),认会引入G20版本的jar包,而G21的jar包不会被引用。

如果C中的方法使用了G21版本中的某个新方法(或类),由于Maven的处理,导致G21并未被引入。此时,程序在调用对应类时便会抛出ClassNotFoundException异常,调用对应方法时便会抛出NoSuchMethodError异常。

排查定位jar包冲突
在高版本的IDEA中已经自带了Maven依赖管理插件,依次执行:打开pom.xml文件,在文件内右击,选择Maven,选择Show Dependencies即可查看Maven的依赖层级结构:

Maven依赖结构

执行之后展示的效果便是最开始的spring-boot-web那样效果,在图中可以清楚的看到都使用了哪些依赖,它们的层级,是否有冲突的jar包等。冲突部分会用红色标出,同时标出Maven认选择了哪个版本。

如果你的IDEA版本中认没有Maven管理插件,也可安装Maven Helper,通过这块插件来帮你分析jar包冲突。

Maven Helper

安装完插件,重启之后,打开pom.xml文件,在文件下面的Dependency Analyzer视图中便可以看到jar包冲突的结果分析:

Jar包冲突分析

 

此时,关于哪些jar包冲突了,便一目了然。同时,可以右击冲突的jar包,执行”Exclude“进行排除,在pom.xml中便会自动添加排除jar包属性

对于本地环境可以利用Maven Helper等插件解决,但在预生产或生成环境中就没那么方便了。此时可以通过mvn命令来定位突出的细节。

执行如下mvn命令:

mvn dependency:tree -Dverbose

注意不要省略-Dverbose,要不然不会显示被忽略的包。

执行结果如下:

mvn命令查看

 通过这种形式,也可以清晰的看出哪些jar包发生了冲突。

如何统一jar包依赖
像上面截图所示,如果一个项目有N多个子项目构成,项目之间可能还有依赖关系,jar包冲突不可避免,此时可采用父pom,统一对版本进行管理,一劳永逸。

通常做法,是在parent模块的pom文件中尽可能地声明所有相关依赖jar包的版本,并在子pom中简单引用(不再指定版本)该构件即可。

比如在父pom.xml中定义Lombok的版本:

  1.   <dependencyManagement>
  2.       <dependencies>
  3.           <dependency>
  4.               <groupId>org.projectlombok</groupId>
  5.               <artifactId>lombok</artifactId>
  6.               <version>1.18.10</version>
  7.           </dependency>
  8.       </dependencies>
  9.   </dependencyManagement>

在子module中便可定义如下:

  1.   <dependencies>
  2.       <dependency>
  3.           <groupId>org.projectlombok</groupId>
  4.           <artifactId>lombok</artifactId>
  5.       </dependency>
  6.   </dependencies>

通过这种方式,所有的子module中都采用了统一的版本。版本锁定后则不考虑依赖的声明顺序或依赖的路径,以锁定的版本的为准添加到工程中, 此方法在企业开发中常用。

如下的配置是锁定了spring-beans和spring-context的版本:

注意:在工程中锁定依赖的版本并不代表在工程中添加了依赖, 如果工程需要添加锁定版本的依赖则需要单独添加标签, 如下:

上边添加的依赖并没有指定版本, 原因是已在中锁定了版本,所以在下不需要再指定版本。

 

解决jar包冲突的方法
这里基于Maven项目介绍几种场景下解决Jar冲突的方法

Maven认处理:采用此种方法,要牢记Maven依赖调节机制的基本原则,路径最近者优先和第一声明优先;
排除法:上面Maven Helper的实例中已经讲到,可以将冲突的jar包在pom.xml中通过exclude来进行排除;
版本锁定法:如果项目中依赖同一jar包的很多版本,一个个排除非常麻烦,此时可用版本锁定法,即直接明确引入指定版本的依赖。根据前面介绍Maven处理jar包基本原则,此种方式的优先级最高。这种方法一般采用上面我们讲到的如何统一jar包依赖的方式。

jar包冲突的本质:Java应用程序因某种因素,加载不到正确的类而导致其行为跟预期不一致。

具体分两种情况:

情况一:项目依赖了同一jar包的多个版本,并且选错了版本;
情况二:同样的类在不同的jar包中出现,导致JVM加载了错误的类;
情况一,也是本文重点讨论的场景,也就是说引入了多个jar包版本,不同的jar包版本有不同的类和方法。由于(不懂)Maven依赖树的仲裁机制导致Maven加载了错误jar包,从而导致jar包冲突;

情况二,同一类在不同的jar包中出现。这种情况是由于JVM的同一个类加载器对于同一个类只会加载一次,现在加载一个类之后,同全限定名的类便不会进行加载,从而出现jar包冲突的问题。

针对第二种情况,如果不是类冲突抛出了异常,你可能根本意识不到,所以就显得更为棘手。这种情况就可以采用前文所述的通过分析不同类加载器的优先级及加载路径、文件系统的文件加载顺序等进行调整来解决

原文地址:https://www.cnblogs.com/hd92/p/16286169.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


前言 此种方式已过时,不再推荐,当下推荐方式:自我救赎 → 利用 IDEA 和 Spring Boot 搭建 SSM 本文旨在利用maven搭建ssm环境,而关于maven的具体内容,大家可以去阅读《Maven 实战》。其实园内这方面文章已有不少,那么为什么我还要重复造轮子呢?我只是想记录自己的实践
前言 项目中用到了maven,而且用到的内容不像利用maven/eclipse搭建ssm(spring+spring mvc+mybatis)用的那么简单 maven的核心是 pom.xml,那么我们就来看看那些不同的地方 给我印象最深的就是如下四个元素:modules、parent、propert
开心一刻 今天去幼儿园接小侄女,路上聊起了天 小侄女:小叔,今天我吃东西被老师发现了 我:老师说了什么 小侄女:她说拿出来,跟小朋友一起分享 我:那你拿出来了吗 小侄女一脸可怜的看向我,说道:没有,我没有那么多鼻屎 SPI 概念 SPI 全称&#160;Service Provider Interf
本篇文章和大家了解一下怎么搭建maven私有仓库。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。在本篇文章中,我们将介绍如何搭建一个Maven...
今天小编给大家分享的是如何解决Maven依赖冲突,相信很多人都不太了解,为了让大家更加了解,所以给大家总结了以下内容,一起往下看吧。一定会有所收获的哦。目...
这篇文章主要介绍了Maven仓库分类的优先级是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Maven仓库分类的优先级是什么文...
本篇内容主要讲解“Maven怎么实现自己的starter依赖”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Maven怎
本篇内容主要讲解“maven不能下载oraclejdbc驱动的问题怎么解决”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大...
这篇文章主要介绍了怎么使用maven基本命令打包包名的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇怎么使用maven基本命令打包包...
本篇内容介绍了“maven中profile如何使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧...