好機會,我要幫女同事解決Maven沖突問題

任何一個故事起因最重要

任何一個職業(yè)昌执,女生都有絕對的優(yōu)勢烛亦。更別提IT行業(yè)了,在部門中要是有女程序猿那肯定是香餑餑懂拾,備受呵護呀煤禽。

之前有一次,一位剛來的妹子遇到問題了岖赋,畫風(fēng)頓時就變成上面的圖片了檬果,群起而圍之,但是最后的結(jié)果并不理想唐断,還是得我出馬(此處有點小吹牛)选脊。

妹子遇到的是Jar包沖突的問題,錯誤信息是 Caused by: java.lang.ClassNotFoundException脸甘,看錯誤要么就是缺少某個Jar包恳啥,要么就是沖突了。

其實在工作中經(jīng)常會遇到這種沖突的問題丹诀,比如:Caused by:java.lang.NoSuchMethodError 這個異常信息也是沖突導(dǎo)致的钝的,想要解決沖突問題就必須得知道哪里沖突了(好像是廢話)。

大部分都是用Maven來管理依賴的Jar忿墅,今天這篇文章主要是講解如何解決Maven帶來的依賴沖突問題扁藕。

Maven回顧

Maven自述

Maven 是用于構(gòu)建和管理Java項目的工具沮峡。對于Java方向的來說疚脐,Maven幾乎都要接觸和使用。當(dāng)然也有其他的工具來代替Maven邢疙,比如Ant和Gradle棍弄。

之前有接觸過Grails構(gòu)建的Java Web項目,就是用Gradle來做依賴管理的疟游。至于Ant也在剛工作的時候在一些老項目中有見到過呼畸,后面幾乎沒見過了。

Maven文檔地址:https://maven.apache.org

使用Maven可以讓我們快速構(gòu)建一個新的項目颁虐,并且很方便的可以集成和管理多個三方的框架蛮原。當(dāng)我們需要某個框架時可以去搜索一下這個框架的信息,然后配置到你的項目中即可另绩。

搜索地址:https://mvnrepository.com

比如我們想要使用Spring Boot儒陨,除了在Spring的文檔中獲取依賴的版本花嘶,也可以自己去搜索,選擇對應(yīng)的版本蹦漠,如下圖:

可以看到默認(rèn)就是Maven的依賴方式椭员,只需要將dependency整段內(nèi)容復(fù)制到項目的pom.xml文件中即可。右側(cè)還有很多其他的依賴方式笛园,比如Gradle等隘击。

Maven依賴傳遞

今天主要講下如何去解決Maven做依賴管理的時候Jar包沖突的問題,在解決之前先來了解下基本的知識研铆。

上圖展示了Maven的依賴傳遞性埋同,首先是項目B中依賴了Spring和Guava兩個框架。然后項目A又依賴了項目B棵红,所以項目A也會依賴Spring和Guava兩個框架莺禁。

依賴傳遞Jar包選擇邏輯

依賴性傳遞會導(dǎo)致項目中依賴很多其他版本的Jar,這種情況下怎么進行Jar包的選擇呢窄赋?

有兩個規(guī)則:

  • 不同距離哟冬,距離近優(yōu)先
  • 相同距離,前者優(yōu)先

如下圖所示忆绰,項目依賴了項目A和項目B浩峡,A和B分別依賴了Guava,但是從依賴層次來看错敢,項目B的層次更淺翰灾,故Guava18.0會被優(yōu)先選擇。

當(dāng)距離相同的時候稚茅,就會優(yōu)先選擇定義在前面的纸淮,如下圖所示,項目A和項目B都分別依賴了Guava15.0和Guava18.0的版本亚享,但是項目A的順序在項目B的前面咽块,所以會優(yōu)先選擇Guava15.0版本。

通過依賴傳遞性經(jīng)常會導(dǎo)致Jar包沖突的問題欺税,比如下圖的項目A本身依賴了Guava15.0侈沪,然后又依賴了項目B,項目B中依賴了Guava18.0晚凿,這樣項目A就會同時依賴Guava15.0和Guava18.0亭罪。

