现网有一个程序,之前是正常的,替换包以后,发现出现这个异常,写一下排查过程
过程
- 这个类、这个程序在本地的IDEA中没有问题,编译是正常的,怀疑是正式环境和测试环境有区别。
- 仔细查看日志,查找问题点。结果发现在一堆报错的中间,有一个不同的报错,是找不到某个类。
- 在IDEA中查看找不到的这个类,发现这个类GSON,版本是2.8.5,查看现网。因为现网的依赖库都是放在jar包外的lib目录下,进入lib目录,发现GSON包版本是2.2.4。
- 将gson包替换后重启,问题解决。
反思
发生异常的类用到了gson的静态成员变量,但是这个static修饰的成员变量有异常的时候,就会导致class文件的初始化异常,因为static修饰的成员变量、方法、静态块都是初始化时候执行的。
所以同理,我网上看到一个例子,在代码的静态块中加载配置文件时,如果配置文件不存在,没有捕获异常,就会出现这种情况。
如:
public class Test {
static {
File file = new File("/home/test.properties");
...
}
}
ClassNotFound 和 NoClassDefFound 的区别
以下是我的理解:
ClassNotFound是编译的时候找不到类,这种情况一般都是直接缺少了依赖包,找到依赖包放上去就好。
NoClassDefFound是运行的时候找不到类,这种情况一般是编译环境通过的class文件,在别的环境中准备运行是,因为某种意外(异常)导致类的加载失败或者读取失败,最终导致找不到类。出现NoClassDefFound异常的时候,主要的排查方法是查看日志,找到出现这个异常之前是否出现了别的异常导致了这个问题。