你真的知道 NoSuchMethodError 发生原因和解决办法吗 | 您所在的位置:网站首页 › hadoop产生的原因 › 你真的知道 NoSuchMethodError 发生原因和解决办法吗 |
当应用程序试图调用类(静态或实例)的指定方法,而该类已不再具有该方法的定义时,就会抛出 java.lang.NoSuchMethodError 错误。简单地说,就是同一个 Class 有多个版本的实现,并且在运行时调用了缺少方法的那个版本。本文总结了 NoSuchMethodError 常见原因及其解决方法,如有遗漏或错误,欢迎补充指正。 运行时抛出 NoSuchMethodError 的根本原因是什么? 在实际生产系统中,我们主要关注运行时抛出的 NoSuchMethodError 错误,该错误轻则导致程序异常终止,严重时甚至会产生不可预知的程序结果,比如支付服务执行异常,实际支付已完成,却向用户返回支付失败。 运行时抛出 NoSuchMethodError 错误的根本原因就是:应用程序直接或间接依赖了同一个类的多个版本,并且在运行时执行了缺少方法的版本。如下图所示:![]() ![]() 优先按照依赖管理 [dependencyManagement] 元素中指定的版本进行仲裁; 若无版本声明,则按照 “短路径优先” 原则(Maven2.0)进行仲裁,即选择依赖树中路径最短的版本; 若路径长度一致,则按照 “第一声明优先” 原则进行仲裁,即选择 POM 中最先声明的版本。 合理使用 Maven 依赖仲裁机制可以便捷的管理 Jar 包版本,而不合理的使用将导致多版本 Jar 冲突。 其次,JVM 类加载机制 决定了 Class 被加载到 JVM 的优先级, 如果同一个类出现在多个 Jar 包中,那么在 双亲委派类加载机制 下,加载该 Jar 包的类加载器层级越高,该 Jar 包越先被加载,它所包含的 Class 越先被执行,如上图所示:启动类加载器(Bootstrap ClassLoader)优先级最高,主要加载 JVM 运行时核心类,如 java.util、java.io等,这些类主要位于 $JAVA_HOME/lib/rt.jar 文件中。 扩展类加载器(Extention ClassLoader)优先级次之,主要加载 JVM 扩展类,如 swing 组件、xml 解析器等,这些类主要位于 $JAVA_HOME/lib/ext/ 目录下的 Jar 包中。 应用类加载器(Application ClassLoader),又称系统类加载器,优先级再次之,它会加载 Classpath 环境变量里定义的路径中的 Jar 包和目录,通常我们自己编写的代码或依赖的第三方 Jar 包都是由它来加载。 除了上述两种原因外,在同一个 ClassLoader 下,如果存在一个 Class 出现在不同的 Jar 包中,那么文件系统的文件加载顺序也可能会影响最终的加载结果。因此,应该尽量保证开发/测试/生产系统环境一致性。 如何解决 NoSuchMethodError 错误? 虽然抛出 NoSuchMethodError 错误的原因多种多样,但本质上是由于编译时类路径与运行时类路径不一致。因此,通用的定位思路可以归纳为以下 3 步: 1、定位异常 Class 的全限定类名与调用方,通常可以在应用日志抛出的异常堆栈中获取。如下图所示: Exception in thread "main" java.lang.NoSuchMethodError: com.xxx.AsyncAppender.append(Ljava/lang/String;)Ljava/lang/String; at com.xxx.ProvokeNoSuchMethodError.main(ProvokeNoSuchMethodError:7) at …… 2、定位异常 Class 的来源,可以通过 Arthas 等在线诊断工具反编译,如 jad com.xxx.AsyncAppender,获取该类运行时的源码、ClassLoader、Jar 包位置等信息。![]() 重新看待 Jar 包冲突问题及解决方案 http://www.yangbing.club/2017/07/15/solution-for-jar-conflicts/ 3 Steps to Fix NoSuchMethodErrors and NoSuchMethodExceptionshttps://reflectoring.io/nosuchmethod/ 作者信息: 夏明,GitHub ID @StabilityMan,花名涯海,阿里云 ARMS & EagleEye 技术专家,2016 年加入阿里巴巴,一直从事链路追踪和 APM 监控诊断领域的相关工作。 本文缩略图:icon by 轩坊 新福利: 从11月01日开始至12月06日截止,一共五周时间,每周五我会从公众号底部留言+转发+在看综合最多的读者中抽取一名读者,免费包邮送实体新书《Flink入门与实战》,留言互动起来吧~ |
CopyRight 2018-2019 实验室设备网 版权所有 |