升级SpringBoot至2.7.18后触发BeanCreationException问题求助
核心原因
这个错误是Java 17模块化机制导致的:Spring Boot Actuator的TaskExecutorMetricsAutoConfiguration在收集线程池指标时,需要通过反射调用ScheduledThreadPoolExecutor的decorateTask方法,但Java 17默认禁止未命名模块(你的项目属于这类)访问java.base模块中java.util.concurrent包的非公开成员,所以触发了InaccessibleObjectException。
解决方案
添加JVM启动参数:在项目的启动配置里加上以下参数,开放对应包的反射访问权限:
--add-opens java.base/java.util.concurrent=ALL-UNNAMED如果是Maven插件启动(比如spring-boot:run),可以在pom.xml的插件配置里添加:
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <jvmArguments>--add-opens java.base/java.util.concurrent=ALL-UNNAMED</jvmArguments> </configuration> </plugin>如果是Gradle,在build.gradle里配置:
bootRun { jvmArgs = ['--add-opens', 'java.base/java.util.concurrent=ALL-UNNAMED'] }检查依赖一致性:确认项目中Spring Boot Actuator的版本和Spring Boot 2.7.18完全匹配,避免依赖冲突导致的异常。可以通过Maven的
dependency:tree或者Gradle的dependencies命令排查依赖树,确保没有低版本的actuator依赖混入。排查自定义线程池配置:如果项目里有自定义的
TaskExecutor或ScheduledThreadPoolExecutor实现,检查是否有依赖内部API的逻辑,尽量替换成Java公开API或者Spring提供的封装类,减少对非公开方法的依赖。
补充说明
Spring Boot 2.7.x对Java 17的兼容性是支持的,但部分Actuator的指标收集逻辑依赖反射访问JDK内部方法,而Java 17收紧了模块化的访问控制,所以需要显式开放权限。这个参数是临时的兼容方案,后续如果升级到Spring Boot 3.x(本身基于Java 17+设计),这类问题会更少。
内容的提问来源于stack exchange,提问作者Wei Wen

