spring-boot icon indicating copy to clipboard operation
spring-boot copied to clipboard

Support using Log4j2 in a GraalVM native image

Open msosa opened this issue 2 years ago • 6 comments

Starting a native image built with bootBuildImage and org.springframework.boot:spring-boot-starter-log4j2 throws an error on startup

Exception in thread "main" java.lang.ExceptionInInitializerError
        at org.apache.logging.slf4j.Log4jMarkerFactory.<clinit>(Log4jMarkerFactory.java:36)
        at org.apache.logging.slf4j.SLF4JServiceProvider.initialize(SLF4JServiceProvider.java:53)
        at org.slf4j.LoggerFactory.bind(LoggerFactory.java:183)
        at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:170)
        at org.slf4j.LoggerFactory.getProvider(LoggerFactory.java:455)
        at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:441)
        at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:390)
        at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:416)
        at com.example.log4j2native.Log4j2NativeApplicationKt.<clinit>(Log4j2NativeApplication.kt:10)
Caused by: java.lang.IllegalStateException: java.lang.InstantiationException: org.apache.logging.log4j.message.DefaultFlowMessageFactory
        at org.apache.logging.log4j.spi.AbstractLogger.createDefaultFlowMessageFactory(AbstractLogger.java:242)
        at org.apache.logging.log4j.spi.AbstractLogger.<init>(AbstractLogger.java:141)
        at org.apache.logging.log4j.status.StatusLogger.<init>(StatusLogger.java:141)
        at org.apache.logging.log4j.status.StatusLogger.<clinit>(StatusLogger.java:91)
        ... 9 more
Caused by: java.lang.InstantiationException: org.apache.logging.log4j.message.DefaultFlowMessageFactory
        at [email protected]/java.lang.Class.newInstance(DynamicHub.java:639)
        at org.apache.logging.log4j.spi.AbstractLogger.createDefaultFlowMessageFactory(AbstractLogger.java:240)
        ... 12 more
Caused by: java.lang.NoSuchMethodException: org.apache.logging.log4j.message.DefaultFlowMessageFactory.<init>()
        at [email protected]/java.lang.Class.checkMethod(DynamicHub.java:1040)
        at [email protected]/java.lang.Class.getConstructor0(DynamicHub.java:1206)
        at [email protected]/java.lang.Class.newInstance(DynamicHub.java:626)
        ... 13 more

I did try adding some hints to help make it through these errors

hints.reflection().registerType(TypeReference.of("org.apache.logging.log4j.message.DefaultFlowMessageFactory"), MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS)
hints.reflection().registerType(TypeReference.of("org.apache.logging.log4j.message.ParameterizedMessageFactory"), MemberCategory.INVOKE_PUBLIC_CONSTRUCTORS)

But I couldn't fix the error after these were added.

Here is a repo to help reproduce the error(without the hints): https://github.com/msosa/log4j2-native

msosa avatar Aug 31 '23 02:08 msosa

Log4j2 isn't supported in a native image. It requires extensive changes to Log4j2 for it to work. Please see LOG4J2-2649 for further details.

wilkinsona avatar Aug 31 '23 07:08 wilkinsona

