Maven依賴衝突,何解?

本文涉及到以下幾個概念須要注意:依賴衝突、依賴調解、依賴傳遞。html

依賴衝突是什麼

原來運行得好好的代碼,在引入一個 Jar 包後出現 NoSuchMethodException、NoClassDefFoundError 等錯誤提示,那麼恭喜你,大機率遇到了依賴衝突apache

在認識依賴衝突以前,咱們先來了解一下 Maven 的依賴調解maven

依賴調解

參考 Maven依賴衝突問題原理簡析ide

簡單的說,若是一個項目中引入了同一個依賴(jar 包)的兩個(或多個)不一樣版本,Maven 會對這些依賴作調解,以確保最終(運行時)在項目中對於同一個依賴只引入一個版本。ui

依賴調解的兩個原則:spa

  1. 路徑最近者優先
  2. 第一聲明者優先

依賴衝突

如今咱們已經知道了,在一個項目中是可能引入同一個依賴(jar 包)的不一樣版本的。 那麼,在同一個 jar 包的不一樣版本中可能存在一些差別,好比:.net

  1. 類數量變化,表現形式爲類的增長/減小
  2. 類結構變化,表現形式爲方法/字段的增長/減小
  3. ......

舉個例子,咱們項目中引入了兩個版本(1.0、2.0)的依賴 A,通過依賴調解後使用了較高的版本(2.0)。若是該依賴在升級的時候沒有保持向下的兼容性,刪掉了某些方法,而咱們項目中使用 1.0 版本的地方恰好調用了被刪掉的這個方法,就會出現 NoSuchMethodException 異常。插件

存在依賴衝突必定意味着異常嗎?

不必定。若是通過依賴調解後最終使用的版本可以兼容全部的使用,程序就能夠正常運行。命令行

爲何會產生依賴衝突

根本緣由是經過直接或者間接依賴,在代碼中引入了同一個依賴的不一樣版本。code

怎麼解決依賴衝突

  1. 若是能確認高版本向下兼容,那麼引入一個高版本 jar 包做爲項目的直接依賴(利用路徑最近者優先原則)
  2. 用 標籤排除掉不須要的依賴。

怎樣更快地發現依賴衝突?

在 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>
複製代碼

參考官網介紹,該插件有兩個執行目標:

  1. enforcer:enforce 用於規則檢查
  2. enforcer:display-info 用於顯示基本環境信息

執行方式:

  1. 命令行執行 mvn enforcer:enforce
  2. 將該目標綁定到 Maven 的生命週期上自動執行

執行結果:

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
複製代碼

根據這種方式發現依賴衝突後,咱們就可使用上面提到的兩種方式(排除或者引入可用的直接依賴)來解決衝突。

參考

相關文章
相關標籤/搜索