`

maven依赖冲突处理

 
阅读更多

不知道你在使用Maven时是否遇到过诸如"NoSuchMethodError"或"ClassNotFoundException"之类的问题,甚至发生这些问题的Java类你没都没有听说过。要搞清楚这里面的缘由,我们得学习Maven对依赖冲突的处理机制。

 

Maven采用“最近获胜策略(nearest wins strategy)”的方式处理依赖冲突,即如果一个项目最终依赖于相同artifact的多个版本,在依赖树中离项目最近的那个版本将被使用。让我们来看看一个实际的例子。

 

请下载本文的github源代码:https://github.com/davenkin/maven-dependency-conflict-demo

 

我们有一个web应用resolve-web,该工程依赖于project-A和project-B,project-A依赖于project-common的1.0版本并调用其中的sayHello()方法。project-B依赖于project-C,而project-C又进一步依赖于project-common的2.0版本并调用其中的sayGoodBye()方法。project-common的1.0和2.0版本是不同的,1.0中之包含sayHello()方法,而2.0中包含了sayHello()和sayGoodBye()两个方法。整个项目的依赖关系如下图:

 


 

根据Maven的transitive依赖机制,resolve-web将同时依赖于project-common的1.0和2.0版本,这就造成了依赖冲突。而根据最近获胜策略,Maven将选择project-common的1.0版本作为最终的依赖。这和Gradle不同,Gradle在默认情况下将选择最新的版本作为获胜版本。而对于Maven,由于proejct-common的1.0版本比2.0版本在依赖树中离resolve-web更近,故1.0版本获胜。在resolve-web中执行"mvn dependency:tree -Dverbose"可以看到resolve-web的依赖关系:

 

复制代码
[INFO] resolve-web:resolve-web:war:1.0-SNAPSHOT

[INFO] +- junit:junit:jar:3.8.1:test

[INFO] +- project-B:project-B:jar:1.0:compile

[INFO] |  \- project-C:project-C:jar:1.0:compile

[INFO] |     \- (project-common:project-commmon:jar:2.0:compile - omitted for conflict with 1.0)

[INFO] +- project-A:project-A:jar:1.0:compile

[INFO] |  \- project-common:project-commmon:jar:1.0:compile

[INFO] \- javax.servlet:servlet-api:jar:2.4:provided
复制代码

 

 

由上可知,project-common:project-commmon:jar:2.0被忽略掉了。此时在resolve-web的war包中将只包含project-common的1.0版本,于是问题来了。由于project-common的1.0版本中不包含sayGoodBye()方法,而该方法正是project-C所需要的,所以运行时将出现“NoSuchMethodError”。(请根据本文github工程中的README.md中的步骤重现该错误信息。)

 

对于这种有依赖冲突所导致的问题,我们有两种解决方法。

 

方法1:显式加入对project-common 2.0版本的依赖。先前的2.0版本不是离resolve-web远了点吗,那我们就直接将它作为resolve-web的依赖,这不就比1.0版本离resolve-web还近吗?在resove-web的pom.xml文件中直接加上对project-common 2.0 的依赖:

 

<dependency>       
   <groupId>project-common</groupId>      
   <artifactId>project-commmon</artifactId>  
   <version>2.0</version>   
</dependency>  

 

方法2:resolve-web对project-A的dependency声明中,将project-common排除掉。在resolve-web的pom.xml文件中修改对project-A的dependency声明:

 

复制代码
<dependency>  
          <groupId>project-A</groupId>  
          <artifactId>project-A</artifactId>  
          <version>1.0</version>  
          <exclusions>  
              <exclusion>  
                  <groupId>project-common</groupId>  
                  <artifactId>project-commmon</artifactId>  
              </exclusion>  
          </exclusions>  
</dependency>  
复制代码

 

此时再在resolve-web中执行"mvn dependency:tree -Dverbose",结果如下:

 

复制代码
......

[INFO] resolve-web:resolve-web:war:1.0-SNAPSHOT

[INFO] +- junit:junit:jar:3.8.1:test

[INFO] +- project-B:project-B:jar:1.0:compile

[INFO] |  \- project-C:project-C:jar:1.0:compile

[INFO] |     \- project-common:project-commmon:jar:2.0:compile

[INFO] +- project-A:project-A:jar:1.0:compile

[INFO] \- javax.servlet:servlet-api:jar:2.4:provided

......
复制代码

 

此时的依赖树中已经不包含project-common的1.0版本了。

 

另外,我们还可以在project-A中将对project-common的依赖声明为optional,optional即表示非transitive,此时当在resolve-web中引用project-A时,Maven并不会将project-common作为transitive依赖自动加入,除非有别的项目(比如project-B)声明了对project-common的transitive依赖或者我们在resolve-web中显式声明对project-common的依赖(方法一)。

转自:https://www.cnblogs.com/davenkin/p/advanced-maven-resolve-dependencies-conflicts.html

 

优化依赖

可概括为三个命令

mvn dependency:list

表示依赖列表,maven eclipse插件已经实现,有图形化显示,在pom.xml的dependencies页

mvn dependency:tree

表示依赖列表,maven eclipse插件已经实现,有图形化显示,在pom.xml的dependency hierarchy页

mvn dependency:analyze

查找出在编译和测试中未使用但显示声明的依赖

 

转自:https://blog.csdn.net/lastsweetop/article/details/8493475

分享到:
评论

相关推荐

    maven依赖冲突插件 MavenHelper-4.26.0

    maven依赖冲突插件:idea依赖很多的时候 可以使用插件帮我们快速查看冲突的依赖 并快速的解决依赖

    maven依赖小例子

    这大大简化了项目的构建过程,但同时也可能导致依赖冲突,需要通过排除机制或调整依赖版本来解决。 在`&lt;dependency&gt;`标签内,还可以添加`&lt;exclusions&gt;`子标签来排除特定的依赖,避免冲突。例如: ```xml ...

    解决Maven依赖冲突

    对于第二类依赖冲突,同名类存在于多个不同的依赖 jar 包当中,这种情况是 Maven 无法解决的,因为 Maven 只会为你针对同一个 Jar 包的不同版本进行仲裁,而这俩是属于不同的 Jar 包,超出了 Maven 的依赖管理范畴。...

    试试 IDEA 解决 Maven 依赖冲突的高能神器.docx

    总的来说,解决Maven依赖冲突需要理解其工作原理,结合IDEA提供的工具,如Maven Helper插件和依赖结构图,可以有效地定位和排除冲突,保持项目的稳定性和可维护性。在实际开发中,避免引入不必要的依赖和定期清理...

    详解maven依赖冲突以及解决方法

    maven依赖冲突及解决方法 maven依赖冲突是指项目依赖的某一个jar包,有多个不同的版本,因而造成类包版本冲突。这种情况下,项目可能会出现无法编译或运行的错误。 依赖冲突的原因: 依赖冲突很经常是类包之间的...

    idea插件一键解决maven依赖冲突

    本插件参考58开源插件MavenManager,采用dependencyManagement方式,一键解决Java开发过程中使用maven作为依赖管理时的jar包依赖冲突问题,相比MavenHelper更加省时省力,jar包版本采用最新版本号原则

    maven依赖包(用于博客项目)

    本资源“maven依赖包(用于博客项目)”显然包含了一系列与博客项目相关的Maven依赖,这些依赖可能包括数据库连接库、模板引擎、日志框架、安全组件以及其他有助于构建博客平台的Java库。 1. **Maven仓库**: ...

    Maven 依赖详细理解.pdf

    依赖范围(scope)是Maven依赖管理的一个重要概念。scope定义了依赖项的使用范围,主要有以下几个选项:compile、provided、runtime和test。compile表示依赖项在编译时需要,provided表示依赖项在编译和测试时需要,但...

    dubbo项目maven依赖

    当执行`mvn clean package`命令时,Maven会清理目标目录,然后编译源代码,处理资源文件,最后将结果打包成指定格式(如JAR或WAR)。 在尝试编译Apache Dubbo源码时,可能会遇到以下问题: 1. **依赖版本不匹配**...

    Maven的依赖验证项目

    在压缩包中的“Maven依赖特性”可能包含了一些特定的示例或者配置,用于展示Maven如何处理不同类型的依赖特性,例如:范围(scope,如compile、test等)、排除依赖、强制版本等。通过实际操作这些例子,你可以更深入...

    ​实现maven项目中多版本依赖兼容使用解决方案

    总结来说,解决Maven依赖冲突需要深入理解Maven的依赖管理和类加载机制。在本案例中,通过修改冲突依赖的类路径,可以实现多版本依赖的共存,但这种方式并不适用于所有场景,因此在实际应用中应谨慎考虑。在可能的...

    maven 中引入依赖的包

    这在排查依赖冲突或理解项目依赖关系时非常有用。 除了Maven的默认仓库外,还可以通过`&lt;repository&gt;`标签添加自定义的远程仓库地址,这对于处理公司内部私有库或者第三方库的非中央仓库发布的情况非常关键。 在...

    cleanLastUpdated maven依赖冲突清理.zip

    导入maven仓库的时候总是提示jar文件导入不成功的错误,后经过分析,发现不成功的文件夹里面存在lastUpdate后缀名的文件。 用途:删除lastupdated脚本文件 注:路径需要自己用文本编辑器打开后进行修改

    maven_package 依赖包(完整)

    6. **依赖冲突解决**:Maven采用"最接近原则"解决依赖冲突,即当两个或更多依赖引入相同jar的不同版本时,会选择离当前模块最近的版本。 7. **聚合与继承**:聚合(aggregation)允许一个项目包含其他项目,而继承...

    MavenHelper插件 帮你检查maven的各种冲突

    这款插件专为IntelliJ IDEA设计,旨在帮助开发者轻松解决Maven依赖冲突问题,提高开发效率。 **MavenHelper插件介绍** MavenHelper是一款强大的IDEA插件,它的主要功能是分析和可视化Maven项目的依赖树,帮助开发者...

    maven依赖的压缩包

    5. **解决依赖问题**:如果遇到依赖冲突,Maven遵循“最接近原则”(nearest wins)进行解决,但也可以通过调整POM中的dependencyManagement来全局控制依赖版本。 6. **使用Maven仓库**:除了中央仓库外,还可以...

    Maven中的依赖

    5. **仓库**:Maven依赖的存储库,包括本地仓库(默认在用户目录下)和远程仓库(如中央仓库mvnrepository.com)。当本地仓库没有所需依赖时,Maven会尝试从远程仓库下载。 6. **排除依赖(exclude)**:有时候我们...

    精通Maven依赖冲突:策略、工具与实战技巧

    Maven的核心是一个项目对象模型(POM),利用这个模型的概念,可以管理项目的构建、依赖、文档创建、站点发布和分发等步骤。 Maven的主要目标是提供一个可重复使用、可维护且易于理解的项目综合模型,以及与此模型...

    关于项目、产品maven依赖问题

    然而,当多个项目或产品之间存在相互依赖时,如果不正确地管理这些依赖,可能会导致各种问题,如资源冲突和版本不一致,这正是"关于项目、产品maven依赖问题"所涉及的关键点。 1. 问题阐述: 在一个典型的多项目...

    Maven离线依赖包v2

    2. 版本兼容性:需要确保离线包中的依赖版本与项目POM.xml中声明的版本匹配,否则可能会出现版本冲突。 3. 缺少依赖:如果项目需要的某个特定版本不在离线包中,仍需网络下载。 在实际开发中,为了更好地利用Maven...

Global site tag (gtag.js) - Google Analytics