為什么會產生jar包沖突,如何排查jar包沖突?
Jar包沖突產生的原因
我們知道maven有傳遞性依賴機制,舉例來說,當我們需要A的依賴的時候,就會在pom.xml中引入A的jar包;而A的jar包中依賴了B的jar包,這樣Maven在解析pom.xml的時候,會依次將A、B 的jar包全部都引入進來。
這樣就會造成一個問題:
- 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插件是一個簡便的排查方法
- 下載Maven Helper
- 打開pom.xml
- 點擊Dependency Analyzer 窗口一目了然

通過Maven命名行的方式也是也不錯的選擇:
- 通過 mvn dependency:tree 可以在控制台上打印出依賴
- 通過 mvn dependency:tree -Dverbose -Dincludes=groupId:artifactId 只打印出你關心的Jar包的依賴關系
- 通過
標簽手動排除依賴
例如:
<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這個包排除掉。
當然也有一些其他方法,對我來說第一種已經滿足日常使用了。
避免Jar包沖突
最重要的還是要主動避免jar包沖突的情況,在父pom文件中利用
例如在父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包
