Maven依賴沖突問題排查經(jīng)驗

一、背景

在日常的開發(fā)中为狸,排查問題是一個合格Java開發(fā)者的的基本能力歼郭。對于常見的NullPointerException,NoClassDefFoundError等問題一般通過google直接就能找到答案辐棒。

不過還有一些異常情況不是那么直觀病曾,google一般搜不到有效的信息,就需要深入研究排查漾根。新人遇到這類問題泰涂,往往一臉懵逼,不知如何下手辐怕,請教高手逼蒙,高手如果只是簡單指導(dǎo)一個方向,新人踩過幾個坑沒解決后會更加沮喪寄疏。甚至懷疑自己遇到一個神秘的無法解決的bug是牢。有經(jīng)驗的開發(fā)往往也不能一眼就看出問題的修復(fù)方案,但是排查問題多了會有大概的思路陕截,需要沉下心來不斷的踩坑驳棱、爬坑,最終才能定位解決問題农曲。

本文以Maven構(gòu)建工具為例社搅,從原理、思路朋蔫、工具罚渐、實踐幾方面分享Java中復(fù)雜jar包依賴問題排查經(jīng)驗。

二驯妄、Maven依賴問題的表現(xiàn)形式

1荷并、老項目

  • 一般是新引入了一個jar包,導(dǎo)致項目啟動不起來

  • 原來的服務(wù)好好的青扔,新的改動不涉及這塊源织,但是新改動代碼后突然報錯了

2、新項目

  • 日志問題:眾所周知微猖,jar生態(tài)的日志包及其混亂谈息,同一套日志組件,不同版本之間也可能會帶來問題

  • 組件整合問題:各組件底層依賴jar包版本不一致凛剥,導(dǎo)致問題侠仇。最麻煩的是不兼容的依賴。

三、問題排查策略

1逻炊、基礎(chǔ)知識:Maven依賴傳遞策略

compile (編譯范圍):默認(rèn)策略互亮;編譯,測試余素,運(yùn)行豹休,打包都能用

provided (已提供范圍):編譯,測試可用桨吊,不會打包到package包中威根。大部分情況下需要底層環(huán)境提供,比如tomcat服務(wù)中已經(jīng)內(nèi)置了servlet包视乐,代碼寫代碼時需要調(diào)用servlet的類

runtime (運(yùn)行時范圍):只有運(yùn)行時才可用洛搀,但在編譯的時候不需要。比如炊林,你可能在編譯的時候只需要JDBC API JAR姥卢,而只有在運(yùn)行的時候才需要JDBC驅(qū)動實現(xiàn)卷要。

test (測試范圍):test范圍依賴在編譯和運(yùn)行時都不需要渣聚,它們只有在測試編譯和測試運(yùn)行階段可用。

system (系統(tǒng)范圍):system范圍依賴與provided 類似僧叉,但是你必須顯式的提供一個對于本地系統(tǒng)中JAR 文件的路徑奕枝。適合maven中央倉庫中不存在jar包引用。

2瓶堕、基礎(chǔ)知識:Maven依賴樹的解析規(guī)則

(1)深入優(yōu)先原則

深度優(yōu)先遍歷依賴隘道,并緩存節(jié)點剪枝。比如下圖:

  • A→B→D→E/F

  • A→C→D

在第二步A→C→D時郎笆,由于節(jié)點D已經(jīng)被緩存谭梗,所以會立即返回,不必再次遍歷E/F宛蚓,避免重復(fù)搜索激捏。

image
(2)短路徑優(yōu)先原則

比如下圖 A 通過 B 和 D 引入了 1.0 版本的 E,同時 A 通過 C 引入了 2.0 版本的 E凄吏。針對這種多個版本構(gòu)建依賴時远舅,Maven 采用短路徑優(yōu)先原則,即 A 會依賴 2.0 版本的 E痕钢。如果想引入 1.0 版本的 E图柏,需要直接在 A 的 pom 中聲明 E 的版本。

image-20211113200742469
(3)依賴循環(huán)

maven中禁止有循環(huán)依賴任连。比如A 依賴了 B蚤吹,同時 B 又依賴了 A。這種循環(huán)依賴可能不會直接顯現(xiàn)随抠,但是會在一個很長的調(diào)用關(guān)系顯現(xiàn)出來

