依賴 jar 沒(méi)有傳遞,導(dǎo)致找不到類文件而啟動(dòng)失敗了

前言
最近頻繁遇到找不到類文件錯(cuò)誤。
Caused by: java.lang.NoClassDefFoundError:xxx
就這個(gè)家伙。
但是我本地啟動(dòng)服務(wù)是正常的,前前后后經(jīng)歷了
驚訝 -> 疑惑 -> 煩躁 -> 暴躁 -> 心塞 -> 欣喜
在短短的小半天內(nèi),感覺(jué)心情像過(guò)了一個(gè)過(guò)山車+大擺錘,結(jié)束了,腦袋都是暈的。
關(guān)鍵是本地是正常的!

現(xiàn)在,請(qǐng)跟隨我的視角,來(lái)看看這個(gè)讓人心態(tài)差點(diǎn)爆炸的異常吧!
1
遇到問(wèn)題
在一頓噼里啪啦之后,代碼寫完,Junit 測(cè)試完畢、接口文檔 Upload 到 YApi 完畢。果斷發(fā)布 dev 環(huán)境!
直接進(jìn)入啟動(dòng)重試?。≒S:通過(guò)發(fā)布平臺(tái)發(fā)布的)
這時(shí)候第一反應(yīng):本地啟動(dòng)一下試試!
web started successfully
本地正常??!
肯定是我啟動(dòng)姿勢(shì)不正確,重新發(fā)布一下!

實(shí)錘了,和啟動(dòng)姿勢(shì)沒(méi)關(guān)系!
從淡定到暴躁
當(dāng)然是看啟動(dòng)日志了。
PS: 服務(wù)沒(méi)起來(lái),只能 ssh 到服務(wù)器看日志。
Caused by: java.lang.ClassNotFoundException:xxx
Caused by: java.lang.NoClassDefFoundError:xxx
就這倆哥們,類找不到,奇了怪了。
這個(gè)類是通過(guò)三方 jar 包依賴進(jìn)來(lái)的,我在 IDEA 里面 ? + B 還能進(jìn)入源碼!
這我不禁懷疑是不是因?yàn)殚_(kāi)發(fā)環(huán)境使用的 Docker 容器的原因。
發(fā)布其他分支,是可以的。

莫非就是因?yàn)槲乙肓艘粋€(gè)其他小伙伴提供的 jar,導(dǎo)致我現(xiàn)在用不了!
又是一頓調(diào)整依賴!
還不行!
難道是我引入的引來(lái)版本不對(duì)?
從其他項(xiàng)目找一找怎么用的!
依然不行!
難道是他的 jar 包里面又依賴了很多其他的?
試著 exclusion 掉其他依賴!
依然不行!
是我本地 jar 緩存?
刪除本地磁盤上的 jar 試試?
??????!

解決方案就在靈光一閃
雖然 dev 用的是容器,咱拉不下來(lái) jar 包。但是我可以本地打個(gè)包試試!
clean package
得到一個(gè) jar 包
jar -xvf xxx-web-1.0.0-SNAPSHOT.jar
進(jìn)到 BOOT-INF/lib 里面
% > ls | grep user
竟然啥也沒(méi)有!

既然是打包沒(méi)有打進(jìn)去,那就看一下 mvn 依賴樹(shù)的問(wèn)題吧!
解決問(wèn)題

web 啟動(dòng)失敗,是因?yàn)?service 添加的依賴,沒(méi)有傳遞到 web,所以 web 打包沒(méi)有打進(jìn)去那個(gè)類。
注意,這里可以正常打包,本地環(huán)境可以正常啟動(dòng)。
奇怪吧!
現(xiàn)在進(jìn)入解決方式:
查看 maven 依賴樹(shù)
進(jìn)入到 web module,執(zhí)行以下命令。
mvn dependency:tree>tree.txt
有這么一行錯(cuò)誤:
[WARNING] The POM for com.xxx:xxx-xxx-xxx:jar:1.0.1-SNAPSHOT is invalid, transitive dependencies (if any) will not be available, enable debug logging for more details
問(wèn)題描述的很清晰,依賴傳遞失敗,因?yàn)樯兑蕾噦鬟f失敗呢?
再開(kāi)啟 debug 打印下錯(cuò)誤:
mvn -X dependency:tree>tree.txt
[WARNING] The POM for com.xxx:xxx-xxx-xxx:jar:1.0.1-SNAPSHOT is invalid, transitive dependencies (if any) will not be available: 2 problems were encountered while building the effective model for com.xxx:xxx-xxx-xxx:jar:1.0.1-SNAPSHOT
[ERROR] 'dependencies.dependency.version' for com.alibaba:easyexcel:jar is missing. @
[ERROR] 'dependencies.dependency.version' for com.xxx:cache:jar is missing. @
說(shuō)是因?yàn)橄旅鎯蓚€(gè) jar 的 version 找不到,所以會(huì)導(dǎo)致依賴傳遞失敗。
PS: 我所有的依賴版本都是在父 POM 進(jìn)行維護(hù)的,子 module 只有依賴 groupId 和 artifactId。
所以歸根到底,是因?yàn)楦?POM 的版本沒(méi)有傳遞下去!
仔細(xì)一瞅,發(fā)現(xiàn)父 POM 的版本是 1.0.0,各個(gè) module 的 parent 節(jié)點(diǎn)的屬性也是 <version>1.0.0</version>。
之前都是 SNAPSHOT 版本,后來(lái)因?yàn)楣镜?nexus 配置了自動(dòng)清除長(zhǎng)時(shí)間不用的 SNAPSHOT 版本的依賴,我就去掉了 SNAPSHOT。
父 POM deploy 到私服的就是一個(gè)空的項(xiàng)目,里面就一個(gè) POM 文件。
最后升級(jí)了一下父 POM 的版本,重新 deploy 一下,再改改各個(gè) module 的依賴版本。
大功告成!
2
總結(jié)
本文主要是含淚記下一個(gè)苦逼的問(wèn)題排查過(guò)程。害,竟然沒(méi)有第一時(shí)間想到原因!

下次再遇到記得 mvn -X dependency:tree>tree.txt 看下依賴樹(shù)!
我的實(shí)踐已經(jīng)證明了:重啟、清緩存、排除依賴都是沒(méi)用的!
- <End /> -
歷史文章 | 相關(guān)推薦