@wilkinsona I have log4j2 on version [3.0.5,3.1.0[ and seems to work:

+--- org.springframework.boot:spring-boot-starter-log4j2 -> 3.0.9
|    +--- org.apache.logging.log4j:log4j-slf4j2-impl:2.19.0
|    |    +--- org.slf4j:slf4j-api:2.0.0 -> 2.0.7
|    |    \--- org.apache.logging.log4j:log4j-api:2.19.0
|    +--- org.apache.logging.log4j:log4j-core:2.19.0
|    |    \--- org.apache.logging.log4j:log4j-api:2.19.0
|    \--- org.apache.logging.log4j:log4j-jul:2.19.0
|         \--- org.apache.logging.log4j:log4j-api:2.19.0

I just have that error when I bump to spring boot to 3.1+. That pull log4j2 2.20.0.

luisalves00 avatar Sep 14 '23 15:09 luisalves00

@wilkinsona I have log4j2 on version [3.0.5,3.1.0[ and seems to work:

+--- org.springframework.boot:spring-boot-starter-log4j2 -> 3.0.9
|    +--- org.apache.logging.log4j:log4j-slf4j2-impl:2.19.0
|    |    +--- org.slf4j:slf4j-api:2.0.0 -> 2.0.7
|    |    \--- org.apache.logging.log4j:log4j-api:2.19.0
|    +--- org.apache.logging.log4j:log4j-core:2.19.0
|    |    \--- org.apache.logging.log4j:log4j-api:2.19.0
|    \--- org.apache.logging.log4j:log4j-jul:2.19.0
|         \--- org.apache.logging.log4j:log4j-api:2.19.0

I just have that error when I bump to spring boot to 3.1+. That pull log4j2 2.20.0.

I use springboot3.3.2 with log4j 2.23 but failed.

davelet avatar Aug 02 '24 09:08 davelet

Log4j2 isn't supported in a native image. It requires extensive changes to Log4j2 for it to work. Please see LOG4J2-2649 for further details.

@wilkinsona since it be resolved now, maybe we shall take some actions too...

https://github.com/apache/logging-log4j2/issues/2831

Application run failed
java.lang.IllegalStateException: java.lang.IllegalStateException: Could not initialize Log4J2 logging from classpath:org/springframework/boot/logging/log4j2/log4j2.xml
        at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:347)
        at org.springframework.boot.context.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:298)
        at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:246)
        at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:223)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:185)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:178)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:156)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:138)
        at org.springframework.boot.context.event.EventPublishingRunListener.multicastInitialEvent(EventPublishingRunListener.java:136)
        at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:81)
        at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$2(SpringApplicationRunListeners.java:64)
        at [email protected]/java.lang.Iterable.forEach(Iterable.java:75)
        at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:118)
        at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:112)
        at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:63)
        at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:370)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:330)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352)
        at com.sangfor.gop.gop_auth.GopAuthApplication.main(GopAuthApplication.java:10)
        at [email protected]/java.lang.invoke.LambdaForm$DMH/sa346b79c.invokeStaticInit(LambdaForm$DMH)
Caused by: java.lang.IllegalStateException: Could not initialize Log4J2 logging from classpath:org/springframework/boot/logging/log4j2/log4j2.xml
        at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.loadConfiguration(Log4J2LoggingSystem.java:275)
        at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.load(Log4J2LoggingSystem.java:244)
        at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.loadDefaults(Log4J2LoggingSystem.java:230)
        at org.springframework.boot.logging.AbstractLoggingSystem.initializeWithConventions(AbstractLoggingSystem.java:84)
        at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:61)
        at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.initialize(Log4J2LoggingSystem.java:223)
        at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:332)
        ... 20 more
Caused by: java.io.FileNotFoundException: class path resource [org/springframework/boot/logging/log4j2/log4j2.xml] cannot be resolved to URL because it does not exist
        at org.springframework.core.io.ClassPathResource.getURL(ClassPathResource.java:230)
        at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.getConfigurationSource(Log4J2LoggingSystem.java:289)
        at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.load(Log4J2LoggingSystem.java:281)
        at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.loadConfiguration(Log4J2LoggingSystem.java:266)
        ... 26 more

XenoAmess avatar Oct 16 '24 14:10 XenoAmess

Thanks for the nudge, @XenoAmess. It looks like the necessary changes are only available in 2.25 that has not yet been released. I'll re-open this so that we can investigate supporting Log4j2 once we've upgraded to 2.25 which is likely to be Spring Boot 3.5 at this point as we're nearing the end of the development cycle for 3.4.

In the meantime, you may be able to get things to work by adding some metadata to tell Graal to include org/springframework/boot/logging/log4j2/log4j2.xml in the native image.

wilkinsona avatar Oct 16 '24 14:10 wilkinsona

In the meantime, you may be able to get things to work by adding some metadata to tell Graal to include org/springframework/boot/logging/log4j2/log4j2.xml in the native image.

yes I'm trying it this way and see if there be other troubles in it. would report you when I finish this learning.

XenoAmess avatar Oct 16 '24 14:10 XenoAmess

@XenoAmess Any progress?

quaff avatar Dec 12 '24 07:12 quaff

@XenoAmess Any progress?

