爲何會產生jar包衝突,如何排查jar包衝突?

爲何會產生jar包衝突,如何排查jar包衝突?

[TOC]maven

Jar包衝突產生的緣由

咱們知道maven有傳遞性依賴機制,舉例來講,當咱們須要A的依賴的時候,就會在pom.xml中引入A的jar包;而A的jar包中依賴了B的jar包,這樣Maven在解析pom.xml的時候,會依次將A、B 的jar包所有都引入進來。google

這樣就會形成一個問題:spa

  • A->B->C->G21(guava 21.0)
  • E->F->G20(guava 20.0) 假設pom.xml 文件中引入A與E兩個依賴,按照上述的傳遞性依賴機制,與默認的依賴調解機制(第一:路徑最近者優先;第二:第一聲明優先),默認引用的是G20版本的jar包,G21的jar包不會被引用。

若是C的methodC使用了新版本G21才擁有的新類/新方法,程序中調用了C對應G21的新類/新方法時,由於項目中引用的是G20,因此JVM去加載Class時就會發現G20沒有這個類,就會拋出ClassNotFoundException;一樣,調用G20沒有的新方法時會拋出NoSuchMethodError。插件

排查jar包衝突

通常來講,使用IDEA插件是一個簡便的排查方法code

  1. 下載Maven Helper
  2. 打開pom.xml
  3. 點擊Dependency Analyzer 窗口一目瞭然

image

經過Maven命名行的方式也是也不錯的選擇:xml

  1. 經過 mvn dependency:tree 能夠在控制檯上打印出依賴
  2. 經過 mvn dependency:tree -Dverbose -Dincludes=groupId:artifactId 只打印出你關心的Jar包的依賴關係
  3. 經過<exclusions>標籤手動排除依賴

例如:blog

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <exclusions>
        <exclusion>
            <artifactId>error_prone_annotations</artifactId>
            <groupId>com.google.errorprone</groupId>
        </exclusion>
    </exclusions>
</dependency>

在引用guava時將com.google.errorprone這個包排除掉。ci

固然也有一些其餘方法,對我來講第一種已經知足平常使用了。io

避免Jar包衝突

最重要的仍是要主動避免jar包衝突的狀況,在父pom文件中利用 <dependencyManagement>,對依賴Jar包進行統一版本管理,一勞永逸。一般的作法是,在parent模塊的pom文件中儘量地聲明全部相關依賴Jar包的版本,並在子pom中簡單引用該構件便可。class

例如在父pom文件中定義lombok的版本:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
        </dependency>
    </dependencies>
</dependencyManagement>

而後在子moudle中:

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
</dependencies>

子moudle中自動會引用版本爲1.18.10的lombok Jar包

相關文章
相關標籤/搜索