Spring Boot使用GraalVM native-maven-plugin构建时类初始化异常
Spring Boot 3构建Native Image时Logback类初始化异常问题
我尝试参考官方文档,使用Spring Boot 3构建Native Image,但构建阶段遇到以下异常:
[INFO] [creator] [INFO] [creator] Error: Classes that should be initialized at run time got initialized during image building: [INFO] [creator] ch.qos.logback.core.status.InfoStatus was unintentionally initialized at build time. To see why ch.qos.logback.core.status.InfoStatus got initialized use --trace-class-initialization=ch.qos.logback.core.status.InfoStatus [INFO] [creator] ch.qos.logback.core.util.Loader was unintentionally initialized at build time. To see why ch.qos.logback.core.util.Loader got initialized use --trace-class-initialization=ch.qos.logback.core.util.Loader [INFO] [creator] ch.qos.logback.classic.Logger was unintentionally initialized at build time. To see why ch.qos.logback.classic.Logger got initialized use --trace-class-initialization=ch.qos.logback.classic.Logger [INFO] [creator] ch.qos.logback.core.util.StatusPrinter was unintentionally initialized at build time. To see why ch.qos.logback.core.util.StatusPrinter got initialized use --trace-class-initialization=ch.qos.logback.core.util.StatusPrinter [INFO] [creator] ch.qos.logback.classic.Level was unintentionally initialized at build time. To see why ch.qos.logback.classic.Level got initialized use --trace-class-initialization=ch.qos.logback.classic.Level [INFO] [creator] ch.qos.logback.core.status.StatusBase was unintentionally initialized at build time. To see why ch.qos.logback.core.status.StatusBase got initialized use --trace-class-initialization=ch.qos.logback.core.status.StatusBase [INFO] [creator] To see how the classes got initialized, use --trace-class-initialization=ch.qos.logback.core.status.InfoStatus,ch.qos.logback.core.util.Loader,ch.qos.logback.classic.Logger,ch.qos.logback.core.util.StatusPrinter,ch.qos.logback.classic.Level,ch.qos.logback.core.status.StatusBase [INFO] [creator] Error: Use -H:+ReportExceptionStackTraces to print stacktrace of underlying exception [INFO] [creator] -------------------------------------------------------------------------------- [INFO] [creator] 1.6s (3.8% of total time) in 25 GCs | Peak RSS: 5.87GB | CPU load: 4.39
参考类似问题的解决方案,我对Maven插件做了如下配置,但没有生效:
<plugin> <groupId>org.graalvm.buildtools</groupId> <artifactId>native-maven-plugin</artifactId> <configuration> <classesDirectory>${project.build.outputDirectory}</classesDirectory> <metadataRepository> <enabled>true</enabled> </metadataRepository> <requiredVersion>22.3</requiredVersion> <verbose>true</verbose> <!-- note: I've tried several combinations of combine.children here, including omitting it entirely, none seem to have any effect --> <buildArgs> <arg>--verbose</arg> <arg>--initialize-at-build-time=org.slf4j.LoggerFactory,ch.qos.logback</arg> <arg>--trace-class-initialization=ch.qos.logback.core.status.InfoStatus,ch.qos.logback.core.util.StatusPrinter,ch.qos.logback.classic.Level,ch.qos.logback.classic.Logger,ch.qos.logback.core.util.Loader,ch.qos.logback.core.status.StatusBase</arg> </buildArgs> </configuration> </plugin>
我的POM继承自spring-boot-starter-parent:3.0.2:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.0.2</version> <relativePath/> <!-- lookup parent from repository --> </parent>
我试过多种配置组合,异常依然存在。另外添加-H:+ReportExceptionStackTraces也没效果,怀疑参数传递方式有误,请问如何正确配置Maven插件来消除这些错误?
解决方案
1. 修正参数传递逻辑:通过Spring Boot插件配置Native参数
Spring Boot 3中,native-maven-plugin由spring-boot-maven-plugin间接调用,直接配置前者的buildArgs不会生效。正确做法是在Spring Boot插件中传递Native Image参数:
<plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <image> <env> <BP_NATIVE_IMAGE_BUILD_ARGUMENTS> --initialize-at-run-time=ch.qos.logback.core.status.InfoStatus,ch.qos.logback.core.util.Loader,ch.qos.logback.classic.Logger,ch.qos.logback.core.util.StatusPrinter,ch.qos.logback.classic.Level,ch.qos.logback.core.status.StatusBase -H:+ReportExceptionStackTraces </BP_NATIVE_IMAGE_BUILD_ARGUMENTS> </env> </image> </configuration> </plugin>
2. 调整初始化策略:不要反向配置
错误提示明确说明这些类应该在运行时初始化,却被提前到构建阶段,你之前配置的--initialize-at-build-time是反向操作,必须改为--initialize-at-run-time,强制这些类延迟到运行时再初始化。
3. 升级Spring Boot版本(推荐)
Spring Boot 3.0.2存在部分Native Image兼容性问题,升级到3.0.5及以上版本后,官方已修复大量Logback相关的初始化问题,可能无需额外配置即可解决该异常。
4. 检查自定义Logback代码
如果项目中有自定义Logback配置或静态代码块中调用Logback API的逻辑,会在构建Native Image时触发类初始化。需要将这类代码重构为运行时初始化,比如放到@PostConstruct方法中。
内容的提问来源于stack exchange,提问作者Marty Pitt
相关产品推荐
相关产品推荐

