java noSuchMethodError 产生原因以及解决方案
表象原因
A.class 调用的 B.methodX 。
运行时候的 加载到B 的 class 中methodX 可能存在的情况
methodX 方法的确不存在
methodX 方法签名和 A.class调用的 B.methodX签名不一致
根本原因
编译时 B 的版本和 运行时 B 的版本不一致
运行时 B 的 jar 包在 classPath 中有多个,jvm 加载到错误的 jar 包
不同 classLoader 加载到B 不同版本的类。
子 classLoader 在委托父类的时候加载的时候,获取到了到父 classLoder 加载的B.class
分类
jvm 中的类
- 原因
- 通常是写代码的时候,以及编译的时候用的 jdk 版本比较高,但是运行时候用的 jdk 版本较低
- 解决方案
- 确认运行环境 jdk 版本是否正确
公司项目 jar 包中的类
- 原因
引入低版本的 jar 包
引入的 snapshot 版本的包不是最新的
- 解决方案
修改依赖版本的 jar 包 为正确版本
snapshot 版本包不对
- 执行 mvn 命令时加-U 参数。mvn clean package/install -U
不建议
其他环境编译的时候,也同样要加参数
- maven 配置
settings.xml 中配置
<profile>
<id>nexus</id>
<repositories>
<repository>
<id>central</id>
<url>http://central</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</repository>
</repositories>
</profile>
不建议使用
其他人也要修改
- 项目中 pom.xml中配置
- 建议使用
项目中依赖第三方 jar 包中的类
- 原因
引入低版本的 jar 包
引入多个 jar 包,但是加载到了错误版本的 jar 包
子类 classLoader 加载类时候,委托父类 classLoader 加载到低版本的 classLoader
- 定位方式
1.先通过-verbose:class 查找加载到哪个类
2.通过 jvm 类加载器结构判断,是那个类加载器加载到这个类 然后想办法解决
- 解决方案
修改为正确版本的 jar 包
通过 maven 命令选择正确的 jar 包
- 第一步:列出依赖的 jar 包
mvn dependency:list命令可以列出当前所有依赖(包括直接和传递)的列表,以及范围。
mvn dependency:tree命令可以层次化的列出所有依赖,可以从书中看出依赖传递的关系。
- 第二步:利用 exclude 排除不需要的依赖
- 利用 jvm 命令 查看加载了哪个 jar 包 导致的错误
- -verbose:class