4

NoClassDefFoundError的两种情况 - daheww

 1 year ago
source link: https://www.cnblogs.com/daheww/p/17046322.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

ClassNotFoundException vs. NoClassDefFoundError

ClassNotFoundException

关于ClassNotFoundException发生的原因,这篇文章ClassNotFoundException vs. NoClassDefFoundError写得很清晰。

1555060-20230112113635020-1118651843.png

总的来说就是:

  • 需要加载的类在classpath中找不到,一般这种情况都是使用类似Class.forName("oracle.jdbc.driver.OracleDriver")的方式获取类不存在

解决问题的思路:

  • 排查导入的jar包,对于使用maven的程序来说,就是去检查pom.xml中的配置
  • 如果配置的有的话就去看一下maven实际导入的jar包中,对应路径下是否有这个类
1555060-20230112114044731-1354223351.png

NoClassDefFoundError

关于ClassNotFoundException发生的原因,这篇文章ClassNotFoundException vs. NoClassDefFoundError写得很清晰。

1555060-20230112115656272-170165461.png

总的来说就是:

  • 这个类编译时有,但是运行时没有

解决问题的思路:

  • 缩小范围,确定是哪个类的definition找不到。确定原因后再定解决办法

以下我演示两个NoClassDefFoundError的情景。

NoClassDefFoundError的情景

B项目依赖了A项目,并配置<optional>为true。

<dependency> <groupId>com.example</groupId> <artifactId>a</artifactId> <version>0.0.1-SNAPSHOT</version> <optional>true</optional></dependency>

C项目依赖了B项目,并调用B项目中的某个方法,该方法调用了A项目的代码。

此时会发生NoClassDefFoundError报错。

  • B项目依赖了A项目
  • C项目依赖了B项目
  • C项目也依赖了A项目

C项目调用B项目中的某个方法,该方法调用了A项目xxx类的代码。

正常来说这个过程是没问题的,但是B项目、C项目使用的A项目版本不同。
A项目xxx类在这两个版本的包路径不同。

这个是我用hutool的过程中发现的一个问题,NetUtil在项目不同版本中包位置不一样。

1555060-20230112123937781-350135292.png

Note.
需要注意的一点是,如上两个情景,虽然都是因为少了A项目的代码,所以一般堆栈信息会直接报错是找不到A项目某个类的definition。
但如果使用A项目的代码是在B项目的static块中(<cinit>方法执行失败),那么此时会报的是找不到B项目这个类的definition。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK