麻了蛆楞! 被 jar 包沖突坑哭了!

麻了! 被 jar 包沖突坑哭了!

一杯茶一包煙夹厌,一行代碼寫一天

聽說這個是編程大佬的行為準則豹爹。而我沒有茶沒有煙,但是一行代碼寫了一天矛纹,(算起來可能不止一天)臂聋。

大家好,我是janker或南。今天來聊下關(guān)于jar包沖突的事兒孩等。

Part 1

最近接了一個產(chǎn)品需求:

永哥,最近業(yè)務(wù)方提出了一個訴求采够,就是讓我們把某某功能開放給他們肄方,入口參數(shù)就只需要添加一個字段,我都調(diào)研過了蹬癌,我們系統(tǒng)都是支持的权她。

一看到這樣的話術(shù),作為接過很多一句話產(chǎn)品需求的爬坑程序員逝薪,我建議你們不要亂答應(yīng)隅要。因為很有可能加一個字段,你加了一天董济,并且看不到產(chǎn)出步清。但是耳根子很軟的永哥忍不住接了。  

一般這種需求感局,都是要升級jar包的尼啡,加字段三板斧暂衡,改依賴版本、加字段崖瞭、發(fā)布狂巢。帶上測試環(huán)境部署的時間,目測15分鐘就差不多了书聚,自測一下唧领,20分鐘怎么也夠了。自信如我雌续,如風隨性斩个。

`but` 奈何部署了`20`分鐘,容器重啟了好幾次一直不成功驯杜,熟悉的味道受啥,記得上次出現(xiàn)這個情況還是在上次,問題不大鸽心,看下錯誤日志滚局,沒有日志、只有一個簡單的`Main`函數(shù)日志顽频,然后就沒然后了藤肢。

一般出現(xiàn)這種情況的,多半是lib包依賴的時候糯景,有沖突嘁圈。為了驗證我的猜想,我部署了一下mastar分支蟀淮,竟然也啟動不起來最住,what ?是誰動了我的 jar 包怠惶,一邊逼逼賴賴温学,一邊繼續(xù)修bug。思來想去甚疟,只有一種可能,會影響到master分支的部署逃延,那就是我們引用了快照包览妖,因為快照包在我們上線 master 的時候可能是好的,但是我們在發(fā)布到測試環(huán)境的時候快照包做了更改揽祥,導致啟動不了讽膏。到了這里只有一招可以用了,就是對比打包lib文件夾下的jar包拄丰,多出來的就是罪魁禍首府树。最終俐末,搞了個jar包對比腳本,發(fā)現(xiàn)新的包里多出來了 xxx.jar奄侠,我們只知道多了 xxx.jar 怎么知道是哪個依賴引起的卓箫,辦法有兩種:1. 反解jar包,找到MANIFEST.MF 里面有相應(yīng)的包信息垄潮,然后結(jié)合 class 很容易就知道哪個依賴包影響的 2. 根據(jù)jar包名烹卒,見名知意猜測一下(針對常見的jar包完全是ok的)。找出相應(yīng)的依賴弯洗,排掉就好了旅急。我以為快快樂樂的啟動就好了呐舔,沒想到容器啟動了辐啄,但是沒有日志掸刊。只是沒日志宵统,又不是不能用干旧。

短暫總結(jié)下前面的脈絡(luò):

Part 2

既然沒有日志蹦锋,咱們就看看jar包列表對比中宋距,差異部分有沒有跟log包相關(guān)的jar裆装,果不其然秋泳,在新的jar包列表中多了 logback-classic 這個jar潦闲,見名知意順手我就把 logback-classic 這個包給排掉了,這下子日志大概好像能顯示了吧迫皱。

run 啟動直接連日志都木得了歉闰,不過我絲毫不慌,從啟動腳本中copy出啟動命令卓起,登錄上機器 jar -server 啟動一下和敬,我到底看下是什么要么鬼怪。java.lang.ClassNotFoundException戏阅,ch/qos/logback/classic/Level 這不是我剛排查的包里的類嗎昼弟?我陷入了兩難,不排除的話沒日志奕筐、排除了的話啟動不起來舱痘。我還在慌亂中,師兄也沒解決我的問題离赫,緩緩心情給它過個周末吧芭逝,明天再整他,萬一他自己好了呢(雖然知道他一定不會好)渊胸。