not find any problem running with snapshot of log4j2 2.25.0-SNAPSHOT with spring-boot 3.3.4 it works smothly(smother than quite some other libs actually!) we just made a internal thirdparty-fork in our company and use it...not encounter any problem yet. well maybe a reason be we use metadataCopy with native-maven-plugin and get a 80%+ code coverage, which of course covers all usecases we have to log4j... but it works well without problem for my situation, so me be satisfied. thanks for your carefulness.

XenoAmess avatar Dec 12 '24 09:12 XenoAmess

Does it mean Spring Boot supports log4j2 2.25.0-SNAPSHOT out-of-box now?

quaff avatar Dec 13 '24 01:12 quaff

Does it mean Spring Boot supports log4j2 2.25.0-SNAPSHOT out-of-box now?

I don't know if it be officially declaired supported, but at least it works good on my situation...

XenoAmess avatar Dec 13 '24 05:12 XenoAmess

Does it mean Spring Boot supports log4j2 2.25.0-SNAPSHOT out-of-box now?

No.

wilkinsona avatar Dec 13 '24 09:12 wilkinsona

I register my customized log4j configuration file:

hints.resources().registerPattern("log4j2-demo.xml");

exception raised:

Logging system failed to initialize using configuration from 'classpath:log4j2-demo.xml'
java.lang.IllegalStateException: Could not initialize Log4J2 logging from classpath:log4j2-demo.xml
        at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.loadConfiguration(Log4J2LoggingSystem.java:273)
        at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.load(Log4J2LoggingSystem.java:242)
        at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.loadConfiguration(Log4J2LoggingSystem.java:236)
        at org.springframework.boot.logging.AbstractLoggingSystem.initializeWithSpecificConfig(AbstractLoggingSystem.java:67)
        at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:58)
        at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.initialize(Log4J2LoggingSystem.java:223)
        at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:335)
        at org.springframework.boot.context.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:298)
        at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:246)
        at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:223)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:185)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:178)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:156)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:138)
        at org.springframework.boot.context.event.EventPublishingRunListener.multicastInitialEvent(EventPublishingRunListener.java:136)
        at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:81)
        at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$2(SpringApplicationRunListeners.java:64)
        at [email protected]/java.lang.Iterable.forEach(Iterable.java:75)
        at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:118)
        at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:112)
        at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:63)
        at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:353)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:313)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350)
        at io.example.showcase.MainApplication.main(MainApplication.java:19)
Caused by: java.net.ProtocolException: Protocol resource has not been enabled as an allowed protocol
        at org.apache.logging.log4j.core.net.UrlConnectionFactory.createConnection(UrlConnectionFactory.java:79)
        at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.getConfigurationSource(Log4J2LoggingSystem.java:292)
        at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.load(Log4J2LoggingSystem.java:279)
        at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.loadConfiguration(Log4J2LoggingSystem.java:264)
        ... 27 more

The url protocol is jar:file when run in JVM, don't know what is it in native mode. Is there anyway to work around?

quaff avatar Dec 16 '24 04:12 quaff

Please check https://logging.staged.apache.org/log4j/2.x/graalvm.html

barbarosalp avatar May 06 '25 10:05 barbarosalp

Regarding Log4J 2.25.0: #46035.

ianbrandt avatar Jun 19 '25 17:06 ianbrandt

I register my customized log4j configuration file:

hints.resources().registerPattern("log4j2-demo.xml"); exception raised:

Logging system failed to initialize using configuration from 'classpath:log4j2-demo.xml'
java.lang.IllegalStateException: Could not initialize Log4J2 logging from classpath:log4j2-demo.xml
        at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.loadConfiguration(Log4J2LoggingSystem.java:273)
        at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.load(Log4J2LoggingSystem.java:242)
        at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.loadConfiguration(Log4J2LoggingSystem.java:236)
        at org.springframework.boot.logging.AbstractLoggingSystem.initializeWithSpecificConfig(AbstractLoggingSystem.java:67)
        at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:58)
        at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.initialize(Log4J2LoggingSystem.java:223)
        at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:335)
        at org.springframework.boot.context.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:298)
        at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:246)
        at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:223)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:185)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:178)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:156)
        at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:138)
        at org.springframework.boot.context.event.EventPublishingRunListener.multicastInitialEvent(EventPublishingRunListener.java:136)
        at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:81)
        at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$2(SpringApplicationRunListeners.java:64)
        at [email protected]/java.lang.Iterable.forEach(Iterable.java:75)
        at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:118)
        at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:112)
        at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:63)
        at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:353)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:313)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1361)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1350)
        at io.example.showcase.MainApplication.main(MainApplication.java:19)
