摘要:首先我們來看一下依賴沖突產(chǎn)生的原因如果項目的依賴和依賴同時引入了依賴。除非源代碼就引入了共有依賴因升級而缺失的類則會直接編譯失敗。
maven定義了許多dependency,每個dependency內(nèi)部也會定義它的dependency。
首先我們來看一下依賴沖突產(chǎn)生的原因:如果項目的依賴A和依賴B同時引入了依賴C。
如果依賴C在A和B中的版本不一致就可能依賴沖突。
比如 項目 <- A, B, A <- C(1.0),B <- C(1.1)。
那么maven如果選擇高版本C(1.1)來導(dǎo)入(這個選擇maven會根據(jù)不等路徑短路徑原則和同等路徑第一聲明原則選取),C(1.0)中的類c在C(1.1)中被修改而不存在了。
在編譯期可能并不會報錯,因為編譯的目的只是把業(yè)務(wù)源代碼編譯成class文件,所以如果項目源代碼中沒有引入共有依賴C因升級而缺失的類c,就不會出現(xiàn)編譯失敗。除非源代碼就引入了共有依賴C因升級而缺失的類c則會直接編譯失敗。
在運行期,很有可能出現(xiàn)依賴A在執(zhí)行過程中調(diào)用C(1.0)以前有但是升級到C(1.1)就缺失的類c,導(dǎo)致運行期失敗,出現(xiàn)很典型的依賴沖突時的NoClassDefFoundError錯誤。
如果是升級后出現(xiàn)原有的方法被修改而不存在的情況時,就會拋出NoSuchMethodError錯誤。
那么怎么來解決依賴沖突呢?首先可以借助Maven查看依賴的依賴樹來分析一下:mvn dependency:tree,或者使用IDEA的插件Dependency Analyzer插件來可視化地分析依賴關(guān)系。這個過程后可以明確哪些dependency引入了可能會沖突的依賴。
比如我們的項目引入A的依賴C為1.1版本,引入的B會在內(nèi)部依賴C的1.0版本,那么Dependency Analyzer插件會出現(xiàn)依賴沖突提示,會提示B引入的C的1.0版本和當前選用的C的1.1版本沖突因而被忽略(1.0 omitted for conflict with 1.1)。
如果這時候打war包出來啟動很有可能會遇到因依賴沖突而出現(xiàn)的NoClassDefFoundError或NoSuchMethodError,導(dǎo)致編譯期正常的代碼無法在運行期跑起來。
由于A引入的C的版本高而B依賴的C版本低,我們優(yōu)先會選擇兼容高版本C的方案,即試圖把B的版本調(diào)高以使得引入的依賴C可以和A引入的依賴A達到一致的版本,以此來解決依賴沖突。當然這是一個理想狀況。
如果找到了目前已有的所有的B的版本,均發(fā)現(xiàn)其依賴的C沒有與A一致的1.1版本,比如B是一個許久未升級的舊項目,那么也可以考慮把A的版本拉低以使得C的版本降到與B一致的1.0版本,當然這也可能會反過來導(dǎo)致A不能正常工作。
上面已經(jīng)可以看出來解決依賴沖突這件事情并不簡單,很難顧及兩邊,很多情況下引入不同版本依賴的很可能超過兩方而是更多方。
那么來考慮一下妥協(xié)的方案,如果A引入的C使用的功能并不跟被拋棄的類或方法有關(guān),而是其他在1.1版本中仍然沒有改變的類或方法,那么可以考慮直接使用舊的1.0版本,那么可以使用exclusion標簽來在A中排除掉對C的依賴,那么A在使用到C的功能時會使用B引入的1.0舊版本C。即A其實向B妥協(xié)使用了B依賴的C。
來看個實例:
項目引入了4.2.5.RELEASE的spring-webmvc,同時引入了3.2.1.RELEASE的spring-security-web。
用Dependency Analyzer插件分析得到的依賴關(guān)系是這樣的:
為什么maven會選擇4.2.5.RELEASE引入呢,其實前文提到過:比如對spring-beans這個依賴來說spring-webmvc:4.2.5.RELEASE-spring-beans:4.2.5.RELEASE的路徑是2,而spring-security-web:3.2.1.RELEASE-spring-security-core:3.2.1.RELEASE-spring-beans:3.2.8.RELEASE的路徑是3,因此根據(jù)不等路徑取短路徑原則則選取了前者,即spring-beans:4.2.5.RELEASE,注意的是引入時并不是優(yōu)先引入高版本的,同時如果依賴的路徑長相等則取第一個出現(xiàn)的版本。
可以看到spring-security-web引入的一眾spring依賴是3.X版本的,同spring-webmvc的4.2.5.RELEASE版本不一致。
果不其然,打好的war包啟動的時候即會報錯終止。
那么在我們的問題在于兼容高版本的spring-webmvc的4.2.5.RELEASE的情形下尋找spring依賴版本一致的spring-security-web,在www.mvnrepository.com尋找合適版本依賴的spring-security-web,最終我們看到了4.1.0.RELEASE版本似乎還不錯,其依賴的spring版本在4.2.5.RELEASE:
因此我們將這個版本的spring-security-web填入pom.xml看一下效果,確實已經(jīng)沒有依賴沖突產(chǎn)生了:
如果我們找不到完美匹配4.2.5.RELEASE的spring-security-web怎么辦,比如所有的spring-security-web版本就是在4.2.3.RELEASE或者4.2.6.RELEASE,那么我們就得想到妥協(xié)一下了:使用4.1.1.RELEASE版本的spring-security-web,它的spring依賴版本是4.3.1.RELEASE,
那么我們試圖使用exclusive標簽來忽略spring版本:
org.springframework.security spring-security-web 4.1.1.RELEASE spring-aop org.springframework spring-beans org.springframework spring-context org.springframework spring-core org.springframework spring-expression org.springframework spring-web org.springframework
依賴沖突會消失,spring-security-web會使用4.2.5.RELEASE版本的spring:
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/69453.html
摘要:添加的的依賴,可以從項目的中拷貝使用命令編譯項目。在子模塊中我們可以這樣使用引入父模塊坐標三使用建立項目新建一個項目,選擇,如圖所示在中配置插件可參見官方文檔。部署項目到即可。 一、Maven入門 1.下載maven Maven是基于項目對象模型(Project Object Model),可以通過一小段描述信息來管理項目的構(gòu)建、報告和文檔的項目管理工具,提供了一個倉庫的概念,統(tǒng)一...
摘要:但是,這種行為是危險的,所以最佳實踐應(yīng)該是顯示聲明任何項目中直接用到的依賴。生命周期和插件的生命周期生命周期清理項目。生命周期建立和發(fā)布站點,分享項目信息。 坐標和依賴 依賴沖突的調(diào)節(jié) 當包的依賴產(chǎn)生沖突,如A->B->X(1.0)和A->D-X(2.0),應(yīng)該引入X的哪一個版本?消解沖突的法則如下: 路徑最近者優(yōu)先。 如路徑長度一樣,第一聲明者優(yōu)先。 排除不想要的依賴 在引入第三...
摘要:時間年月日星期二說明本文部分內(nèi)容均來自慕課網(wǎng)。項目一個項目代表一個正在構(gòu)建的組件比如一個文件,當構(gòu)建啟動后,會基于實例化一個類,并且能夠通過變量使其隱式可用。任務(wù)動作定義了一個最小的工作單元。 時間:2017年05月16日星期二說明:本文部分內(nèi)容均來自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com教學示例源碼:無個人學習源碼:https://github.com/zccod...
摘要:在平常工作中我們經(jīng)常會遇到引用的包沖突的事情,這時候我們就需要找出沖突的包,并將低版本或者缺少某些方法的給剔除掉。要選擇沖突項的話可以直接點擊,然后在點擊,顯示的會更清楚一些,因為包比較多,依賴比較復(fù)雜會讓圖變得很小。 ????在平常工作中我們經(jīng)常會遇到maven引用的jar包沖突的事情,這時候我們就需要找出沖突的包,并將低版本或者缺少某些方法的jar給剔除掉。這個時候使用idea自帶...
閱讀 2022·2021-10-25 09:48
閱讀 2893·2021-09-22 14:59
閱讀 1819·2019-08-29 16:52
閱讀 933·2019-08-29 16:07
閱讀 2380·2019-08-29 12:38
閱讀 1847·2019-08-26 13:23
閱讀 937·2019-08-26 11:49
閱讀 3350·2019-08-26 10:56