设为首页 收藏本站
查看: 1356|回复: 0

[经验分享] java--遇到NoSuchMethodError通用解决思路

[复制链接]

尚未签到

发表于 2017-3-1 10:03:43 | 显示全部楼层 |阅读模式
  最近接手新项目,项目一跑,NoSuchMethodError蹦出来了,好不容易解决了,换一个电脑,NoSuchMethodError又蹦出来了,干脆,总结下遇到NoSuchMethodError应该如何应对的思路。
  通过下面的通用思路,可以在不必了解业务的情况下,尽可能解决这个报错。
  下面演示下如何在啥都不知道的情况下遇到该错误的解决思路:
  随便找一个错误示例



Caused by: java.lang.NoSuchMethodError: org.eclipse.jdt.internal.compiler.Compiler.<init>(Lorg/eclipse/jdt/internal/compiler/env/INameEnvironment;Lorg/eclipse/jdt/internal/compiler/IErrorHandlingPolicy;Lorg/eclipse/jdt/internal/compiler/impl/CompilerOptions;Lorg/eclipse/jdt/internal/compiler/ICompilerRequestor;Lorg/eclipse/jdt/internal/compiler/IProblemFactory;)V
at com.taobao.sketch.compile.Compiler.generateClass(Compiler.java:392)
at com.taobao.sketch.compile.Compiler.compile(Compiler.java:38)
at com.taobao.sketch.compile.SketchCompilationContext.globalVmCompile(SketchCompilationContext.java:403)
at com.taobao.sketch.runtime.SketchRuntimeServer.getGlobalVmTemplate(SketchRuntimeServer.java:622)
at com.taobao.sketch.runtime.SketchRuntimeServer.resolveGloabalVm(SketchRuntimeServer.java:136)
at com.taobao.sketch.runtime.SketchRuntimeServer.initializeVmLibrary(SketchRuntimeServer.java:127)
at com.taobao.sketch.runtime.SketchRuntimeServer.init(SketchRuntimeServer.java:96)
at com.taobao.sketch.SketchEngine.init(SketchEngine.java:66)
at com.taobao.sketch.service.impl.SketchEngineImpl.init(SketchEngineImpl.java:118)
at com.alibaba.citrus.springext.support.BeanSupport.afterPropertiesSet(BeanSupport.java:80)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1369)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1335)
... 39 more
  这是一个webx框架下的javaweb项目,在启动jetty服务器时报的错。一开始看时看到报错,内心是奔溃的,刚接手项目,以前代码又不是我写的,我怎么知道会报找不到方法的是什么原因引起的啊。别急,先看引起这个错误有可能的原因是什么。
  错误可能的原因


  • 有这个类,该类真的没有这个方法
  • 有这个类,而且有好几个,他们之间发生了冲突
  原因排除
  1、点击进入报错的代码所在行,在报错的地方打一个debug点,重行启动项目或重现该错误,让程序运行到该行代码:
DSC0000.png  

DSC0001.png

  2、打开display界面(若没有,请在window--show view里面找出该界面),
    手动敲出xxx.class.getProtectionDomain().getCodeSource(),xxx为报错的类的全类名,鼠标选中该行代码,点击界面右上角的J图标,即会打印出到该类对应的包所在的地址。如下图所示。  
DSC0002.png

  可以看到,结果为:
  (java.security.CodeSource) (file:/D:/Program%20Files%20(x86)/eclipse/configuration/org.eclipse.osgi/843/0/.cp/lib/core-3.1.1.jar <no signer certificates>)
  3、接着复制该类的全类名,快捷键Ctrl+Shift+T打开open type界面,查看我们的项目引用到的包中,哪些有这个类:
DSC0003.png

  我们发现有两个包中有org.eclipse.jdt.internal.compiler.Compiler这个类,分别为:
  包一:ecj.3.5.1.jar
  包二:core-3.1.1.jar
  地址分别为:
DSC0004.png

  但我们发现,刚刚在display中,我们看到的地址,居然不是来自这上面两个地址(上面两个包的地址都在C盘,DEBUG中的包来自D盘),也就是说,实现运行环境引入的包,并不是在我们自己项目中配置的,因为open typy只能找到自己项目中配的东西。
  那么D盘的这个包,在什么地方引入的呢?
  想想,这个错误是在项目启动时报的,那么除了项目,还有“服务器”可能会引入其他包,那么有没有可能是服务器帮我们引入呢?
  4、打开服务器的Classpath,可以找到服务器确实引入了这个包
     DSC0005.png
  那么我们在服务器的classpath中把这个包“remove”掉。
  5、再次重新启动项目,dubug、卡点、display,这次结果如下:
   DSC0006.png
    发现:实际环境中,现在己经没有引入D盘那个core-3.1.1.jar包了。我们让项目运行下去,发现还是报同样的错——找不到方法。那么接下来我们让项目引用ecj.3.5.1.jar这个包试试。
  6、ctrl+shift+T、双击进入core-3.1.1.jar中Compiler类所在的目录结构:
     DSC0007.png  
  提示:左边栏勾上这个标志,即可展开该包所在的目录:
     DSC0008.png
DSC0009.png

  同理,打开ecj.3.5.1.jar中Compiler类所在的目录结构。
  最后发现,这个jar包都同一个项目下面,而且两个包都有Compiler类,且排在前面的是core-3.1.1.jar,但是core-3.1.1.jar的Compiler类并没有我们想要的方法,所以报错了。但是eclipse在找类的时候,只要按顺序找到一个,就不会往下找了,所以排在下面的ecj-3.5.1.jar并不会被找到,即使里面有Compiler这个类,且有我们想要的方法。
  7、排除core-3.1.1.jar包:
  该项目是maven项目。我们尝试直接在该项目的pom.xml中搜索core这个包是搜索不到的,那么这个core-3.1.1包可能是因为本项目引入其他项目,而其他项目引入core-3.1.1.jar,所以本项目间接把该包引过来了。
  同时,因为该项目是maven项目,可以通过以下该方法排除这个包:
     DSC00010.png
  排除后,该项目的pom.xml变成:
     DSC00011.png
  假如是非maven项目,那么可以直接从lib中除去该包,或从项目根目录下面打开.classpath文件,找到对应的包的配置,删除该行即可。
  通过该pom.xml我们可以知道,之所以会产生jar包冲突,原因有两个:
  1、 本项目A本身引用了ecj-3.5.1.jar包,同时引入了项目B,而项目B引入了core-3.1.1.jar,所以本项目也相当于引入了core-3.1.1.jar,这就是maven项目中常见的jar包冲突。
  2、 那为什么maven没有自动帮我们解决jar包冲突呢,那是因为ecj-3.5.1.jar包和core-3.1.1.jar包的groupId和artifactId都不一样,所以maven认为这是两个jar包,并不冲突,解决的办法就是像上面那样,加入exclusions排除。所以我们在开发一个组件的时候,起名字是一个很重要的问题,如果升级组件连名字也改了,用户会产生很大的不方便。
  再次启动项目,问题解决。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-348668-1-1.html 上篇帖子: Emoji与unicode特殊字符的处理 下篇帖子: 基于jFinal建立简单的服务端-接收请求并返回指定内容
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表