截止到發(fā)文前旬盯,我終于解決了,本質(zhì)原因是使用的腳手架封裝了logback(基于logback包二次開發(fā)),引入logback 兩者天然是水火不容胖翰,既然原生logback包刪除不了接剩,打不過就加入(KD語錄),直接把log包直接替換掉萨咳,加上logback配置(logback.xml)懊缺,完美解決。

What?

在實際開發(fā)過程中某弦,我們往往會引入一些其他服務(wù)的 API 包桐汤,調(diào)用API 包中的 RPC 服務(wù)來達到調(diào)用別人服務(wù)的目的。在我們的想入引入別人的 jar 包時靶壮,總是會遇到基礎(chǔ)能力總是會遇到相關(guān)基礎(chǔ)能力jar包的版本沖突怔毛,又或者權(quán)限定類名沖突,在對方?jīng)]有自定義類加載器的時候腾降,我們是需要解決這些沖突問題的拣度,不然再項目運行時就會發(fā)生找不到類或者找不到具體的方法。常見的異常有兩種:

  1. java.lang.NoSuchMethodError螃壤;
  2. java.lang.ClassNotFoundException抗果;

Why?

沖突的來源源于類加載器沒有加載到合適的類奸晴,類丟了冤馏,或者方法丟了。

舉個例子:

比如我們使用的User對象寄啼,a逮光、b包的依賴我們都引入了,在默認的類加載器加載的時候墩划,因為我們是按照權(quán)限定名來做唯一標識的涕刚,如果我們在程序中使用的是a中的User.class ,但是加載的時候加載的是b中的User.class乙帮,當我們程序中使用的方法在B中沒有時杜漠,就會出現(xiàn)java.lang.NoSuchMethodError

還有一種情況:

我們引入jar包的時候一般都是靠groupIdartifactId確定一個依賴包察净,如下圖驾茴,a 和 b 的 groupIdartifactId 都一致,只是版本不同氢卡,一般情況下Maven打包的時候就會把高版本的給打進去沟涨,如果a為高版本,但是程序中引用了 b 中的User.class 運行時就會出現(xiàn) java.lang.ClassNotFoundException 异吻。

How?

我們已經(jīng)知道 jar 包沖突是什么?并且知道是什么引起 jar 包沖突了诀浪,接下來我們看一下如何去解決 jar 包沖突棋返。

確定沖突依賴包

啟動時我們已經(jīng)看到,java.lang.ClassNotFoundException雷猪,ch/qos/logback/classic/Level 這樣的異常信息睛竣,在IDEA 中搜索到這個類,并且定位到依賴包求摇。

<img src="https://upload-images.jianshu.io/upload_images/957716-eac071e901f4e292.png" style="zoom: 50%;" />

首先確定依賴包射沟,然后確定pom信息,pom中包含 groupId 和 artifactId 和version信息与境。有了這些信息验夯,我們就可以找到具體都那些pom依賴,把那些新進并且沒有用的依賴排除掉摔刁。

找到有問題的依賴

如果依賴較少挥转,直接把依賴樹打出來,然后根據(jù)樹形關(guān)系共屈,排掉沖突的依賴即可绑谣。

  1. 分析當前pom依賴樹 mvn dependency:tree
  2. 人肉搜索,確定沖突

當然依賴樹也是有篩選功能的拗引,并且可以直接展示沖突信息借宵。

mvn dependency:tree > dependency_tree.txt -Dverbose -Dincludes={groupId}:{artifactId }

