依賴 Jar 沒有傳遞,導(dǎo)致找不到類文件而啟動(dòng)失敗了
前言
最近頻繁遇到找不到類文件錯(cuò)誤。
Caused by: java.lang.NoClassDefFoundError:xxx
就這個(gè)家伙。
但是我本地啟動(dòng)服務(wù)是正常的,前前后后經(jīng)歷了
驚訝 -> 疑惑 -> 煩躁 -> 暴躁 -> 心塞 -> 欣喜
在短短的小半天內(nèi),感覺心情像過了一個(gè)過山車+大擺錘,結(jié)束了,腦袋都是暈的。
關(guān)鍵是本地是正常的!
現(xiàn)在,請跟隨我的視角,來看看這個(gè)讓人心態(tài)差點(diǎn)爆炸的異常吧!
1遇到問題
在一頓噼里啪啦之后,代碼寫完,Junit 測試完畢、接口文檔 Upload 到 YApi 完畢。果斷發(fā)布 dev 環(huán)境!
直接進(jìn)入啟動(dòng)重試!(PS:通過發(fā)布平臺(tái)發(fā)布的)
這時(shí)候第一反應(yīng):本地啟動(dòng)一下試試!
- web started successfully
本地正常啊!
肯定是我啟動(dòng)姿勢不正確,重新發(fā)布一下!
實(shí)錘了,和啟動(dòng)姿勢沒關(guān)系!
從淡定到暴躁
當(dāng)然是看啟動(dòng)日志了。
PS: 服務(wù)沒起來,只能 ssh 到服務(wù)器看日志。
- Caused by: java.lang.ClassNotFoundException:xxx
- Caused by: java.lang.NoClassDefFoundError:xxx
就這倆哥們,類找不到,奇了怪了。
這個(gè)類是通過三方 jar 包依賴進(jìn)來的,我在 IDEA 里面 ? + B 還能進(jìn)入源碼!
這我不禁懷疑是不是因?yàn)殚_發(fā)環(huán)境使用的 Docker 容器的原因。
發(fā)布其他分支,是可以的。
莫非就是因?yàn)槲乙肓艘粋€(gè)其他小伙伴提供的 jar,導(dǎo)致我現(xiàn)在用不了!
又是一頓調(diào)整依賴!
還不行!
難道是我引入的引來版本不對?
從其他項(xiàng)目找一找怎么用的!
依然不行!
難道是他的 jar 包里面又依賴了很多其他的?
試著 exclusion 掉其他依賴!
依然不行!
是我本地 jar 緩存?
刪除本地磁盤上的 jar 試試?
解決方案就在靈光一閃
雖然 dev 用的是容器,咱拉不下來 jar 包。但是我可以本地打個(gè)包試試!
clean package
得到一個(gè) jar 包
- jar -xvf xxx-web-1.0.0-SNAPSHOT.jar
進(jìn)到 BOOT-INF/lib 里面
- % > ls | grep user
竟然啥也沒有!
既然是打包沒有打進(jìn)去,那就看一下 mvn 依賴樹的問題吧!
解決問題
項(xiàng)目結(jié)構(gòu)
web 啟動(dòng)失敗,是因?yàn)?service 添加的依賴,沒有傳遞到 web,所以 web 打包沒有打進(jìn)去那個(gè)類。
注意,這里可以正常打包,本地環(huán)境可以正常啟動(dòng)。
奇怪吧!
現(xiàn)在進(jìn)入解決方式:
- 查看 maven 依賴樹
進(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
問題描述的很清晰,依賴傳遞失敗,因?yàn)樯兑蕾噦鬟f失敗呢?
再開啟 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. @
說是因?yàn)橄旅鎯蓚€(gè) jar 的 version 找不到,所以會(huì)導(dǎo)致依賴傳遞失敗。
PS: 我所有的依賴版本都是在父 POM 進(jìn)行維護(hù)的,子 module 只有依賴 groupId 和 artifactId。
所以歸根到底,是因?yàn)楦?POM 的版本沒有傳遞下去!
仔細(xì)一瞅,發(fā)現(xiàn)父 POM 的版本是 1.0.0,各個(gè) module 的 parent 節(jié)點(diǎn)的屬性也是
之前都是 SNAPSHOT 版本,后來因?yàn)楣镜?nexus 配置了自動(dòng)清除長時(shí)間不用的 SNAPSHOT 版本的依賴,我就去掉了 SNAPSHOT。
父 POM deploy 到私服的就是一個(gè)空的項(xiàng)目,里面就一個(gè) POM 文件。
最后升級了一下父 POM 的版本,重新 deploy 一下,再改改各個(gè) module 的依賴版本。
大功告成!
2總結(jié)
本文主要是含淚記下一個(gè)苦逼的問題排查過程。害,竟然沒有第一時(shí)間想到原因!
下次再遇到記得 mvn -X dependency:tree>tree.txt 看下依賴樹!
我的實(shí)踐已經(jīng)證明了:重啟、清緩存、排除依賴都是沒用的!
本文轉(zhuǎn)載自微信公眾號「程序員小航」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系程序員小航公眾號。