本文涉及到以下幾個概念須要注意:依賴衝突、依賴調解、依賴傳遞。html
原來運行得好好的代碼,在引入一個 Jar 包後出現 NoSuchMethodException、NoClassDefFoundError 等錯誤提示,那麼恭喜你,大機率遇到了依賴衝突
。apache
在認識依賴衝突以前,咱們先來了解一下 Maven 的依賴調解
。maven
參考 Maven依賴衝突問題原理簡析 。ide
簡單的說,若是一個項目中引入了同一個依賴(jar 包)的兩個(或多個)不一樣版本,Maven 會對這些依賴作調解,以確保最終(運行時)在項目中對於同一個依賴只引入一個版本。ui
依賴調解的兩個原則:spa
如今咱們已經知道了,在一個項目中是可能引入同一個依賴(jar 包)的不一樣版本的。 那麼,在同一個 jar 包的不一樣版本中可能存在一些差別,好比:.net
舉個例子,咱們項目中引入了兩個版本(1.0、2.0)的依賴 A,通過依賴調解後使用了較高的版本(2.0)。若是該依賴在升級的時候沒有保持向下的兼容性,刪掉了某些方法,而咱們項目中使用 1.0 版本的地方恰好調用了被刪掉的這個方法,就會出現 NoSuchMethodException 異常。插件
不必定。若是通過依賴調解後最終使用的版本可以兼容全部的使用,程序就能夠正常運行。命令行
根本緣由是經過直接或者間接依賴,在代碼中引入了同一個依賴的不一樣版本。code
在 IDE 中使用 Maven Enforcer Plugin
插件。 這個插件有不少規則,咱們最關心的是 Dependency Convergence
規則。 用法:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.4.1</version>
<configuration>
<rules><dependencyConvergence/></rules>
</configuration>
</plugin>
</plugins>
複製代碼
參考官網介紹,該插件有兩個執行目標:
執行方式:
mvn enforcer:enforce
執行結果:
Dependency convergence error for log4j:log4j:1.2.17 paths to dependency are:
+-com.ricston.conflict:conflict-info:2.1.3-SNAPSHOT
+-org.slf4j:slf4j-log4j12:1.7.6
+-log4j:log4j:1.2.17
and
+-com.ricston.conflict:conflict-info:2.1.3-SNAPSHOT
+-log4j:log4j:1.2.16
複製代碼
根據這種方式發現依賴衝突後,咱們就可使用上面提到的兩種方式(排除或者引入可用的直接依賴)來解決衝突。