spring-boot-devtools 热部署造成的类加载问题
如果你的项目在IDE中出现了像下面这些奇怪的错误
-
object is not an instance of declaring class // 对象不是声明类的实例
-
java.lang.ClassCastException: com.example.A cannot be cast to com.example.A // A类无法转换成A类
-
又或者是全局静态变量莫名变为了null,前一秒才看到静态变量被赋值了,下一秒获取的时候就出现了空指针异常。
而且这些错误在使用 java -jar xx.jar
还不会出现,那么很有可能是因为你是用了 spring-boot-devtools
依赖
官方描述:
By default, any open project in your IDE will be loaded using the “restart” classloader, and any regular .jar file will be loaded using the “base” classloader. If you work on a multi-module project, and not each module is imported into your IDE, you may need to customize things. To do this you can create a META-INF/spring-devtools.properties file.
默认情况下,IDE中任何打开的项目都将使用 restart classloader加载,而任何常规的.jar文件都将使用 base classloader加载。如果你在一个多模块项目上工作,并且不是每个模块都被导入到你的IDE中,你可能需要自定义一些东西。要做到这一点,你可以创建一个META-INF/spring-devtools.properties文件。
原因:
- 项目中的java文件,因其可能随时被修改,为了热部署及时生效,这些java文件对于的类会使用
org.springframework.boot.devtools.restart.classloader.RestartClassLoader
类加载器进行加载。如果同时有jar中的一些代码使用了反射等技术使用我们项目的类时,就会使用AppClassLoade
进行加载。造成本该是一个类的类,因被不同的类加载器加载而同时出现两个不同的类,而出现上面的错误。
解决办法:
-
不使用
spring-boot-devtools
-
在resource下创建META-INF/spring-devtools.properties
restart.exclude.companycommonlibs=排除的jar包 restart.include.projectcommon=包含的jar包 // 使用restartClassLoader加载
下面是我解决这个问题的实际步骤
下面是我工作中遇到这个问题的解决思路。我的项目中出现了1和3这样的问题,我的项目中有一个类
AppContext
类,其中有一个全局静态变量context
-
使用 debug 断点,在 context 被赋初始值的的地方的下一行,暂停程序,使用
jmap -dump:live,format=b,file=heap-dump-1.bin pid
导出程序的堆文件,在使用jhat heap-dump.bin
分析堆文件,此时 context 不为null -
程序继续运行,再次导堆文件进行分析,这时 context 变为了 null ,同时发现 ClassLoader 发生了变化
-
基本确认是因为ClassLoader变化导致的问题,再次使用
java -jar xx.jar
运行分析,感觉 RestartClassLoader 有些特殊,然后百度搜索 restartClassLoader 解决了问题
参考资料:
本文转自 https://www.cnblogs.com/zerolinck/p/15412795.html,如有侵权,请联系删除。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)