利用Arthas排查NoSuchMethodError
1、前言
有時spring boot應用會遇到java.lang.NoSuchMethodError的問題,下面以具體的demo來說明怎樣利用arthas來排查。
Demo: https://github.com/hengyunabc/spring-boot-inside/tree/master/demo-NoSuchMethodError
2、在應用的main函數里catch住異常,保證進程不退出
很多時候當應用拋出異常后,進程退出了,就比較難排查問題??梢韵雀南耺ain函數,把異常catch住:
public static void main(String[] args) throws IOException {try {SpringApplication.run(DemoNoSuchMethodErrorApplication.class, args);} catch (Throwable e) {e.printStackTrace();}// blockSystem.in.read();}Demo啟動之后,拋出的異常是:
java.lang.NoSuchMethodError: org.springframework.core.annotation.AnnotationAwareOrderComparator.sort(Ljava/util/List;)Vat org.springframework.boot.SpringApplication.getSpringFactoriesInstances(SpringApplication.java:394)at org.springframework.boot.SpringApplication.getSpringFactoriesInstances(SpringApplication.java:383)at org.springframework.boot.SpringApplication.initialize(SpringApplication.java:249)at org.springframework.boot.SpringApplication.<init>(SpringApplication.java:225)at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118)at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107)at com.example.demoNoSuchMethodError.DemoNoSuchMethodErrorApplication.main(DemoNoSuchMethodErrorApplication.java:13)顯然,異常的意思是AnnotationAwareOrderComparator缺少sort(Ljava/util/List;)V這個函數。
3、安裝arthas
參考:https://alibaba.github.io/arthas/install-detail.html
使用sc命令查找類所在的jar包
應用需要拋出了異常,但是進程還沒有退出,我們用arthas來attach上去。比如在mac下面:
然后選擇com.example.demoNoSuchMethodError.DemoNoSuchMethodErrorApplication進程。
再執行sc命令來查找類:
$ sc -d org.springframework.core.annotation.AnnotationAwareOrderComparatorclass-info org.springframework.core.annotation.AnnotationAwareOrderComparatorcode-source /Users/hengyunabc/.m2/repository/org/springframework/spring/2.5.6.SEC03/spring-2.5.6.SEC03.jarname org.springframework.core.annotation.AnnotationAwareOrderComparatorisInterface falseisAnnotation falseisEnum falseisAnonymousClass falseisArray falseisLocalClass falseisMemberClass falseisPrimitive falseisSynthetic falsesimple-name AnnotationAwareOrderComparatormodifier publicannotationinterfacessuper-class +-org.springframework.core.OrderComparator+-java.lang.Objectclass-loader +-sun.misc.Launcher$AppClassLoader@5c647e05+-sun.misc.Launcher$ExtClassLoader@689e3d07classLoaderHash 5c647e05Affect(row-cnt:1) cost in 41 ms.可以看到AnnotationAwareOrderComparator是從spring-2.5.6.SEC03.jar里加載的。
4、使用jad查看反編繹的源代碼
下面使用jad命令來查看AnnotationAwareOrderComparator的源代碼
$ jad org.springframework.core.annotation.AnnotationAwareOrderComparatorClassLoader: +-sun.misc.Launcher$AppClassLoader@5c647e05+-sun.misc.Launcher$ExtClassLoader@689e3d07Location: /Users/hengyunabc/.m2/repository/org/springframework/spring/2.5.6.SEC03/spring-2.5.6.SEC03.jar/** Decompiled with CFR 0_132.*/ package org.springframework.core.annotation;import java.lang.annotation.Annotation; import org.springframework.core.OrderComparator; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order;public class AnnotationAwareOrderComparator extends OrderComparator {protected int getOrder(Object obj) {Order order;if (obj instanceof Ordered) {return ((Ordered)obj).getOrder();}if (obj != null && (order = obj.getClass().getAnnotation(Order.class)) != null) {return order.value();}return Integer.MAX_VALUE;} }Affect(row-cnt:1) cost in 286 ms.可見,AnnotationAwareOrderComparator的確沒有sort(Ljava/util/List;)V函數。
5、排掉依賴,解決問題
從上面的排查里,可以確定
- AnnotationAwareOrderComparator來自spring-2.5.6.SEC03.jar,的確沒有sort(Ljava/util/List;)V函數。
所以,可以檢查maven依賴,把spring 2的jar包排掉,這樣子就可以解決問題了。
6、總結
- 仔細看NoSuchMethodError的異常信息,了解是什么類缺少了什么函數
- 利用arthas來查找類,反編繹源碼,確認問題
本文主要注重思路。很多時候,本地開發與服務器上可能存在差異,本地問題容易debug,遠程的雖然也可以遠程debug,但是畢竟沒有本地方便。所以,借助工具(如:Arthas)會更容易分析服務器上的問題。
本文主要參考:https://yq.aliyun.com/articles/645679?utm_content=m_1000017531
總結
以上是生活随笔為你收集整理的利用Arthas排查NoSuchMethodError的全部內容,希望文章能夠幫你解決所遇到的問題。