I have a basic Spring MVC app where its only function is to make a call with WebClient when it receives an HTTP request. I wanted to deploy it as a native image, but encountered the following error:

Error: Classes that should be initialized at run time got initialized during image building:
 org.slf4j.LoggerFactory was unintentionally initialized at build time. io.netty.channel.AbstractChannel caused initialization of this class with the following trace:
        at org.slf4j.LoggerFactory.<clinit>(LoggerFactory.java:94)
        at io.netty.util.internal.logging.Slf4JLoggerFactory.<init>(Slf4JLoggerFactory.java:42)
        at io.netty.util.internal.logging.Slf4JLoggerFactory$NopInstanceHolder.<clinit>(Slf4JLoggerFactory.java:63)
        at io.netty.util.internal.logging.Slf4JLoggerFactory.getInstanceWithNopCheck(Slf4JLoggerFactory.java:59)
        at io.netty.util.internal.logging.InternalLoggerFactory.useSlf4JLoggerFactory(InternalLoggerFactory.java:62)
        at io.netty.util.internal.logging.InternalLoggerFactory.newDefaultFactory(InternalLoggerFactory.java:42)
        at io.netty.util.internal.logging.InternalLoggerFactory.getDefaultFactory(InternalLoggerFactory.java:111)
        at io.netty.util.internal.logging.InternalLoggerFactory.getInstance(InternalLoggerFactory.java:134)
        at io.netty.util.internal.logging.InternalLoggerFactory.getInstance(InternalLoggerFactory.java:127)
        at io.netty.channel.AbstractChannel.<clinit>(AbstractChannel.java:45)

Spring Boot 3.0.1

GraalVM 22.3.0 Java 17 CE Java version info: '17.0.5+8-jvmci-22.3-b08' C compiler: gcc (linux, x86_64, 9.4.0) Garbage collector: Serial GC

Using GraalVM native-image directly via mvn native:compile -Pnative -DskipTests

I've narrowed it down, and it happens in a bare-bones Spring Boot 3.0.1 project with only spring-boot-starter-webflux in use. Here is the example project: https://github.com/matthenry87/native-image-webflux-bug

When I change spring-boot-starter-webflux -> spring-boot-starter it builds fine.

Comment From: ashok2ashok

@matthenry87 - Can you try --initialize-at-build-time to exclude the classes? That should help it.

Example given below for slf4j with logback implementation:

--initialize-at-build-time=\
org.slf4j.impl.StaticLoggerBinder\
,org.slf4j.LoggerFactory\
,ch.qos.logback.classic.Logger\
,ch.qos.logback.core.spi.AppenderAttachableImpl\
,ch.qos.logback.core.status.StatusBase\
,ch.qos.logback.classic.Level\
,ch.qos.logback.core.status.InfoStatus\
,ch.qos.logback.classic.PatternLayout\
,ch.qos.logback.core.CoreConstants

Comment From: matthenry87

@matthenry87 - Can you try --initialize-at-build-time to exclude the classes? That should help it.

Example given below for slf4j with logback implementation:

--initialize-at-build-time=\ org.slf4j.impl.StaticLoggerBinder\ ,org.slf4j.LoggerFactory\ ,ch.qos.logback.classic.Logger\ ,ch.qos.logback.core.spi.AppenderAttachableImpl\ ,ch.qos.logback.core.status.StatusBase\ ,ch.qos.logback.classic.Level\ ,ch.qos.logback.core.status.InfoStatus\ ,ch.qos.logback.classic.PatternLayout\ ,ch.qos.logback.core.CoreConstants

Tried this, and then it complains about

io.netty.util.AbstractReferenceCounted, ch.qos.logback.core.util.StatusPrinter, ch.qos.logback.core.util.Loader, org.slf4j.MDC, ch.qos.logback.core.pattern.parser.Parser

being built at build time unexpectedly.

And the blocker here:

io.netty.util.AbstractReferenceCounted the class was requested to be initialized at run time (from 'META-INF/native-image/io.netty/netty-common/native-image.properties' in 'file:///mnt/c/Users/Matt.Henry/.m2/repository/io/netty/netty-common/4.1.86.Final/netty-common-4.1.86.Final.jar' with 'io.netty.util.AbstractReferenceCounted').

It doesn't let me switch that to build time:

Error: Incompatible change of initialization policy for io.netty.util.AbstractReferenceCounted: trying to change RUN_TIME from 'META-INF/native-image/io.netty/netty-common/native-image.properties' in 'file:///mnt/c/Users/Matt.Henry/.m2/repository/io/netty/netty-common/4.1.86.Final/netty-common-4.1.86.Final.jar' with 'io.netty.util.AbstractReferenceCounted' to BUILD_TIME from command line with 'io.netty.util.AbstractReferenceCounted'

Comment From: matthenry87

This works when I use real Ubuntu and not WSL on my machine. Odd.

Comment From: sshemirani

So what was the solution to this issue? I build with spring boot 3 and Buildpack and I get the same exception.