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