spring+mybatis启动NoClassDefFoundError异常分析三部曲之三:改spring源码,取详细错误

简介: spring+mybatis启动NoClassDefFoundError异常分析

欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码): https://github.com/zq2599/blog_demos
  • 在上一章《spring+mybatis启动NoClassDefFoundError异常分析三部曲之二:定位错误》中,我们通过打断点的方式,在spring初始化时创建bean的位置单步执行代码,定位到了应用启动失败的原因是由于AbstractAutowireCapableBeanFactory.createBean方法被多层嵌套式调用从而导致了栈内存被耗光,抛出了StackOverflowError异常,但由于doCreateBean方法捕获异常并抛出新的异常,导致启动的输出信息中看不到原始的错误堆栈,本章我们一起来修改并编译spring源码,使得错误发生的时候及时打印出有效的堆栈信息,以便我们定位问题;
  • 关于修改和编译spring源码的方法,您可以参照《修改和编译spring源码,构建jar(spring-context-4.0.2.RELEASE)》,此处我们修改的不是spring-context,而是spring-bean,如果读者您觉得准备一个修改和编译spring-bean源码的环境太费时太麻烦,也可以从我的git上直接下载可运行的工程,地址是:git@github.com:zq2599/blog_demos.git,这里面有多个工程,本次用到的工程如下图红框所示:

这里写图片描述

  • 创建这个工程的主要步骤,在《修改和编译spring源码,构建jar(spring-context-4.0.2.RELEASE)》一文中已经说过了,为了编译通过,此处把几处重要的改动再说明一下:
  • 将官方的spring-beans-4.0.2.RELEASE.jar文件解压,在java/org/springframework/beans/factory/xml目录下,将所有的xsd文件复制到我们工程的同名目录下;
  • 工程的pom中增加插件,以便打包的时候可以复制xsd文件到jar包,如下:
<plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <configuration>
                    <archive>
                        <addMavenDescriptor>false</addMavenDescriptor>
                    </archive>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>build-helper-maven-plugin</artifactId>
                <version>1.8</version>
                <executions>
                    <execution>
                        <id>add-resource</id>
                        <phase>generate-resources</phase>
                        <goals>
                            <goal>add-resource</goal>
                        </goals>
                        <configuration>
                            <resources>
                                <resource>
                                    <directory>src/main/java</directory>
                                    <includes>
                                        <include>**/*.xsd</include>
                                    </includes>
                                </resource>
                            </resources>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
  • GroovyBeanDefinitionReader.java编译未过,本次实战我们不会涉及到Groovy相关的代码,所以此处直接将此文件中的红叉部分注释掉,修改的地方有如下三处:

这里写图片描述

这里写图片描述

这里写图片描述

  • 经过了上面的修改,我们本地的spring-bean工程应该能正常编译的构建程jar包了,开始改源码吧:
  • 根据我们之前的分析,启动失败的位置是在执行AbstractAutowireCapableBeanFactory.createBean的时候,调用populateBean方法抛出了异常,又被try catch将异常捕获处理了,如下图:

这里写图片描述

  • 所以此次改动就在这里,我们添加更详细的输出,以便在异常的时候可以看到更多的输出信息:
  • createBean方法会被反复迭代调用,如果每次抛异常都打印信息就太多了,我们不需要这么多,所以加个是否已经打印过异常的标志位,初始值是false,打印一次就改为true:
private static boolean hasErrorPrinted = false;
  • 把上面截图中的代码改成下图这样,捕获异常后,如果hasErrorPrinted为false,就把异常打印出来,并且将hasErrorPrinted改为true:

这里写图片描述

  • 修改完毕了,在工程目录下执行mvn clean package -U,执行成功后在target目录下可以生成最新的spring-beans-4.0.2.RELEASE.jar文件,复制到tomcat的webapp下的lib中替换原有文件,启动tomcat看一下,我们捕获的异常信息被完整的打印出来了,多层迭代导致的StackOverflowError,如下图:

这里写图片描述

  • 至此,spring启动异常的问题三部曲就全部结束了,除了阅读源码,debug调试,我们还尝试了修改源码,希望此系列的实战能对您今后深入学习spring有所帮助。

欢迎关注阿里云开发者社区博客:程序员欣宸

学习路上,你不孤单,欣宸原创一路相伴...
相关文章
|
3月前
|
设计模式 Java 开发者
如何快速上手【Spring AOP】?从动态代理到源码剖析(下篇)
Spring AOP的实现本质上依赖于代理模式这一经典设计模式。代理模式通过引入代理对象作为目标对象的中间层,实现了对目标对象访问的控制与增强,其核心价值在于解耦核心业务逻辑与横切关注点。在框架设计中,这种模式广泛用于实现功能扩展(如远程调用、延迟加载)、行为拦截(如权限校验、异常处理)等场景,为系统提供了更高的灵活性和可维护性。
|
5月前
|
Java 数据库连接 数据库
Spring boot 使用mybatis generator 自动生成代码插件
本文介绍了在Spring Boot项目中使用MyBatis Generator插件自动生成代码的详细步骤。首先创建一个新的Spring Boot项目,接着引入MyBatis Generator插件并配置`pom.xml`文件。然后删除默认的`application.properties`文件,创建`application.yml`进行相关配置,如设置Mapper路径和实体类包名。重点在于配置`generatorConfig.xml`文件,包括数据库驱动、连接信息、生成模型、映射文件及DAO的包名和位置。最后通过IDE配置运行插件生成代码,并在主类添加`@MapperScan`注解完成整合
936 1
Spring boot 使用mybatis generator 自动生成代码插件
|
7月前
|
前端开发 Java 物联网
智慧班牌源码,采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署
智慧班牌系统是一款基于信息化与物联网技术的校园管理工具,集成电子屏显示、人脸识别及数据交互功能,实现班级信息展示、智能考勤与家校互通。系统采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署与私有化定制。核心功能涵盖信息发布、考勤管理、教务处理及数据分析,助力校园文化建设与教学优化。其综合性和可扩展性有效打破数据孤岛,提升交互体验并降低管理成本,适用于日常教学、考试管理和应急场景,为智慧校园建设提供全面解决方案。
465 70
|
5月前
|
Java 数据库连接 API
Java 对象模型现代化实践 基于 Spring Boot 与 MyBatis Plus 的实现方案深度解析
本文介绍了基于Spring Boot与MyBatis-Plus的Java对象模型现代化实践方案。采用Spring Boot 3.1.2作为基础框架,结合MyBatis-Plus 3.5.3.1进行数据访问层实现,使用Lombok简化PO对象,MapStruct处理对象转换。文章详细讲解了数据库设计、PO对象实现、DAO层构建、业务逻辑封装以及DTO/VO转换等核心环节,提供了一个完整的现代化Java对象模型实现案例。通过分层设计和对象转换,实现了业务逻辑与数据访问的解耦,提高了代码的可维护性和扩展性。
218 1
|
4月前
|
SQL Java 数据库连接
Spring、SpringMVC 与 MyBatis 核心知识点解析
我梳理的这些内容,涵盖了 Spring、SpringMVC 和 MyBatis 的核心知识点。 在 Spring 中,我了解到 IOC 是控制反转,把对象控制权交容器;DI 是依赖注入,有三种实现方式。Bean 有五种作用域,单例 bean 的线程安全问题及自动装配方式也清晰了。事务基于数据库和 AOP,有失效场景和七种传播行为。AOP 是面向切面编程,动态代理有 JDK 和 CGLIB 两种。 SpringMVC 的 11 步执行流程我烂熟于心,还有那些常用注解的用法。 MyBatis 里,#{} 和 ${} 的区别很关键,获取主键、处理字段与属性名不匹配的方法也掌握了。多表查询、动态
150 0
|
5月前
|
SQL Java 数据库
解决Java Spring Boot应用中MyBatis-Plus查询问题的策略。
保持技能更新是侦探的重要素质。定期回顾最佳实践和新技术。比如,定期查看MyBatis-Plus的更新和社区的最佳做法,这样才能不断提升查询效率和性能。
223 1
|
7月前
|
SQL 存储 Java
Mybatis源码解析:详述初始化过程
以上就是MyBatis的初始化过程,这个过程主要包括SqlSessionFactory的创建、配置文件的解析和加载、映射文件的加载、SqlSession的创建、SQL的执行和SqlSession的关闭。这个过程涉及到了MyBatis的核心类和接口,包括SqlSessionFactory、SqlSessionFactoryBuilder、XMLConfigBuilder、XMLMapperBuilder、Configuration、SqlSession和Executor等。通过这个过程,我们可以看出MyBatis的灵活性和强大性,它可以很好地支持定制化SQL、存储过程以及高级映射,同时也避免了几
135 20
|
5月前
|
负载均衡 Java API
基于 Spring Cloud 的微服务架构分析
Spring Cloud 是一个基于 Spring Boot 的微服务框架,提供全套分布式系统解决方案。它整合了 Netflix、Zookeeper 等成熟技术,通过简化配置和开发流程,支持服务发现(Eureka)、负载均衡(Ribbon)、断路器(Hystrix)、API网关(Zuul)、配置管理(Config)等功能。此外,Spring Cloud 还兼容 Nacos、Consul、Etcd 等注册中心,满足不同场景需求。其核心组件如 Feign 和 Stream,进一步增强了服务调用与消息处理能力,为开发者提供了一站式微服务开发工具包。
593 0
|
前端开发 druid Java
SpringBoot 整合 MyBatis
文本是基于MVC前后端分离模式的一个SpringBoot整合MyBatis的项目,不过没有用到前端页面,使用了更方便的Apifox请求工具。SpringBoot+MyBatis使用起来更方便,更舒服。掌握SpingBoot整合MyBatis,要比Spring整合简单的多,少了很多繁琐的配置。......
318 0
SpringBoot 整合 MyBatis