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