Maven處理依賴沖突
- 什么是依賴沖突?
- 如何解決?
- Maven自動處理依賴沖突的規則
- 路徑優先原則
- 第一聲明優先原則
- 注意
- 子模塊覆蓋父模塊
- 父模塊聲明dependency子模塊覆蓋dependency
- 父模塊聲明dependencyManagement 子模塊覆蓋dependency
- 父模塊聲明dependencyManagement 子模塊覆蓋dependencyManagement
- Maven手動處理依賴沖突
- Maven自動處理依賴后導致引入了低版本的依賴
- 解決方案
- exclusions
- optional
- 注意
- 工具
什么是依賴沖突?
當項目中直接或者間接的引入多個版本的同一依賴時則會出現依賴沖突
如何解決?
Maven自動處理依賴沖突的規則
路徑優先原則
當依賴沖突發生時,
Maven
會優先選擇路徑最短的依賴版本。路徑長度是指從當前項目到依賴的層級深度。例如:項目直接引入的a:v1
,及b:v1
,但b:v1
中引入了a:v2
。那么項目自動會引入a:v1
。因為a:v1
比b:v1->a:v2
路徑更短
實例:
package-b
引入了logback.1.5.14
,及package-a
但是,package->a
引入了logback.1.5.13
。直接maven
選擇了logback.1.5.14
符合路徑優先原則
第一聲明優先原則
如果兩個依賴的路徑長度相同,
Maven
會優先選擇在pom.xml
文件中先聲明的依賴版本。例如:項目直接引入了a:v1->b:v1
,與a:v2->b:v2
但是a:v1
是在a:v2
前先聲明的,那么就會選擇a:v2中的b:v1
反之選擇b:v2
注意
坑!!!!
直接在pom.xml
中引入兩個相同坐標但不同版本的依賴時,不會按照聲明優先原則選擇。而是使用最后聲明的依賴。
[WARNING] 'dependencies.dependency.(groupId:artifactId:type:classifier)' must be unique: ch.qos.logback:logback-core:jar -> version 1.5.14 vs 1.5.13 @ line 23, column 21
->表示同一個pom下不能聲明相同的坐標。這就導致maven直接選擇了最后聲明的依賴
子模塊覆蓋父模塊
子模塊可以通過在自己的
pom.xml
文件中直接聲明依賴的版本來覆蓋父模塊的版本。Maven 的依賴解析規則會優先考慮子模塊中直接聲明的依賴版本。
父模塊聲明dependency子模塊覆蓋dependency
父模塊聲明dependencyManagement 子模塊覆蓋dependency
父模塊聲明dependencyManagement 子模塊覆蓋dependencyManagement
Maven手動處理依賴沖突
Maven自動處理依賴后導致引入了低版本的依賴
package-g:1.0,package-g:2.0。通常我們是使用高版本的包,但是因為路徑優先原則,導致使用了低版本的依賴。這種就需要手動解決了。
解決方案
思路:通常我們高版本的依賴兼容低版本的依賴。那么我只需要依賴高版本的依賴即可。
exclusions
使用于不能修改package-h內部的場景
<dependencies><dependency><groupId>com.mfyuan</groupId><artifactId>package-j</artifactId><version>1.0-SNAPSHOT</version></dependency><dependency><groupId>com.mfyuan</groupId><artifactId>package-h</artifactId><version>1.0-SNAPSHOT</version><exclusions><exclusion><groupId>com.mfyuan</groupId><artifactId>package-g</artifactId></exclusion></exclusions></dependency></dependencies>
將低版本的依賴通過
exclusion
給排除掉即可。這樣就沒有發生依賴沖突了。
optional
optional
為true
時,不將該依賴傳遞給外層。這樣就可以避免造成依賴沖突的問題。
適用場景:可以修改package-h
內部的pom.xml
一般都為自己開發的jar包
<dependencies><dependency><groupId>com.mfyuan</groupId><artifactId>pacage-g</artifactId><version>1.0-SNAPSHOT</version><!--不將該依賴傳遞給外層--><optional>true</optional></dependency>
</dependencies>
注意
高版本如果沒有兼容低版本怎么辦?這種情況會造成
編譯失敗
,或者ClassNotFoundException
。如果你又需要高版本的功能也需要低版本的功能那么這種問題是解決不了的。
工具
idea插件:Maven Helper
可以快速查看那些依賴存在沖突