Caused by: java.net.ProtocolException: Protocol resource has not been enabled as an allowed protocol
        at org.apache.logging.log4j.core.net.UrlConnectionFactory.createConnection(UrlConnectionFactory.java:79)
        at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.getConfigurationSource(Log4J2LoggingSystem.java:292)
        at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.load(Log4J2LoggingSystem.java:279)
        at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.loadConfiguration(Log4J2LoggingSystem.java:264)
        ... 27 more

The url protocol is jar:file when run in JVM, don't know what is it in native mode. Is there anyway to work around?

@quaff Set the value of this environment variable equal to resource org.apache.logging.log4j.core.net.UrlConnectionFactory#ALLOWED_PROTOCOLS

example in windows set log4j2.Configuration.allowedProtocols=resource.

I'm not sure if this is a standard practice. If it requires setting an environment variable to work, it suggests that Log4j2's support for GraalVM is not out-of-the-box. However, it does solve the problem for now.

EkkoWH avatar Jun 30 '25 02:06 EkkoWH

Does it mean Spring Boot supports log4j2 2.25.0-SNAPSHOT out-of-box now?

Even if Log4j Core provides out-of-the-box GraalVM support for most applications with the release of version 2.25.0, a few integration issues with Spring Boot remain that require additional configuration:

  1. Spring Boot Reconfiguration (see apache/logging-log4j2#3770 and #46035): This issue prevents Spring Boot from reconfiguring Log4j Core correctly. It is expected to be fixed in the upcoming Log4j 2.25.1 release.

  2. Spring Boot Configuration Files in Classpath (see apache/logging-log4j2#3790): Spring Boot’s configuration files, such as log4j2-spring.xml, require a custom value for log4j2.configurationAllowedProtocols that includes the resource protocol. To fix this, you can set it in your application.yml like so:

    log4j2:
      configuration:
        allowed-protocols: "file, https, jar, resource"
    

    This issue will also be addressed in the upcoming Log4j 2.25.1 release.

  3. Spring Boot Default Configuration Files (see #42273): Based on my tests, Spring Boot does not automatically include entries for its default configuration files—such as log4j2.xml and log4j2-file.xml in the org/springframework/boot/logging/log4j2 folder, and log4j2.springboot in the classpath root—into the GraalVM metadata. To use these configurations, you'll need to manually add them to the resource-config.json file. While I’m not fully familiar with how Spring Boot generates GraalVM metadata, this appears to be a limitation of the AOT (Ahead-of-Time) compiler plugin.

  4. Official Support: As highlighted in this issue, Log4j 2 is not officially supported by Spring Boot with GraalVM. Once Log4j 2.25.1 is released, I’ll consider opening an issue to address this gap in official support.

Key Differences Between Logback and Log4j Core with GraalVM:

Note that there are key differences in the way Logback and Log4j Core are supported in Spring Boot.

  • Logback: Logback is mostly feature-stable, with minimal changes expected between releases. The GraalVM metadata is mostly maintained manually by the Spring Boot team (e.g., see reflect-config.json for Logback).

  • Log4j Core: Log4j Core is actively developed and has a major version release (3.x) planned by the end of summer. GraalVM support for Log4j Core in Spring Boot requires closer collaboration between the teams compared to Logback, as the metadata is embedded in the log4j-core JAR itself and not directly maintained by the Spring Boot team.

ppkarwasz avatar Jul 01 '25 14:07 ppkarwasz

@wilkinsona,

Since 4.0.0-RC1 uses Log4j Core 2.25.0 and #46410 provides the missing Spring Boot bits, should this issue be closed as completed?

ppkarwasz avatar Nov 06 '25 15:11 ppkarwasz

I think it can, thanks @ppkarwasz. We can reopen if @wilkinsona disagrees.

philwebb avatar Nov 06 '25 18:11 philwebb

I'm going to re-open this as I don't think anyone has tested it, on our side at least. There's also some documentation to be updated, including this section of the wiki.

wilkinsona avatar Nov 07 '25 07:11 wilkinsona

The basics seem to work, but a native image produces an ugly exception very early on in its startup:

2025-11-07T14:11:36.097878Z main ERROR Unable to invoke factory method in class org.apache.logging.log4j.core.filter.ThresholdFilter for element ThresholdFilter: java.lang.IllegalStateException: No factory method found for class org.apache.logging.log4j.core.filter.ThresholdFilter
java.lang.IllegalStateException: No factory method found for class org.apache.logging.log4j.core.filter.ThresholdFilter
	at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.findFactoryMethod(PluginBuilder.java:268)
	at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:140)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:1206)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:1125)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:1117)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:1117)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:1117)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:715)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.initialize(AbstractConfiguration.java:271)
	at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:324)
	at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:697)
	at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:812)
	at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.reconfigure(Log4J2LoggingSystem.java:298)
	at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.load(Log4J2LoggingSystem.java:275)
	at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.loadDefaults(Log4J2LoggingSystem.java:261)
	at org.springframework.boot.logging.AbstractLoggingSystem.initializeWithConventions(AbstractLoggingSystem.java:89)
	at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:65)
	at org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.initialize(Log4J2LoggingSystem.java:254)
	at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:337)
	at org.springframework.boot.context.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:302)
	at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:248)
	at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:225)
	at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:180)
	at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:173)
	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:151)
	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:133)
	at org.springframework.boot.context.event.EventPublishingRunListener.multicastInitialEvent(EventPublishingRunListener.java:137)
	at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:82)
	at org.springframework.boot.SpringApplicationRunListeners.lambda$environmentPrepared$0(SpringApplicationRunListeners.java:66)
	at java.base@25/java.util.ImmutableCollections$List12.forEach(ImmutableCollections.java:681)
	at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:123)
	at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:117)
	at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:65)
	at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:356)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:316)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1374)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363)
	at com.example.log4j2.Log4j2Application.main(Log4j2Application.java:26)
	at java.base@25/java.lang.invoke.LambdaForm$DMH/sa346b79c.invokeStaticInit(LambdaForm$DMH)

