前言
對(duì)于Jar包沖突問(wèn)題,我們開(kāi)發(fā)人員經(jīng)常都會(huì)有碰到,當(dāng)我們使用一些jar包中的類(lèi)、方法等,或者有時(shí)遇到一些日志系統(tǒng)的問(wèn)題,我們會(huì)遇到ClassNotFoundException,NoSuchFieldException,NoSuchMethodException 之類(lèi)的運(yùn)行時(shí)異常,從經(jīng)驗(yàn)上我們就會(huì)判斷,Jar包沖突了。解決Jar包沖突問(wèn)題,每個(gè)人都有每個(gè)人的方法,這里我介紹一下我的方法,供大家參考。
處理方法
當(dāng)遇到j(luò)ar包沖突時(shí),我們首先確定是哪個(gè)jar包沖突了,這個(gè)很容易,看我們調(diào)用的類(lèi)或方法,是屬于哪個(gè)Jar包。然后就是要找出沖突了,我這里使用命令 mvn dependency:tree -Dverbose -Dincludes=<groupId>:<artifactId> 填寫(xiě)上Jar包的groupId和artifactId,可以只有一個(gè),但是中間的冒號(hào)不要少,這樣就會(huì)輸出依賴樹(shù),而且是僅包含這個(gè)Jar包的依賴樹(shù),這樣那些地方依賴了這個(gè)Jar包的那個(gè)版本就一目了然了。 例如,我的項(xiàng)目中notify-common包存在沖突,我們使用命令 mvn dependency:tree -Dverbose -Dincludes=:notify-common 得到依賴樹(shù)輸出
[INFO] com.taobao.wlb:bis-server:war:1.0-SNAPSHOT
[INFO] +- com.taobao.wlb:bis-core:jar:1.0-SNAPSHOT:compile
[INFO] | \- com.taobao.logistics:schedule-client:jar:1.1.1:compile
[INFO] | \- (com.taobao.notify:notify-common:jar:1.8.15:compile - omitted for conflict with 1.8.19.26)
[INFO] \- com.taobao.notify:notify-tr-client:jar:1.8.19.26:compile
[INFO] +- com.taobao.notify:notify-common:jar:1.8.19.26:compile
[INFO] \- com.taobao.notify:notify-remoting:jar:1.8.19.26:compile
[INFO] \- (com.taobao.notify:notify-common:jar:1.8.19.26:compile - omitted for duplicate)
看一下依賴樹(shù)中所有的葉子節(jié)點(diǎn)就是所有的notify-common包,我們可以看到我們依賴的bis-core中依賴了schedule-client包,它依賴了一個(gè)notify-common包,版本是1.8.15,第四行的后面也提示了這個(gè)包同其他包有沖突 - omitted for conflict with 1.8.19.26)。而我們的系統(tǒng)依賴的notify-tr-client包所依賴的版本是1.8.19.26,于是我們知道是這里沖突了,在POM排除掉依賴,OK了。
說(shuō)明
這里我們對(duì)我們執(zhí)行的命令做一個(gè)簡(jiǎn)單的說(shuō)明。 mvn dependency:tree -Dverbose -Dincludes=<groupId>:<artifactId> 第一部分mvn dependency:tree是maven依賴的分析命令,作用是對(duì)我們的項(xiàng)目的依賴進(jìn)行分析,并輸出項(xiàng)目依賴樹(shù) 第二部分-Dverbose的作用是添加了verbose一個(gè)環(huán)境變量,起的作用是在分析項(xiàng)目依賴時(shí)輸出明細(xì),這樣項(xiàng)目中依賴的所有引用都會(huì)被輸出出來(lái),包含了所有的間接引用,會(huì)有很多很多,我們只需要我們要找的,所以就需要第三個(gè)參數(shù)了
第三部分-Dincludes=<groupId>:<artifactId>的作用就是進(jìn)行過(guò)濾,只包含我們想要的依賴的依賴時(shí),排除掉其它不需要的,依賴樹(shù)的所有葉子節(jié)點(diǎn)就是我們的找的依賴包。其中的groupId和artifactId可以只填寫(xiě)一個(gè),為了保證準(zhǔn)確性,一般都會(huì)填兩個(gè)(填寫(xiě)時(shí)不包括尖括號(hào))。
其他方法:
1、對(duì)于maven工程,我的辦法是使用eclipse來(lái)解決,點(diǎn)開(kāi)pom.xml,切換到hierarchy dependency,右上角搜索對(duì)應(yīng)的包,可以清晰地看到?jīng)_突版本
2、可以使用idea,在pom.xml中右單擊 選擇Diagrams-》show dependencies
3、mvn dependency:tree -Dverbose > tree.log 直接輸出沖突的jar文件