java noSuchMethodError 產(chǎn)生原因以及解決方案
表象原因
A.class 調(diào)用的 B.methodX 剧包。
運(yùn)行時候的 加載到B 的 class 中methodX 可能存在的情況
methodX 方法的確不存在
methodX 方法簽名和 A.class調(diào)用的 B.methodX簽名不一致
根本原因
編譯時 B 的版本和 運(yùn)行時 B 的版本不一致
運(yùn)行時 B 的 jar 包在 classPath 中有多個,jvm 加載到錯誤的 jar 包
不同 classLoader 加載到B 不同版本的類。
子 classLoader 在委托父類的時候加載的時候,獲取到了到父 classLoder 加載的B.class
分類
jvm 中的類
- 原因
- 通常是寫代碼的時候,以及編譯的時候用的 jdk 版本比較高,但是運(yùn)行時候用的 jdk 版本較低
- 解決方案
- 確認(rèn)運(yùn)行環(huán)境 jdk 版本是否正確
公司項目 jar 包中的類
- 原因
引入低版本的 jar 包
引入的 snapshot 版本的包不是最新的
- 解決方案
修改依賴版本的 jar 包 為正確版本
snapshot 版本包不對
- 執(zhí)行 mvn 命令時加-U 參數(shù)拦惋。mvn clean package/install -U
不建議
其他環(huán)境編譯的時候,也同樣要加參數(shù)
- maven 配置
settings.xml 中配置
<profile>
<id>nexus</id>
<repositories>
<repository>
<id>central</id>
<url>http://central</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</repository>
</repositories>
</profile>
不建議使用
其他人也要修改
- 項目中 pom.xml中配置
- 建議使用
項目中依賴第三方 jar 包中的類
- 原因
引入低版本的 jar 包
引入多個 jar 包安寺,但是加載到了錯誤版本的 jar 包
子類 classLoader 加載類時候厕妖,委托父類 classLoader 加載到低版本的 classLoader
- 定位方式
1.先通過-verbose:class 查找加載到哪個類
2.通過 jvm 類加載器結(jié)構(gòu)判斷,是那個類加載器加載到這個類 然后想辦法解決
- 解決方案
修改為正確版本的 jar 包
通過 maven 命令選擇正確的 jar 包
- 第一步:列出依賴的 jar 包
mvn dependency:list命令可以列出當(dāng)前所有依賴(包括直接和傳遞)的列表挑庶,以及范圍叹放。
mvn dependency:tree命令可以層次化的列出所有依賴,可以從書中看出依賴傳遞的關(guān)系挠羔。
- 第二步:利用 exclude 排除不需要的依賴
- 利用 jvm 命令 查看加載了哪個 jar 包 導(dǎo)致的錯誤
- -verbose:class