NoSuchMethodError 问题

最近maven升级到gradle后,总是报NoSuchMethod error。然后 ,报错的类确实是有这个方法,一切看起来都没有问题。那么运行时jvm到底加载的哪里的类呢?有没有相关的命令可以查询,答案是有的:

1)方法1:

jvm里面有一个跟踪classload的参数: 

-XX:+TraceClassLoading

可以看到运行时加载的类,然后,找到这个类反编译,发现确实没有这个方法。

2)方法2:

阿里的聚石写了一个housemd的工具 ,安装方法可以点击这里(https://github.com/CSUG/HouseMD) , 启动后运行如下命令attach到tomcat进程:

housemd `jps|grep Bootstrap|awk '{print $1}'`

 然后loaded classname 就可以得到运行时类所在的jar .

 要自己实现的话,比如我们要获取一个Test.class类是被哪个jar导入的,可以这样

URL url =  Log.class.getClassLoader().getResource("Test.class");  

 url.getFile(); 

另外,还可以用loaded -h 命令查看类加载器树, 

要自己实现的话可以这样:

for(ClassLoader cl = Log.class.getClassLoader(); cl  != null ; cl = cl.getParent()){

  System.out.println(cl.getName()); 

}

那么我们能否在应用打包的时候,就分析出存在jar冲突的地方呢 ?我的思路是这样的: 

1、在应用打包成功以后,把应用的class的jar包拷贝到一个临时文件夹。

2、对这些jar包中的字节码文件,做如下操作:

1)使用asm分析出class 导入的class .

2)对每一个导入的class获取 build classpath下的jar列表,如果jar的个数大于等于2 ,则表明有jar冲突。 

3)输出jar冲突信息到控制台。

目前,我已经在本机mac环境下实现了基本功能, 接下来的计划是做成maven插件,放到整个maven应用的build cycle中去。

原文地址:https://www.cnblogs.com/lzmrex/p/10563804.html