在IDEA里解决maven的pom引用jar包冲突


前言

有的时候,我们要给系统添加一个新功能,可能需要引入新的pom依赖,一切都搞定好后,运行程序却发现报NoClassDeFoundError错误,或者其它莫名奇妙的问题。
这个时候很有可能就是新引入的pom依赖里某个jar包和之前系统已有的冲突了。

那么,该从何下手呢?

四种解决思路和原则

共有四种解决方式

1、第一声明优先原则

在pom.xml配置文件中,如果有两个名称相同版本不同的依赖声明,那么先写的会生效。
所以,先声明自己要用的版本的jar包即可。

2、路径近者优先

直接依赖优先于传递依赖,如果传递依赖的jar包版本冲突了,那么可以自己声明一个指定版本的依赖jar,即可解决冲突。

3、排出原则

传递依赖冲突时,可以在不需要的jar的传递依赖中声明排除,从而解决冲突。

例子

<dependency>
    <groupId>org.apache.struts</groupId>
    <artifactId>struts2-spring-plugin</artifactId>
    <version>2.3.24</version>
    <exclusions>
      <exclusion>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
      </exclusion>
    </exclusions>
</dependency>

4、版本锁定原则(最常使用)

在配置文件pom.xml中先声明要使用哪个版本的相应jar包,声明后其他版本的jar包一律不依赖。解决了依赖冲突。

例子:

<properties>
    <spring.version>4.2.4.RELEASE</spring.version>
    <hibernate.version>5.0.7.Final</hibernate.version>
    <struts.version>2.3.24</struts.version>
</properties>
<!-- 锁定版本,struts2-2.3.24、spring4.2.4、hibernate5.0.7 -->
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
</dependencies>
</dependencyManagement>

解决方案

1.mvn dependency:tree

mvn dependency:tree 可以完整清晰的展示出所有的jar包(包括 传递性依赖),并且是以 层级树方式展现,非常直观。

这边又有两种使用方式

1.1 mvn dependency:tree>temp/tree.txt

用mvn dependency:tree>temp/tree.txt,直接输出到当前项目下,然后在idea中打开,搜索要找的jar包名字即可.

这里的 “+-” 和”\-“并没有什么意义,只是为了让分级看起来更直观。

 

如图,可看到jline是在zookeeper中被间接引用的

1.2 用include参数

H:\下载\新建文件夹\yjg>mvn dependency:tree -Dincludes=jline
[INFO] Scanning for projects…
[WARNING]
[WARNING] Some problems were encountered while building the effe
[WARNING] ‘build.plugins.plugin.version’ for org.apache.maven.pl
[WARNING]
[WARNING] It is highly recommended to fix these problems because
[WARNING]
[WARNING] For this reason, future Maven versions might no longer
[WARNING]
[INFO]
[INFO] ———————————————————
[INFO] Building esshop Maven Webapp 0.0.1-SNAPSHOT
[INFO] ———————————————————
[INFO]
[INFO] — maven-dependency-plugin:2.8:tree (default-cli) @ essh
[INFO] esshop:esshop:war:0.0.1-SNAPSHOT
[INFO] – org.apache.zookeeper:zookeeper:jar:3.3.3:compile
[INFO] – jline:jline:jar:0.9.94:compile
[INFO] ———————————————————
[INFO] BUILD SUCCESS
[INFO] ———————————————————
[INFO] Total time: 3.256 s
[INFO] Finished at: 2017-12-05T08:57:49+08:00

如果想看冲突和重复的具体情况,用verbose参数

如图,用了程序显式定义的版本

H:\下载\新建文件夹\yjg>mvn dependency:tree -Dverbose -Dincludes=commons-collections
[INFO] Scanning for projects…
[WARNING]
[WARNING] Some problems were encountered while building the effective model for esshop:esshop:war:0.0.1-SNAPSHOT
[WARNING] ‘build.plugins.plugin.version’ for org.apache.maven.plugins:maven-compiler-plugin is missing. @ line 621,
[WARNING]
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
[WARNING]
[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
[WARNING]
[INFO]
[INFO] ————————————————————————
[INFO] Building esshop Maven Webapp 0.0.1-SNAPSHOT
[INFO] ————————————————————————
[INFO]
[INFO] — maven-dependency-plugin:2.8:tree (default-cli) @ esshop —
[INFO] esshop:esshop:war:0.0.1-SNAPSHOT
[INFO] +- commons-collections:commons-collections:jar:3.2.1:compile
[INFO] +- org.hibernate:hibernate:jar:3.2.2.ga:compile
[INFO] | – (commons-collections:commons-collections:jar:2.1.1:compile – omitted for conflict with 3.2.1)
[INFO] +- org.hibernate:hibernate-annotations:jar:3.4.0.GA:compile
[INFO] | – org.hibernate:hibernate-core:jar:3.3.0.SP1:compile
[INFO] | – (commons-collections:commons-collections:jar:3.1:compile – omitted for conflict with 3.2.1)
[INFO] +- org.springframework.security:spring-security-core:jar:2.0.4:compile
[INFO] | – (commons-collections:commons-collections:jar:3.2:compile – omitted for conflict with 3.2.1)
[INFO] +- org.apache.velocity:velocity:jar:1.5:compile
[INFO] | – (commons-collections:commons-collections:jar:3.1:compile – omitted for conflict with 3.2.1)
[INFO] – net.sf.json-lib:json-lib:jar:jdk15:2.4:compile
[INFO] – (commons-collections:commons-collections:jar:3.2.1:compile – omitted for duplicate)
[INFO] ————————————————————————
[INFO] BUILD SUCCESS

2. 查看Maven的依赖关系图

  1. 打开项目的Maven界面,一般在右侧工具栏
  2. 按下Ctrl + shift + Alt + U组合键,或者点击上面菜单栏的倒数第三个按钮

 

 

 

 

需要说明的是不同的idea版本,具体的工具栏可能略有不同,但是差别不会太大,我截图的这个是2019版本,之前的2016版本我也用过,有些微差别。

这张图有以下几点

  1. 可以放大缩小
  2. 双击可以导航到指定的pom文件
  3. 冲突的jar包关系线会用红色的线标记
  4. 通过这个线可以找到你在pom里面定义的最上层依赖

3. 通过Project Structure或者Maven Dependencies来定位

上面的依赖关系图虽然很直观,但是有一个缺点就是不能搜索关键字定位,一个简单的示例demo就这么多依赖jar包了,正常生产使用的系统那这张图要想看清楚定位到冲突的jar包(虽然有红线标记,但是复杂的系统,冲突的jar包也多),非常不方便。

所以我个人更喜欢通过 Project Structure或者Maven Dependencies来定位有冲突的jar包。

正常情况下,通过错误提示,我们能知道大概是什么jar包冲突了,这边比方说Maven: com.google.guava:guava 这个冲突了(这个可是非常容易冲突的)。

依次点开 File-> Project Structure ->Modules->选中Source->Denpendencies

 

 

这个有个好处,就是直接 Denpendencies 界面输入关键字,就能定位想要的jar包,如果有多个结果,使用键盘上的上下键就能移动光标。

找到它,然后右击,点击remove。重启,冲突就解决了。

不过,这种方法,只是当前有效,如果maven重新编译过后,还是会恢复成原来的。原理也简单,那就是它并没有从pom文件里exclude该jar包。

最简单的办法其实就是在Maven- Denpendencies里搜索(同上)关键字定位jar包

 

 

就能知道它的层级关系,然后去pom文件里

总结

不管是何种方法,最后体现出来的代码就是要在pom文件里把冲突的jar包exclusion掉。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM