Java中的NoClassDefFoundError报错含义解析

 更新时间:2023年11月07日 08:38:37   作者:用户bPbhIAe  
这篇文章主要为大家介绍了Java中的NoClassDefFoundError含义详解,有需要的朋友可以借鉴参考下,希望能够有所帮助

引言

半夜睡得正香的时候,突然接到警告电话,于是翻起身就打卡电脑连上环境查看是什么情况?登录上之后发现有个微服务占用的句柄数量一直在持续上涨,最终导致了微服务内存溢出挂掉了。这个微服务在运行的过程中会建立SSH连接,且之前这个微服务已经遇到过很多次类似的情况了,因此第一反应是哪里建立的连接又没有关闭。

猜肯定是猜不出来的,所以第一步肯定先看下日志里面哪里在报错,然后才好对症下药。打开日志之后,经过一番排查,发现日志里面有个很奇怪的报错,日志里面有打印NoClassDefFoundError。最开始的我对这个错误的理解是不够深刻的,我的第一反应是Class文件找不到了。于是我切换到微服务的路径下,去找这个Class文件,发现文件是存在的。于是我又想,难道是文件的权限不对?我又用了ll命令看了一下文件的权限,发现文件的权限也是对的。这个时候我有点懵了,心想完了,这道题不会呀,老师没教过呀!

没办法,为了保住工作,硬着头皮还是得上。俗话说,源码之下无秘密,只有根据堆栈找到对应的源代码进行分析,看看有什么怀疑点,然后又从网上搜索了一下NoClassDefFoundError报错的含义。经过我的深思熟虑终于发现了问题的所在。

NoClassDefFoundError的报错含义

首先需要了解一下NoClassDefFoundError的报错含义,参考why-am-i-getting-a-noclassdeffounderror-in-java这个帖子:

这段话说:NoClassDefFoundError这个报错说明之前JVM尝试过去加载这个类,但是因为某些原因失败了。现在又要使用到这个类,所以又会触发这个类的加载,但是因为之前加载这个类失败了,所以这次就不会去加载这个类了,而是直接抛出NoClassDefFoundError这个报错。

解析

如果上面这段话不好理解,可以看下面这个例子,这个例子也是来自于上面那个帖子中的回答:

public class NoClassDefFoundError {
    public static void main(String[] args) {
        try {
            // 这里尝试new一个对象,会触发SimpleCalculator的第一次加载
            SimpleCalculator calculator1 = new SimpleCalculator();
        } catch (Throwable t) {
            System.out.println(t);
        }
        // 这里又尝试new一个对象,会触发SimpleCalculator的第二次加载
        SimpleCalculator calculator2 = new SimpleCalculator();
    }
​
}
​
class SimpleCalculator {
    // 类加载的时候会初始化这个类变量,这里会抛出一个运行时异常
    static int undefined = 1 / 0;
}

从上面的运行结果可以看到,在代码的第12行抛出了NoClassDefFoundError的报错,这里也是第二次尝试加载这个类的地方。第一次尝试初始化SimpleCalculator 这个类时,因为初始化会初始化 undefined 这个变量,而这个变量在初始化过程中会抛出一个异常,满足了第一次报错的条件,然后第12行尝试第二次初始化这个类,因为第一次已经初始化失败了,这个时候 JVM 就直接抛出NoClassDefFoundError 这个报错,而不是尝试再次去加载这个类。

当然实际的代码不可能会写出这么明显的Bug,我出问题的代码大概是长如下这样:

public class XXXUtils {
    private static final XXXBean bean = SpringContextUtils.getBean(XXXBean.class);
}
​
public class SpringContextUtils {
    public static <T> T getBean(Class<T> clazz) {
        return context.getBean(clazz);
    }
}
​
public class XXXClazz {
    public static void xxxMethod() {
        XXXUtils.xxxMethod();
    }
}
​
public class Session {
    try {
        XXX conn = xxx;
    } finnaly {
        XXXUtils.closeConn(conn);
    }
}

其中的工具类 XXXUtils 实际依赖了 SpringContexUtils 来获取 Bean,也就是依赖 Spring 上下文初始化好。但是实际在服务启动的过程中又触发了 XXXClass 的 xxxMethod 调用了 XXXUtils 的方法,这个时候就会触发 XXXUtils 的类加载,也就会触发它的 bean 变量的初始化,但是由于这个时候 Spring 上下文还没有初始化好,因此调用 SpringContextUtils.getBean() 方法就会抛出异常。在第一次初始化 XXXUtils 失败之后,等到服务正常启动,其它地方再调用 XXXUtils的方法时,就会抛出 NoClassDefFoundError 错误,导致了 XXXUtils 的所有方法都不可用,而正常的SSH连接结束之后,会调用 XXXUtils.closeConn() 方法关闭连接,当然,因为这个时候方法不可用,所以连接也关不掉,最终导致了的句柄数量不断上涨,服务也挂掉了。

以上就是Java中的NoClassDefFoundError报错解析的详细内容,更多关于Java中的NoClassDefFoundError报错解析的资料请关注脚本之家其它相关文章!

相关文章

  • 使用IntelliJ IDEA搭建SSM框架的图文教程

    使用IntelliJ IDEA搭建SSM框架的图文教程

    本文通过图文并茂的形式给大家介绍了使用IntelliJ IDEA搭建SSM框架的教程,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-05-05
  • Spring的连接数据库以及JDBC模板(实例讲解)

    Spring的连接数据库以及JDBC模板(实例讲解)

    下面小编就为大家带来一篇Spring的连接数据库以及JDBC模板(实例讲解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-10-10
  • springboot应用服务启动事件的监听实现

    springboot应用服务启动事件的监听实现

    本文主要介绍了springboot应用服务启动事件的监听实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-04-04
  • Spring的Bean生命周期之BeanDefinition详解

    Spring的Bean生命周期之BeanDefinition详解

    这篇文章主要介绍了Spring的Bean生命周期之BeanDefinition详解,在spring bean创建过程 依赖 BeanDefinition 中的信息处理bean的生产,BeanDefinition 是 Spring Framework 中定义 Bean 的配置元信息接口,需要的朋友可以参考下
    2023-12-12
  • 使用jsoup解析html的table中的文本信息实例

    使用jsoup解析html的table中的文本信息实例

    今天小编就为大家分享一篇使用jsoup解析html的table中的文本信息实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-05-05
  • 通过Java 程序获取Word中指定图片的坐标位置

    通过Java 程序获取Word中指定图片的坐标位置

    本文介绍通过Java程序获取Word文档中指定图片的坐标位置,程序运行环境是jdk1.8开发环境idea,通过java程序代码给大家介绍的非常详细,需要的朋友参考下吧
    2021-05-05
  • mybatis多个区间处理方式(双foreach循环)

    mybatis多个区间处理方式(双foreach循环)

    这篇文章主要介绍了mybatis多个区间处理方式(双foreach循环),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • 解析Spring Cloud Bus消息总线

    解析Spring Cloud Bus消息总线

    这篇文章主要介绍了Spring Cloud Bus消息总线的介绍及使用,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-10-10
  • Java判断用户输入月份的季节

    Java判断用户输入月份的季节

    这篇文章主要为大家详细介绍了Java判断用户输入月份的季节,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • 详解IDEA用maven创建springMVC项目和配置

    详解IDEA用maven创建springMVC项目和配置

    本篇文章主要介绍了详解IDEA用maven创建springMVC项目和配置 ,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-09-09

最新评论