Search code examples
spring-bootgraalvmgraalvm-native-image

Spring Boot / GraalVM native-maven-plugin failing with runtime vs build-time class initialization


I'm trying to build a native image using Spring Boot 3, referring to these docs.

I'm hitting the below exception at build time:

[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

Based on other similar questions, I've configured the maven plugin as follows, but it hasn't had any effect:

<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>

My POM inherits from 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>

I've tried multiple different configurations, but I can't seem to change the exception.

I note that adding -H:+ReportExceptionStackTraces had no impact, so I'm wondering if I'm passing these args incorrectly?

How do I correctly configure the maven plugin to remove these errors?


Solution

  • After lots of digging, the specific issue turns out to be an old slf4j driver in a transient dependency (snowflake-jdbc), which is shaded in.

    Here's the relevant issue.

    After removing the dependency on snowflake, native builds worked again.