這個就比較厲害了,直接根據(jù) groupIdartifactId 篩選出相關(guān)的 dependency 并在下方直接 exclusion 即可矾削,排除示例:

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>${hutool.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.projectlombok</groupId>
                    <artifactId>lombok</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

格式類似于這樣的壤玫。

總結(jié)

jar 包沖突在開發(fā)過程中是不可避免的,為了不挨罵(給小伙伴埋坑)怔软,我這里有幾個建議垦细。

  1. api 包定義盡量簡單純粹。(盡量不要包含一些跟api定義本身無關(guān)的包挡逼,例如:spring全家桶括改、log全家桶等)。
  2. 經(jīng)臣铱玻看下依賴樹是否存在大量的依賴沖突嘱能,并修正。(可以安裝meven helper插件便于查看依賴沖突)
  3. 日常開發(fā)使用快照包版本虱疏,上線發(fā)布前必須改為release版本(避免快照版本變更造成線上啟動問題惹骂、線上事故等)。

忙時做業(yè)績做瞪,閑時修內(nèi)功对粪。我是janker右冻。咱們下期見。

本文由mdnice多平臺發(fā)布

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末著拭,一起剝皮案震驚了整個濱河市纱扭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌儡遮,老刑警劉巖乳蛾,帶你破解...
    沈念sama閱讀 221,635評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異鄙币,居然都是意外死亡肃叶,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評論 3 399
  • 文/潘曉璐 我一進店門十嘿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來因惭,“玉大人,你說我怎么就攤上這事详幽∩富叮” “怎么了?”我有些...
    開封第一講書人閱讀 168,083評論 0 360
  • 文/不壞的土叔 我叫張陵唇聘,是天一觀的道長版姑。 經(jīng)常有香客問我,道長迟郎,這世上最難降的妖魔是什么剥险? 我笑而不...
    開封第一講書人閱讀 59,640評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮宪肖,結(jié)果婚禮上表制,老公的妹妹穿的比我還像新娘。我一直安慰自己控乾,他們只是感情好么介,可當我...
    茶點故事閱讀 68,640評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蜕衡,像睡著了一般壤短。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上慨仿,一...
    開封第一講書人閱讀 52,262評論 1 308
  • 那天久脯,我揣著相機與錄音,去河邊找鬼镰吆。 笑死帘撰,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的万皿。 我是一名探鬼主播摧找,決...
    沈念sama閱讀 40,833評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼核行,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蹬耘?” 一聲冷哼從身側(cè)響起钮科,我...
    開封第一講書人閱讀 39,736評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎婆赠,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體佳励,經(jīng)...
    沈念sama閱讀 46,280評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡休里,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,369評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了赃承。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片妙黍。...
    茶點故事閱讀 40,503評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖瞧剖,靈堂內(nèi)的尸體忽然破棺而出拭嫁,到底是詐尸還是另有隱情,我是刑警寧澤抓于,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布做粤,位于F島的核電站,受9級特大地震影響捉撮,放射性物質(zhì)發(fā)生泄漏怕品。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,870評論 3 333
  • 文/蒙蒙 一巾遭、第九天 我趴在偏房一處隱蔽的房頂上張望肉康。 院中可真熱鬧,春花似錦灼舍、人聲如沸吼和。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽炫乓。三九已至,卻和暖如春砂豌,著一層夾襖步出監(jiān)牢的瞬間厢岂,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評論 1 272
  • 我被黑心中介騙來泰國打工阳距, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留塔粒,地道東北人。 一個月前我還...
    沈念sama閱讀 48,909評論 3 376
  • 正文 我出身青樓筐摘,卻偏偏與公主長得像卒茬,于是被迫代替她去往敵國和親船老。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,512評論 2 359

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

  • Jar包沖突是老生常談的問題圃酵,幾乎每一個Java程序猿都不可避免地遇到過柳畔,并且也都能想到通常的原因一般是同一個Ja...
    sherlockyb閱讀 37,359評論 1 65
  • 情景一: A-pom繼承B-pom,B-pom依賴xx郭赐。A-pom想覆蓋xx的版本號薪韩,直接在A-pom中重新引入x...
    心淡然如水閱讀 1,612評論 0 0
  • 一、前言 早前捌锭,筆者在碰到ClassNotFoundException的異常也是一臉懵逼俘陷,但是這個類確實存在于我們...
    GeekerLou閱讀 3,049評論 0 2
  • 接手了一套比較有年代感的系統(tǒng),計劃把重構(gòu)及遇到的問題寫成系列文章观谦,老樹發(fā)新枝拉盾,重溫一些實戰(zhàn)技術(shù),分享給大家豁状∽狡【重構(gòu)...
    十萬嬉皮_c728閱讀 227評論 0 0
  • Jar包沖突的本質(zhì)是什么?Java應(yīng)用程序因某種因素泻红,加載不到正確的類而導致其行為跟預期不一致夭禽。 具體來說可分為兩...
    tracy_668閱讀 722評論 0 4