Native compiled executable prints log4j2 exception/warning when both Netty and JBoss Logging are on the classpath

See original GitHub issue

I have a CLI tool using Spring Boot 3.0.0.RC2 with Spring Shell. When I compile it natively and run it, it suddenly now prints this at the start:

ERROR StatusLogger Unable to load services for service class org.apache.logging.log4j.spi.Provider
 java.lang.NoSuchMethodException: no such method: java.util.ServiceLoader.load(Class,ClassLoader)ServiceLoader/invokeStatic
	at java.base@19.0.1/java.lang.invoke.MemberName.makeAccessException(MemberName.java:976)
	at java.base@19.0.1/java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:1117)
	at java.base@19.0.1/java.lang.invoke.MethodHandles$Lookup.resolveOrFail(MethodHandles.java:3664)
	at java.base@19.0.1/java.lang.invoke.MethodHandles$Lookup.findStatic(MethodHandles.java:2598)
	at org.apache.logging.log4j.util.ServiceLoaderUtil.loadClassloaderServices(ServiceLoaderUtil.java:91)
	at org.apache.logging.log4j.util.ServiceLoaderUtil.loadServices(ServiceLoaderUtil.java:74)
	at org.apache.logging.log4j.util.ServiceLoaderUtil.loadServices(ServiceLoaderUtil.java:68)
	at org.apache.logging.log4j.util.ProviderUtil.<init>(ProviderUtil.java:67)
	at org.apache.logging.log4j.util.ProviderUtil.lazyInit(ProviderUtil.java:145)
	at org.apache.logging.log4j.util.ProviderUtil.hasProviders(ProviderUtil.java:129)
	at org.apache.logging.log4j.LogManager.<clinit>(LogManager.java:90)
	at org.jboss.logging.LoggerProviders.tryLog4j2(LoggerProviders.java:119)
	at org.jboss.logging.LoggerProviders.findProvider(LoggerProviders.java:84)
	at org.jboss.logging.LoggerProviders.find(LoggerProviders.java:32)
	at org.jboss.logging.LoggerProviders.<clinit>(LoggerProviders.java:29)
	at org.jboss.logging.Logger.getLogger(Logger.java:2465)
	at org.jboss.logging.Logger.doGetMessageLogger(Logger.java:2573)
	at org.jboss.logging.Logger.getMessageLogger(Logger.java:2530)
	at org.jboss.logging.Logger.getMessageLogger(Logger.java:2516)
	at org.hibernate.validator.internal.util.logging.LoggerFactory.make(LoggerFactory.java:22)
	at org.hibernate.validator.internal.util.Version.<clinit>(Version.java:20)
	at org.hibernate.validator.internal.engine.AbstractConfigurationImpl.<clinit>(AbstractConfigurationImpl.java:85)
	at java.base@19.0.1/java.lang.Class.ensureInitialized(DynamicHub.java:528)
	at org.hibernate.validator.HibernateValidator.createGenericConfiguration(HibernateValidator.java:33)
	at jakarta.validation.Validation$GenericBootstrapImpl.configure(Validation.java:296)
	at org.springframework.boot.validation.MessageInterpolatorFactory.getMessageInterpolator(MessageInterpolatorFactory.java:79)
	at org.springframework.boot.validation.MessageInterpolatorFactory.getObject(MessageInterpolatorFactory.java:70)
	at org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration.defaultValidator(ValidationAutoConfiguration.java:64)
	at org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration__BeanDefinitions.lambda$getDefaultValidatorInstanceSupplier$0(ValidationAutoConfiguration__BeanDefinitions.java:33)
	at org.springframework.util.function.ThrowingBiFunction.apply(ThrowingBiFunction.java:68)
	at org.springframework.util.function.ThrowingBiFunction.apply(ThrowingBiFunction.java:54)
	at org.springframework.beans.factory.aot.BeanInstanceSupplier.lambda$get$2(BeanInstanceSupplier.java:208)
	at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:59)
	at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:47)
	at org.springframework.beans.factory.aot.BeanInstanceSupplier.invokeBeanSupplier(BeanInstanceSupplier.java:220)
	at org.springframework.beans.factory.aot.BeanInstanceSupplier.get(BeanInstanceSupplier.java:208)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainInstanceFromSupplier(AbstractAutowireCapableBeanFactory.java:1225)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1210)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1157)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:561)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:521)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:961)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:916)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:584)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:730)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:432)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:308)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1291)
	at io.github.wimdeblauwe.ttcli.TamingThymeleafCliApplication.main(TamingThymeleafCliApplication.java:10)
Caused by: java.lang.NoSuchMethodError: java.util.ServiceLoader.load(java.lang.Class, java.lang.ClassLoader)
	at org.graalvm.nativeimage.builder/com.oracle.svm.core.methodhandles.Util_java_lang_invoke_MethodHandleNatives.resolve(Target_java_lang_invoke_MethodHandleNatives.java:345)
	at java.base@19.0.1/java.lang.invoke.MethodHandleNatives.resolve(MethodHandleNatives.java:223)
	at java.base@19.0.1/java.lang.invoke.MemberName$Factory.resolve(MemberName.java:1085)
	at java.base@19.0.1/java.lang.invoke.MemberName$Factory.resolveOrFail(MemberName.java:1114)
	... 52 more
ERROR StatusLogger Log4j2 could not find a logging implementation. Please add log4j-core to the classpath. Using SimpleLogger to log to the console...

To be clear: this is not printed when running on the JVM.

I am not using Log4j2, it is not in my dependency tree:

[INFO] --- maven-dependency-plugin:3.3.0:tree (default-cli) @ ttcli ---
[INFO] io.github.wimdeblauwe:ttcli:jar:0.0.3-SNAPSHOT
[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:3.0.0-RC2:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter:jar:3.0.0-RC2:compile
[INFO] |  |  +- org.springframework.boot:spring-boot:jar:3.0.0-RC2:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-autoconfigure:jar:3.0.0-RC2:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-starter-logging:jar:3.0.0-RC2:compile
[INFO] |  |  |  +- ch.qos.logback:logback-classic:jar:1.4.4:compile
[INFO] |  |  |  |  \- ch.qos.logback:logback-core:jar:1.4.4:compile
[INFO] |  |  |  +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.19.0:compile
[INFO] |  |  |  |  \- org.apache.logging.log4j:log4j-api:jar:2.19.0:compile
[INFO] |  |  |  \- org.slf4j:jul-to-slf4j:jar:2.0.3:compile
[INFO] |  |  +- jakarta.annotation:jakarta.annotation-api:jar:2.1.1:compile
[INFO] |  |  \- org.yaml:snakeyaml:jar:1.33:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-json:jar:3.0.0-RC2:compile
[INFO] |  |  +- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:jar:2.14.0-rc3:compile
[INFO] |  |  +- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.14.0-rc3:compile
[INFO] |  |  \- com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.14.0-rc3:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-tomcat:jar:3.0.0-RC2:compile
[INFO] |  |  +- org.apache.tomcat.embed:tomcat-embed-core:jar:10.1.1:compile
[INFO] |  |  +- org.apache.tomcat.embed:tomcat-embed-el:jar:10.1.1:compile
[INFO] |  |  \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:10.1.1:compile
[INFO] |  +- org.springframework:spring-web:jar:6.0.0-RC4:compile
[INFO] |  |  +- org.springframework:spring-beans:jar:6.0.0-RC4:compile
[INFO] |  |  \- io.micrometer:micrometer-observation:jar:1.10.0:compile
[INFO] |  |     \- io.micrometer:micrometer-commons:jar:1.10.0:compile
[INFO] |  \- org.springframework:spring-webmvc:jar:6.0.0-RC4:compile
[INFO] |     +- org.springframework:spring-aop:jar:6.0.0-RC4:compile
[INFO] |     +- org.springframework:spring-context:jar:6.0.0-RC4:compile
[INFO] |     \- org.springframework:spring-expression:jar:6.0.0-RC4:compile
[INFO] +- org.springframework.boot:spring-boot-starter-webflux:jar:3.0.0-RC2:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-reactor-netty:jar:3.0.0-RC2:compile
[INFO] |  |  \- io.projectreactor.netty:reactor-netty-http:jar:1.1.0:compile
[INFO] |  |     +- io.netty:netty-codec-http:jar:4.1.84.Final:compile
[INFO] |  |     |  +- io.netty:netty-common:jar:4.1.84.Final:compile
[INFO] |  |     |  +- io.netty:netty-buffer:jar:4.1.84.Final:compile
[INFO] |  |     |  +- io.netty:netty-transport:jar:4.1.84.Final:compile
[INFO] |  |     |  +- io.netty:netty-codec:jar:4.1.84.Final:compile
[INFO] |  |     |  \- io.netty:netty-handler:jar:4.1.84.Final:compile
[INFO] |  |     +- io.netty:netty-codec-http2:jar:4.1.84.Final:compile
[INFO] |  |     +- io.netty:netty-resolver-dns:jar:4.1.84.Final:compile
[INFO] |  |     |  +- io.netty:netty-resolver:jar:4.1.84.Final:compile
[INFO] |  |     |  \- io.netty:netty-codec-dns:jar:4.1.84.Final:compile
[INFO] |  |     +- io.netty:netty-resolver-dns-native-macos:jar:osx-x86_64:4.1.84.Final:compile
[INFO] |  |     |  \- io.netty:netty-resolver-dns-classes-macos:jar:4.1.84.Final:compile
[INFO] |  |     +- io.netty:netty-transport-native-epoll:jar:linux-x86_64:4.1.84.Final:compile
[INFO] |  |     |  +- io.netty:netty-transport-native-unix-common:jar:4.1.84.Final:compile
[INFO] |  |     |  \- io.netty:netty-transport-classes-epoll:jar:4.1.84.Final:compile
[INFO] |  |     \- io.projectreactor.netty:reactor-netty-core:jar:1.1.0:compile
[INFO] |  |        \- io.netty:netty-handler-proxy:jar:4.1.84.Final:compile
[INFO] |  |           \- io.netty:netty-codec-socks:jar:4.1.84.Final:compile
[INFO] |  \- org.springframework:spring-webflux:jar:6.0.0-RC4:compile
[INFO] |     \- io.projectreactor:reactor-core:jar:3.5.0:compile
[INFO] |        \- org.reactivestreams:reactive-streams:jar:1.0.4:compile
[INFO] +- org.springframework.shell:spring-shell-starter:jar:3.0.0-M2:compile
[INFO] |  +- org.springframework.shell:spring-shell-autoconfigure:jar:3.0.0-M2:compile
[INFO] |  +- org.springframework.shell:spring-shell-core:jar:3.0.0-M2:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-starter-validation:jar:3.0.0-RC2:compile
[INFO] |  |  |  \- org.hibernate.validator:hibernate-validator:jar:8.0.0.Final:compile
[INFO] |  |  |     +- jakarta.validation:jakarta.validation-api:jar:3.0.2:compile
[INFO] |  |  |     +- org.jboss.logging:jboss-logging:jar:3.5.0.Final:compile
[INFO] |  |  |     \- com.fasterxml:classmate:jar:1.5.1:compile
[INFO] |  |  +- org.springframework:spring-messaging:jar:6.0.0-RC4:compile
[INFO] |  |  +- org.jline:jline:jar:3.21.0:compile
[INFO] |  |  +- org.antlr:ST4:jar:4.3.1:compile
[INFO] |  |  |  \- org.antlr:antlr-runtime:jar:3.5.2:compile
[INFO] |  |  \- commons-io:commons-io:jar:2.11.0:compile
[INFO] |  +- org.springframework.shell:spring-shell-standard:jar:3.0.0-M2:compile
[INFO] |  +- org.springframework.shell:spring-shell-standard-commands:jar:3.0.0-M2:compile
[INFO] |  \- org.springframework.shell:spring-shell-table:jar:3.0.0-M2:compile
[INFO] +- org.jsoup:jsoup:jar:1.15.3:compile
[INFO] +- us.codecraft:xsoup:jar:0.3.6:compile
[INFO] |  \- org.assertj:assertj-core:jar:3.23.1:compile
[INFO] |     \- net.bytebuddy:byte-buddy:jar:1.12.18:compile
[INFO] +- com.fasterxml.jackson.core:jackson-databind:jar:2.14.0-rc3:compile
[INFO] |  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.14.0-rc3:compile
[INFO] |  \- com.fasterxml.jackson.core:jackson-core:jar:2.14.0-rc3:compile
[INFO] \- org.springframework.boot:spring-boot-starter-test:jar:3.0.0-RC2:test
[INFO]    +- org.springframework.boot:spring-boot-test:jar:3.0.0-RC2:test
[INFO]    +- org.springframework.boot:spring-boot-test-autoconfigure:jar:3.0.0-RC2:test
[INFO]    +- com.jayway.jsonpath:json-path:jar:2.7.0:test
[INFO]    |  +- net.minidev:json-smart:jar:2.4.8:test
[INFO]    |  |  \- net.minidev:accessors-smart:jar:2.4.8:test
[INFO]    |  |     \- org.ow2.asm:asm:jar:9.1:test
[INFO]    |  \- org.slf4j:slf4j-api:jar:2.0.3:compile
[INFO]    +- jakarta.xml.bind:jakarta.xml.bind-api:jar:4.0.0:test
[INFO]    |  \- jakarta.activation:jakarta.activation-api:jar:2.1.0:test
[INFO]    +- org.hamcrest:hamcrest:jar:2.2:test
[INFO]    +- org.junit.jupiter:junit-jupiter:jar:5.9.1:test
[INFO]    |  +- org.junit.jupiter:junit-jupiter-api:jar:5.9.1:test
[INFO]    |  |  +- org.opentest4j:opentest4j:jar:1.2.0:test
[INFO]    |  |  +- org.junit.platform:junit-platform-commons:jar:1.9.1:test
[INFO]    |  |  \- org.apiguardian:apiguardian-api:jar:1.1.2:test
[INFO]    |  +- org.junit.jupiter:junit-jupiter-params:jar:5.9.1:test
[INFO]    |  \- org.junit.jupiter:junit-jupiter-engine:jar:5.9.1:test
[INFO]    |     \- org.junit.platform:junit-platform-engine:jar:1.9.1:test
[INFO]    +- org.mockito:mockito-core:jar:4.8.1:test
[INFO]    |  +- net.bytebuddy:byte-buddy-agent:jar:1.12.18:test
[INFO]    |  \- org.objenesis:objenesis:jar:3.2:test
[INFO]    +- org.mockito:mockito-junit-jupiter:jar:4.8.1:test
[INFO]    +- org.skyscreamer:jsonassert:jar:1.5.1:test
[INFO]    |  \- com.vaadin.external.google:android-json:jar:0.0.20131108.vaadin1:test
[INFO]    +- org.springframework:spring-core:jar:6.0.0-RC4:compile
[INFO]    |  \- org.springframework:spring-jcl:jar:6.0.0-RC4:compile
[INFO]    +- org.springframework:spring-test:jar:6.0.0-RC4:test
[INFO]    \- org.xmlunit:xmlunit-core:jar:2.9.0:test

I compiled on macOS using GraalVM:

sdk use java 22.3.r19-grl
mvn -Pnative native:compile

Let me know if you need more info. The project can be viewed at https://github.com/wimdeblauwe/ttcli

Issue Analytics

  • State:closed
  • Created 10 months ago
  • Comments:9 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
wilkinsonacommented, Nov 14, 2022

I’ve opened https://github.com/oracle/graalvm-reachability-metadata/pull/108 to fix the reachability metadata for Netty. With this change in place, Log4j2 no longer performs the error-level logging of the exception. Until this change is available, please continue to exclude the org.apache.logging.log4j:log4j-to-slf4j dependency or set the org.jboss.logging.provider system property to jdk.

I’ve also opened https://github.com/spring-projects/spring-boot/issues/33155 to address the different providers on the JVM and in a native image that was discovered while investigating this issue.

0reactions
wilkinsonacommented, Nov 14, 2022

org.apache.logging.log4j.message.DefaultFlowMessageFactory is accessible reflectively when Netty’s on the classpath. This is due to its reachability metadata. Given that Log4j2 doesn’t work in a native image and that Netty prefers SLF4J over Log4j2, I wonder if this metadata is doing more harm than good.

Read more comments on GitHub >

github_iconTop Results From Across the Web

JBoss logging does not route directly to SLF4J when ... - GitHub
Native compiled executable prints log4j2 exception/warning when both Netty and JBoss Logging are on the classpath #33113.
Read more >
Log4j2 could not find a logging implementation with Spring Boot
I looked up the source code of LogManager.class and found the reason was there's no LoggerContextFactory found in log4j-provider.properties ...
Read more >
Configuring Logging - Quarkus
This guide explains logging and how to configure it. Internally, Quarkus uses JBoss Log Manager and the JBoss Logging facade. You can use...
Read more >
Log4j – Frequently Asked Questions - Apache Logging Services
By default, Log4j looks for a configuration file named log4j2.xml (not log4j.xml) in the classpath. You can also specify the full path of...
Read more >
Separating Log4J application logging from the server.log in ...
xml is packaged in our application. Messages are not logged in server.log . I would like to separate application logging configuration file ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found