java.lang.NoSuchMethodError问题定位

出现java.lang.NoSuchMethodError这个异常的原因基本上都是是类冲突,即在不同的jar包中有全名完全相同的两个类,但是方法的参数不一致。下面介绍几种定位和解决这个问题的办法。

方法1

例如如下所示,在knowledge-api-5.5.0.Final.jar和drools-api-5.1.0.jar中都有org.drools.util.CompositeClassLoader这个类:
orgdroolsknowledge-api5.5.0.Finalknowledge-api-5.5.0.Final.jar!orgdroolsutil
orgdroolsdrools-api5.1.0drools-api-5.1.0.jar!orgdroolsutil
排查这个问题很简单,在抛异常的代码行上加上如下这段代码:
String location = “”;
String urlLocation = “”;
try {
    location =CompositeClassLoader.class.getProtectionDomain().getCodeSource().getLocation().getFile();
    urlLocation =  URLDecoder.decode(location, “UTF-8”);
catch (Exception e) {
    logger.error(“get LOCATION error”, e);
}
logger.debug(“** location=” + location + “; URLLocation=” + urlLocation);
// 这行业务代码就是抛出java.lang.NoSuchMethodError异常的地方,上面的代码都是辅助定位问题
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
再次运行就能知道加载的是哪个jar包中的class文件了,log日志会把加载的包名的全路径打印出来;
这种方法需要修改源码,所以比较适合本地的开发环境。

方法2(推荐)

增加-verbose:class这个JVM参数,控制台日志中会输出哪个类从哪个jar包中加载的信息。得到这个信息后,就能定位类冲突问题了,类似日志如下:
[Loaded com.google.common.base.Predicate from file:/app/fin-rules-service/lib/guava-16.0.1.jar]
[Loaded com.google.common.collect.Lists from file:/app/fin-rules-service/lib/guava-16.0.1.jar]
[Loaded com.google.common.collect.Lists$TransformingRandomAccessList from file:/app/fin-rules-service/lib/guava-16.0.1.jar]
[Loaded com.google.common.collect.Lists$TransformingSequentialList from file:/app/fin-rules-service/lib/guava-16.0.1.jar]
[Loaded com.google.common.collect.Lists$Partition from file:/app/fin-rules-service/lib/guava-16.0.1.jar]
从这段日志,我们就能知道com.google.common.collect.Lists来源于guava 16.0.1这个版本,而跟踪我们的源码发现Lists实际需要的是guava 20.0这个版本才行。
这些方法不需要修改源码,只需要增加一个JVM参数。所以非常建议在非开发环境,例如生产环境上使用。

写在最后

这两种方法都是只能找到加载错误的jar包,我们最终还是要根据这些信息,排除掉对问题包的依赖从而解决问题。
非常推荐使用mvn命令mvn dependency:tree查看问题包是怎么引入的,从而exclude掉对问题包的依赖。

    本站所有文章均由网友分享,仅用于参考学习用,请勿直接转载,如有侵权,请联系网站客服删除相关文章。若由于商用引起版权纠纷,一切责任均由使用者承担
    极客文库 » java.lang.NoSuchMethodError问题定位

    Leave a Reply

    欢迎加入「极客文库」,成为原创作者从这里开始!

    立即加入 了解更多