2025-11-07T14:11:36.098271Z main ERROR Null object returned for ThresholdFilter in Filters.

@ppkarwasz this looks like a Log4j2 bug to me due to missing reflection hints for org.apache.logging.log4j.core.filter.ThresholdFilter. WDYT?

wilkinsona avatar Nov 07 '25 14:11 wilkinsona

@wilkinsona,

Yes, it is a bug in the reachability metadata generated by Log4j. You can follow it under apache/logging-log4j2#3871, but I didn't have the time to look at it yet.

ppkarwasz avatar Nov 12 '25 09:11 ppkarwasz

Thank you. I've subscribed to that issue so that we can document Boot's support once it has been addressed.

wilkinsona avatar Nov 12 '25 09:11 wilkinsona

This is no longer blocked, see #48551

snicoll avatar Dec 16 '25 16:12 snicoll

We have a few Log4j2 smoke tests now that are passing with Spring Boot 4.0.1. I've updated the wiki accordingly.

wilkinsona avatar Dec 19 '25 11:12 wilkinsona

Thanks! :100:

Could you also improve the recommendation about Commons Logging? As of Spring Framework 7.0, there is no spring-jcl component: we included the functionality of spring-jcl in version 1.3.0 of Commons Logging (see spring-projects/spring-framework#32459).

If there are problems with reachability metadata, we can manually include them in commons-logging version 1.4.0 (cc @garydgregory).

ppkarwasz avatar Dec 19 '25 12:12 ppkarwasz

Good catch. Thanks, @ppkarwasz. I've updated the bullet about Commons Logging.

wilkinsona avatar Dec 19 '25 12:12 wilkinsona

I can cut a new Apache Commons Logging RC anytime if need be.

garydgregory avatar Dec 19 '25 13:12 garydgregory