Maven中關於jar包衝突的2種排查方案及3種解決方式

導讀:在實際開發中,多模塊項目常會使用Maven進行包管理。在poml文件中進行包依賴時,常存在引入一個jar包中默認依賴了其他的jar包的情況。這樣很容易導致jar包衝突,從而產生一些詭異問題,如版本問題導致的類、方法找不到等。下面我們將聊聊具體關於依賴衝突產生的原因、排查方式以及解決的方案。

Maven中關於jar包衝突的2種排查方案及3種解決方式

依賴傳遞的概念

舉個簡單例子,比如一個多模塊項目依賴關係如下圖。其中bepe-dal引入了common-lib,當bepe-manager模塊中引入bepe-dal時,common-lib這個依賴也會被引入到bepe-manager模塊中,這個就是依賴傳遞。

Maven中關於jar包衝突的2種排查方案及3種解決方式

依賴衝突的概念

依賴衝突指當模塊中引入很多jar包時,如果其中存在著groupId和artifactId 一樣,但是version不一樣的兩個jar包,這就是依賴衝突。那麼在應用時會選用哪一個version呢?這就是我們接下來要討論的衝突解決方式。

Maven中關於jar包衝突的2種排查方案及3種解決方式

依賴衝突該是怎麼解決的?

  • 最短路徑原則
  • 聲明優先原則
  • 依賴排除

1、最短路徑原則

當存在groupId和artifactId一致但是version不一致的jar包衝突時,模塊會自動選擇距離自己路徑短的包。如:bepe-manager到common-lib(1.0)的距離為2,bepe-manager到common-lib(2.0)的距離為1,就會選擇距離短的common-lib(2.0),這就是最短路徑原則。

Maven中關於jar包衝突的2種排查方案及3種解決方式

當衝突包路徑距離長度一樣時,這個時候就會依據其在pom文件中聲明的先後順序。

Maven中關於jar包衝突的2種排查方案及3種解決方式

在manager模塊pom.xml中,如果先引用bepe-common,就會用2.0版本的common-lib。

<dependency> 
<groupid>com.company.bepe/<groupid>
<artifactid>bepe-common/<artifactid>
<version>2.2/<version>
/<dependency>
<dependency>
<groupid>om.company.bepe/<groupid>
<artifactid>bepe-dal/<artifactid>
<version>2.2/<version>
/<dependency>

3、依賴排除

通過<exclusions>標籤將不需要依賴的包進行排除,通過這種方式我們就靈活進行取捨。但是該如何發現衝突呢?接下來將討論關於依賴衝突排查的方式。/<exclusions>

Maven中關於jar包衝突的2種排查方案及3種解決方式

依賴衝突情況該怎麼排查?

我們可以藉助一些插件工具幫助找出衝突jar的具體位置。下面分享一下我在項目中排查並解決包衝突的兩種方式。

  • maven-enforcer-plugin 插件
  • Maven Helper 插件

maven-enforcer-plugin插件

Maven提供了Maven-Enforcer-Plugin插件 , 用來校驗約定遵守情況,比依賴 jar 包的版本等等。當規則檢查不通過的時候則會構建失敗。

1、在pom.xml中引入該插件

Maven中關於jar包衝突的2種排查方案及3種解決方式

rules內則是定義校驗規則,通過配置<dependencyconvergence>可實現重複依賴檢測。也支持自定義做一些其他檢驗如版本檢驗等。關於maven-enforcer-plugin插件rules的其他配置用法,感興趣的朋友們,可以去查閱其相關的資料。

<rules> 

\t\t\t<requiremavenversion>
\t\t\t\t<version>3.0.4/<version>
\t\t\t/<requiremavenversion>
\t\t\t
\t\t\t<requirejavaversion>
\t\t\t\t<version>6.0/<version>
\t\t\t/<requirejavaversion>
\t\t\t<banneddependencies>
\t\t\t\t
\t\t\t\t<searchtransitive>true/<searchtransitive>
\t\t\t\t<excludes>
\t\t\t\t\t<exclude>junit:junit/<exclude>
\t\t\t\t/<excludes>
\t\t\t\t<message>must use TestNG/<message>
\t\t\t/<banneddependencies>
\t\t/<rules>

2、配置好插件後進行項目構建,當存在包衝突時會在console中打印出來。

Maven中關於jar包衝突的2種排查方案及3種解決方式

3、依據信息便可將不需要的jar包通過<exclusion>排除掉。/<exclusion>

Maven中關於jar包衝突的2種排查方案及3種解決方式

Maven Helper

使用IntelliJ IDE的Maven helper插件方便找到和排除衝突的依賴項

1、command+, 打開工具的設置窗口

Maven中關於jar包衝突的2種排查方案及3種解決方式

2、設置搜索中輸入plugin

Maven中關於jar包衝突的2種排查方案及3種解決方式

3、在Marketplace table頁面中搜索Maven Helper,並安裝

Maven中關於jar包衝突的2種排查方案及3種解決方式

4、重啟後即可使用,打開pom文件後,文件下面會多出Dependency Analyzer這一個tab,進入Dependency Analyzer視圖之後有三個查看選項,分別是Conflicts(衝突)、All Dependencies as List(列表形式查看所有依賴)、All Dependencies as Tree(樹結構查看所有依賴)。通過查看信息後再做出對應的依賴衝突處理。

Maven中關於jar包衝突的2種排查方案及3種解決方式

總結

關於依賴衝突解決方式有三種:最短路徑原則、聲明優先原則、依賴排除。在沒有手動進行依賴排除的情況下,會依據最短路徑原則、聲明優先原則來選擇jar包。關於依賴衝突排查可藉助如maven-enforcer-plugin 與Maven Helper 插件。根據實際情況及環境,選擇組合最優的解決方案解決依賴衝突問題。

感謝您的閱讀,如果喜歡本文歡迎關注和轉發,本頭條號將堅持原創,持續分享IT技術知識。對於文章內容有其他想法或意見建議等,歡迎提出共同討論共同進步


分享到:


相關文章: