前言
有时spring boot应用会遇到java.lang.NoSuchMethodError
的问题,下面以具体的demo来说明怎样利用arthas来排查。
Demo: https://github.com/hengyunabc/spring-boot-inside/tree/master/demo-NoSuchMethodError
在应用的main函数里catch住异常,保证进程不退出
很多时候当应用抛出异常后,进程退出了,就比较难排查问题。可以先改下main函数,把异常catch住:
1 | public static void main(String[] args) throws IOException { |
Demo启动之后,抛出的异常是:
1 | java.lang.NoSuchMethodError: org.springframework.core.annotation.AnnotationAwareOrderComparator.sort(Ljava/util/List;)V |
显然,异常的意思是AnnotationAwareOrderComparator
缺少sort(Ljava/util/List;)V
这个函数。
安装arthas
参考:https://alibaba.github.io/arthas/install-detail.html
使用sc命令查找类所在的jar包
应用需要抛出了异常,但是进程还没有退出,我们用arthas来attach上去。比如在mac下面:
1 | ./as.sh |
然后选择com.example.demoNoSuchMethodError.DemoNoSuchMethodErrorApplication
进程。
再执行sc命令来查找类:
1 | $ sc -d org.springframework.core.annotation.AnnotationAwareOrderComparator |
可以看到AnnotationAwareOrderComparator
是从spring-2.5.6.SEC03.jar
里加载的。
使用jad查看反编绎的源代码
下面使用jad命令来查看AnnotationAwareOrderComparator
的源代码
1 | $ jad org.springframework.core.annotation.AnnotationAwareOrderComparator |
可见,AnnotationAwareOrderComparator
的确没有sort(Ljava/util/List;)V
函数。
排掉依赖,解决问题
从上面的排查里,可以确定
AnnotationAwareOrderComparator
来自spring-2.5.6.SEC03.jar
,的确没有sort(Ljava/util/List;)V
函数。
所以,可以检查maven依赖,把spring 2的jar包排掉,这样子就可以解决问题了。
总结
- 仔细看
NoSuchMethodError
的异常信息,了解是什么类缺少了什么函数 - 利用arthas来查找类,反编绎源码,确认问题