如果剛好用到了高版本不兼容低版本的方法和類時,就會出現(xiàn)選擇錯誤歼秽,因為Maven會根據(jù)依賴樹的深淺來選型淺的依賴应役,也就是15.0。

沖突案例

下面就是一個典型的Jar包沖突問題,當(dāng)一個Jar有多個版本的時候箩祥,就會出現(xiàn)沖突呻惕。

錯誤信息可以看到com.google.common.collect.FluentIterable.concat這個方法找不到,目前是從guava-18.0.jar中加載的滥比,這種問題我們改怎么解決呢亚脆?

Description:
An attempt was made to call the method com.google.common.collect.FluentIterable.concat(Ljava/lang/Iterable;Ljava/lang/Iterable;)Lcom/google/common/collect/FluentIterable; but it does not exist. Its class, com.google.common.collect.FluentIterable, is available from the following locations:
    jar:file:/Users/yinjihuan/.m2/repository/com/google/guava/guava/18.0/guava-18.0.jar!/com/google/common/collect/FluentIterable.class
It was loaded from the following location:
    file:/Users/yinjihuan/.m2/repository/com/google/guava/guava/18.0/guava-18.0.jar

Action:
Correct the classpath of your application so that it contains a single, compatible version of com.google.common.collect.FluentIterable

解決思路之懸絲診脈

找出沖突的Jar,看看當(dāng)前項目中依賴了哪幾個版本

Eclipse

在Eclipse中可以雙擊pom文件盲泛,進入Dependency視圖濒持,輸入你要搜索的jar名稱進行搜索,就可以看出當(dāng)前項目中哪些框架依賴了你搜索的jar寺滚,什么版本都能知道柑营。

Idea

Idea中可以安裝maven helper插件來查看相關(guān)依賴信息,默認(rèn)選中Conflicts會展示當(dāng)前項目存在沖突的依賴村视,當(dāng)然我們也可以直接查看樹形的依賴關(guān)系去分析沖突官套。

Maven命令

不用不借助于開發(fā)工具的插件,我們可以直接用Maven命令來查看當(dāng)前項目的依賴關(guān)系蚁孔,命令行進入到你要分析的項目目錄下奶赔,執(zhí)行下面的命令將分析結(jié)果保存到文件中:

mvn dependency:tree > tree.log

執(zhí)行完之后依賴的信息結(jié)構(gòu)如下:

搜索了下guava,發(fā)現(xiàn)在smjdbctemplate中依賴了18.0版本杠氢,這個框架是我自己基于jdbctemplate封裝的一個框架站刑。

解決思路之察言觀色

其實很明顯,錯誤信息已經(jīng)告訴我們18.0中找不到concat方法鼻百,所以18.0肯定是不能用的绞旅,通過前面的分析,找到了直接依賴guava.18.0.jar的是smjdbctemplate温艇,解決辦法就是將smjdbctemplate中的guava排除掉因悲。

<dependency>
    <groupId>com.github.yinjihuan</groupId>
    <artifactId>smjdbctemplate</artifactId>
    <version>1.1</version>
    <exclusions>
        <exclusion>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
        </exclusion>
    </exclusions>
</dependency>

還有就是根據(jù)依賴樹的深淺度來判斷當(dāng)前項目依賴的是哪個版本,如下圖:

18.0是最淺的勺爱,肯定是依賴它晃琳,其實在Eclipse里面直接查看Maven Dependencies就可以指定當(dāng)前項目依賴哪些框架和版本信息,如下圖:

當(dāng)我們排除掉18.0后再來看依賴的版本是20.0邻寿,如下圖:

根據(jù)依賴樹的深淺度蝎土,20.0和19.0都是一樣的層級视哑,但是20.0在19.0前面绣否,所以優(yōu)先選擇20.0版本。

再來看項目中的pom文件挡毅,發(fā)現(xiàn)swagger的聲明順序在apollo的前面蒜撮。

如果我們把順序調(diào)整一下,那么就會依賴19.0的版本。

總結(jié)

通過我仔細(xì)耐心的講解段磨,妹子終于自己解決了遇到的問題取逾,后面的事你們就猜去吧。??