(4)Maven多模塊問題

B模塊依賴A模塊裁着,A模塊的依賴修改了余佃,需要install一下,B模塊才能感知到最新的依賴跨算。

3爆土、工具

(1)日志

開發(fā)環(huán)境,建議默認(rèn)日志級別設(shè)置為info诸蚕,對需要關(guān)注的模塊步势,建議設(shè)置為debug模式,比如當(dāng)前工程目錄背犯,正在聯(lián)調(diào)的依賴jar包坏瘩。

如果異常無法定位,第一反應(yīng)應(yīng)該是添加日志漠魏。

(2)maven命令行

添加以下有空的命令行參數(shù):

  • -e 出錯日志

  • -X 打印debug日志

  • -q 只打印錯誤

(3)IDEA插件:Maven Helper

安裝插件后左下角會出現(xiàn)個新標(biāo)簽頁倔矾,點擊后搜所有此模塊依賴的jar包及沖突情況

image-20211113201357394
image-20211113201425368

4、新項目

新項目碰到錯誤柱锹,復(fù)雜的問題哪自,先不要深入研究,先看下是否有以下情況:

  • 新項目推薦Log4j2禁熏,代碼里統(tǒng)一用slf4j打日志

  • 新項目推薦spring boot壤巷,它們內(nèi)部把依賴問題都修復(fù)了,可以避免很多問題

5瞧毙、從下往上遞歸根因

java的錯誤棧是從報錯的最底層逐步往上打胧华,這樣能很方便的定位秤茅,一般的問題通過此手段定位問題后即可很快修復(fù)摆马。

復(fù)雜點的異常,比如jar包沖突異常爸吮,最底層的異常一般都是基礎(chǔ)組件释漆,比如類加載器悲没、日志組件等,這種情況就要多看幾層灵汪。

6檀训、從上往下查看變動

大部分問題都是新引入依賴導(dǎo)致,從上往下查看變動享言,配合從下往上定位信息峻凫,定位出問題的組件。

四览露、案例分享

1荧琼、Tomcat項目啟動報錯

背景:新需求接入輿情SDK,測試環(huán)境測試通過,線上發(fā)布有大量機(jī)器tomcat啟動失敗命锄。

(1)查找錯誤日志

異常日志:

image-20211113201801746

(2)嘗試修復(fù):第一次

通過module-info.class堰乔,和 tag in constant pool: 19分析,直觀感受是tomcat不支持java9中的模塊策略

機(jī)器上使用的是tomcat6, 還不支持java9的新模塊策略脐恩,遂升級tomcat6到tomcat8镐侯,啟動錯誤還有

(3)嘗試修復(fù):第二次

此異常是lombok-1.18.10引起的,這個版本為了支持java9添加了module-info.class驶冒,而lombok包是java源代碼增強(qiáng)的一個工具苟翻,運(yùn)行時,并不需要骗污,遂把依賴的scope改成provided崇猫。

重新發(fā)布,又報了以下異常:

image-20211113201859921

(4)嘗試修復(fù):第三次

報錯Not running on Jetty需忿,而我們的服務(wù)是運(yùn)行在tomcat上诅炉,配合從上到下排查的思路,在新引入的maven依賴項打開pom.xml屋厘,查看里面的依賴項還有parent里的依賴項涕烧,找到了以下元兇:parent里會依賴***-boot-starter-web,而這里默認(rèn)使用jetty作為引擎擅这,遂排除掉澈魄,并驗證業(yè)務(wù)邏輯是否正常景鼠。

image-20211113202044303

重新發(fā)布仲翎,問題解決。

(5)經(jīng)驗總結(jié)

  • 排查jar包也有風(fēng)險铛漓,很可能導(dǎo)致業(yè)務(wù)功能受影響溯香,排除后要經(jīng)過充分驗證

2、新加依賴后服務(wù)啟動失敗

背景:新需求接入用戶個性化api jar包浓恶,使用MDP的thrift注解注冊了 thrift client bean玫坛,引入后項目啟動失敗。

(1)異常日志

[圖片上傳中...(image-1c74a8-1637415298229-3)]

(2)定位問題

