相 關 閱 讀
導讀
『StabilityGuide』是阿里多位阿里技術工程師共同發起的穩定性領域的知識庫開源項目,涵蓋性能壓測、故障演練、JVM、應用容器、服務框架、流量調度、監控、診斷等多個技術領域,以更結構化的方式來打造穩定性領域的知識庫,歡迎您的加入。

- 正文開始 -
🧯
運行時拋出 NoSuchMethodError 的根本原因是什么?
為什么同一個 Class 會出現多個版本?
-
JDK 版本不一致。常見於編譯打包環境使用高版本 JDK 開發與打包,而實際運行環境的 JDK 版本較低。例如,本地項目環境 JDK 版本為 1.7,調用 Character.isAlphabetic() 方法判斷當前字符是否為字母;而線上環境 JDK 版本為 1.6,在運行期間就會拋出 NoSuchMethodError 錯誤。
-
SNAPSHOT 版本不一致。常見於本地更新 SNAPSHOT 版本后,沒有執行 mvn clean deploy 部署,導致線上環境運行時仍然引用了舊版本的 SNAPSHOT 包。
-
Maven 依賴生命周期為 provided。常見於本地依賴的某組件生命周期為 provided,所聲明版本僅用於本地編譯打包,而線上運行時會通過其他依賴關系加載 Jar 包。
-
同一個 Jar 包出現了多個版本。常見於 Maven 依賴未顯式指定版本號,導致間接依賴版本沖突,很容易引入低版本的 Jar 包。
-
同一個 Class 出現在不同的 Jar 包中。該問題常見於代碼拷貝場景,比如基於開源版本定制了一些功能,使用了新的 Maven 坐標打包發布,此時 Maven 仲裁機制失效(非常隱蔽,難以排查)。由於 JVM 類加載器對於同一個類只會加載一次,最終加載的類實現受到 Jar 包依賴的路徑、類聲明的先后順序或文件加載順序等因素的影響,很可能出現不同機器加載的類實現不一致。
哪個版本的 Class 最終會被執行?
優先按照依賴管理 [dependencyManagement] 元素中指定的版本進行仲裁;
若無版本聲明,則按照 “短路徑優先” 原則(Maven2.0)進行仲裁,即選擇依賴樹中路徑最短的版本;
若路徑長度一致,則按照 “第一聲明優先” 原則進行仲裁,即選擇 POM 中最先聲明的版本。
啟動類加載器(Bootstrap ClassLoader)優先級最高,主要加載 JVM 運行時核心類,如 java.util、java.io等,這些類主要位於 $JAVA_HOME/lib/rt.jar 文件中。
擴展類加載器(Extention ClassLoader)優先級次之,主要加載 JVM 擴展類,如 swing 組件、xml 解析器等,這些類主要位於 $JAVA_HOME/lib/ext/ 目錄下的 Jar 包中。
應用類加載器(Application ClassLoader),又稱系統類加載器,優先級再次之,它會加載 Classpath 環境變量里定義的路徑中的 Jar 包和目錄,通常我們自己編寫的代碼或依賴的第三方 Jar 包都是由它來加載。
如何解決 NoSuchMethodError 錯誤?
Exception in thread "main" java.lang.NoSuchMethodError: com.xxx.AsyncAppender.append(Ljava/lang/String;)Ljava/lang/String;
at com.xxx.ProvokeNoSuchMethodError.main(ProvokeNoSuchMethodError:7)
at ……
其他 Jar 包沖突問題
本文介紹的 Jar 包沖突解決方法,除了解決 java.lang.NoSuchMethodError 以外,對其他相似問題也具備一定的參考價值。
推薦工具&產品
ARMS —— 阿里雲 APM 產品,支持 NoSuchMethodError 異常關鍵字告警
https://help.aliyun.com/document_detail/42966.html
Arthas —— Java 在線診斷工具
https://github.com/alibaba/arthas
參考文章
重新看待 Jar 包沖突問題及解決方案
http://www.yangbing.club/2017/07/15/solution-for-jar-conflicts/
3 Steps to Fix NoSuchMethodErrors and NoSuchMethodExceptionshttps://reflectoring.io/nosuchmethod/
作者信息:
夏明,GitHub ID @StabilityMan,花名涯海,阿里雲 ARMS & EagleEye 技術專家,2016 年加入阿里巴巴,一直從事鏈路追蹤和 APM 監控診斷領域的相關工作。
本文縮略圖:icon by 軒坊
本號專注於后端技術、JVM問題排查和優化、Java面試題、個人成長和自我管理等主題,為讀者提供一線開發者的工作和成長經驗,期待你能在這里有所收獲。

點“在看”你懂得