這種問題其實無法避免苹支,當(dāng)你依賴的三方框架越多的時候砾隅,沖突的可能性就越大。碰到問題的時候沉下心來仔細(xì)分析债蜜,借助于工具幫助你排查問題晴埂。

當(dāng)然我們在自己項目中去依賴三方的框架,也是要注意版本的問題寻定,特別是對于多模塊的項目,每個子模塊都去依賴不同的版本,這樣很容易出問題沼瘫,一般建議在父pom中dependencyManagement來統(tǒng)一管理版本酝蜒,子模塊直接統(tǒng)一使用父pom中定義好的版本。

還有就是可以使用optional來設(shè)置可選依賴向胡,比如說你要封裝一個通用的模塊Common恼蓬,這個模塊中有很多通用的功能,項目A依賴只需要使用功能A僵芹,項目B依賴只需要使用功能B滚秩。每個功能都依賴了三方的Jar,這個時候如果你不做任何處理淮捆,只要依賴了你這個通用的模塊Common郁油,那么也就會間接依賴這兩個功能的第三方Jar。這個時候可以通過設(shè)置optional=true來解決這個問題攀痊,我依賴了你的通用模塊Common桐腌,如果我要使用A功能,那么我必須顯示依賴A功能需要的三方依賴才可以苟径。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末案站,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子棘街,更是在濱河造成了極大的恐慌蟆盐,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,843評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件遭殉,死亡現(xiàn)場離奇詭異石挂,居然都是意外死亡,警方通過查閱死者的電腦和手機险污,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評論 3 392
  • 文/潘曉璐 我一進店門痹愚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來富岳,“玉大人,你說我怎么就攤上這事拯腮〗咽剑” “怎么了?”我有些...
    開封第一講書人閱讀 163,187評論 0 353
  • 文/不壞的土叔 我叫張陵动壤,是天一觀的道長萝喘。 經(jīng)常有香客問我,道長琼懊,這世上最難降的妖魔是什么蜒灰? 我笑而不...
    開封第一講書人閱讀 58,264評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮肩碟,結(jié)果婚禮上强窖,老公的妹妹穿的比我還像新娘。我一直安慰自己削祈,他們只是感情好翅溺,可當(dāng)我...
    茶點故事閱讀 67,289評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著髓抑,像睡著了一般咙崎。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上吨拍,一...
    開封第一講書人閱讀 51,231評論 1 299
  • 那天褪猛,我揣著相機與錄音,去河邊找鬼羹饰。 笑死伊滋,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的队秩。 我是一名探鬼主播笑旺,決...
    沈念sama閱讀 40,116評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼馍资!你這毒婦竟也來了筒主?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,945評論 0 275
  • 序言:老撾萬榮一對情侶失蹤鸟蟹,失蹤者是張志新(化名)和其女友劉穎乌妙,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體建钥,經(jīng)...
    沈念sama閱讀 45,367評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡藤韵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,581評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了锦针。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片荠察。...
    茶點故事閱讀 39,754評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡置蜀,死狀恐怖奈搜,靈堂內(nèi)的尸體忽然破棺而出悉盆,到底是詐尸還是另有隱情,我是刑警寧澤馋吗,帶...
    沈念sama閱讀 35,458評論 5 344
  • 正文 年R本政府宣布焕盟,位于F島的核電站,受9級特大地震影響宏粤,放射性物質(zhì)發(fā)生泄漏脚翘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,068評論 3 327
  • 文/蒙蒙 一绍哎、第九天 我趴在偏房一處隱蔽的房頂上張望来农。 院中可真熱鬧,春花似錦崇堰、人聲如沸沃于。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,692評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽繁莹。三九已至,卻和暖如春特幔,著一層夾襖步出監(jiān)牢的瞬間咨演,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,842評論 1 269
  • 我被黑心中介騙來泰國打工蚯斯, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留薄风,地道東北人。 一個月前我還...
    沈念sama閱讀 47,797評論 2 369
  • 正文 我出身青樓拍嵌,卻偏偏與公主長得像村刨,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子撰茎,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,654評論 2 354

推薦閱讀更多精彩內(nèi)容