從堆棧初步看是以下包不兼容導(dǎo)致的:swift-codec或guava包晰,還有mtthrift湿镀。剛開始重點排查了swift-codec或guava的兼容問題,將其降級和新引入jar包里的版本一致伐憾,啟動錯誤還在

剛開始沒往mtthrift方面想勉痴,因為mtthrift是美團(tuán)的基礎(chǔ)組件,一般情況下不會出現(xiàn)兼容的問題树肃,查看官方wiki也沒說有兼容問題

(3)從上到下排查

查看新引入的依賴蒸矛,打開pom.xml,發(fā)現(xiàn)里面引入了MDP 1.5.5版本,而我們的項目的是最新的MDP 1.6.6.1, 初步判斷是MDP包沖突雏掠,所以就把新包的MDP包排除掉

image-20211113202304318

重新啟動斩祭,錯誤依舊

(4)排查版本不一致的依賴

到現(xiàn)在基本可以認(rèn)為是mtthrift升級導(dǎo)致的不兼容問題。我們引入的jar包只需要其中了api定義乡话,并不需要依賴的依賴摧玫,所以把所有的依賴都排除掉。重新引入和依賴包一致的mtthrift版本绑青。重新啟動席赂,問題解決。

[圖片上傳中...(image-43177d-1637415298229-1)]

(5)總結(jié)

這個問題解決過程中走了很多彎路时迫,一般我們的認(rèn)為基礎(chǔ)組件升級會兼容老版本颅停,還有一點加深了這個認(rèn)識:項目里引入的其他的thrift-client包,并沒有出現(xiàn)問題掠拳。

但不幸的是癞揉,這個正好遇到了此類問題。從最終的解決方案看溺欧,應(yīng)該是新引入的jar包編譯的問題喊熟。

五、對外發(fā)布jar包規(guī)范

  • 對外提供的SDK或API包姐刁,不要包含不必要的額外依賴

  • 嚴(yán)禁包含有依賴的parent的jar包發(fā)布

  • 必須要依賴的芥牌,可以依賴通用包比如common-langs、guava包等聂使,最好設(shè)置provided壁拉。

六、總結(jié)

Maven包依賴問題是開發(fā)中的常見問題柏靶,如果不熟悉排查方案弃理,會浪費(fèi)大量時間。本文從工具屎蜓、方法論痘昌、實踐方面做了一些思考,希望對大家日常開發(fā)有幫助炬转。

作者簡介:木小豐辆苔,美團(tuán)Java高級工程師,關(guān)注架構(gòu)扼劈、軟件工程驻啤、全棧等,不定期分享軟件研發(fā)過程中的實踐测僵、思考街佑。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末谢翎,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子沐旨,更是在濱河造成了極大的恐慌森逮,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件褒侧,死亡現(xiàn)場離奇詭異,居然都是意外死亡闷供,警方通過查閱死者的電腦和手機(jī)统诺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進(jìn)店門歪脏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人粮呢,你說我怎么就攤上這事∽墓眩” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵挺物,是天一觀的道長懒浮。 經(jīng)常有香客問我,道長识藤,這世上最難降的妖魔是什么砚著? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任赖草,我火速辦了婚禮剪个,結(jié)果婚禮上版确,老公的妹妹穿的比我還像新娘扣囊。我一直安慰自己绒疗,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布惕虑。 她就那樣靜靜地躺著,像睡著了一般溃蔫。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上私痹,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天统刮,我揣著相機(jī)與錄音,去河邊找鬼侥蒙。 笑死,一個胖子當(dāng)著我的面吹牛桦山,可吹牛的內(nèi)容都是我干的醋旦。 我是一名探鬼主播恒水,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼饲齐,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了御雕?” 一聲冷哼從身側(cè)響起滥搭,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎闽坡,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體疾嗅,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡冕象,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年渐扮,在試婚紗的時候發(fā)現(xiàn)自己被綠了掖棉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片膀估。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖玖像,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情笤昨,我是刑警寧澤握恳,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站崇裁,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏拔稳。R本人自食惡果不足惜锹雏,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望轻绞。 院中可真熱鬧佣耐,春花似錦、人聲如沸兼砖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽戏挡。三九已至晨仑,卻和暖如春褐墅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背竟贯。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工逝钥, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人持际。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓哗咆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親晌柬。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,465評論 2 348

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