在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