Version Sanity Check (Spring/SLF4J)
Asked Answered
A

2

4

I am trying to deploy Spring Boot application on Tomcat. But somehow I am getting:

Unexpected problem occured during version sanity check
Reported exception:
java.lang.AbstractMethodError: org.apache.logging.slf4j.SLF4JServiceProvider.getRequestedApiVersion()Ljava/lang/String;
        at org.slf4j.LoggerFactory.versionSanityCheck(LoggerFactory.java:297)
        at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:141)
        at org.slf4j.LoggerFactory.getProvider(LoggerFactory.java:421)
        at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:407)
        at io.micrometer.core.util.internal.logging.Slf4JLoggerFactory.<init>(Slf4JLoggerFactory.java:49)
        at io.micrometer.core.util.internal.logging.Slf4JLoggerFactory.<clinit>(Slf4JLoggerFactory.java:46)
        at io.micrometer.core.util.internal.logging.InternalLoggerFactory.newDefaultFactory(InternalLoggerFactory.java:60)
        at io.micrometer.core.util.internal.logging.InternalLoggerFactory.getDefaultFactory(InternalLoggerFactory.java:76)
        at io.micrometer.core.util.internal.logging.InternalLoggerFactory.getInstance(InternalLoggerFactory.java:108)
        at io.micrometer.core.util.internal.logging.InternalLoggerFactory.getInstance(InternalLoggerFactory.java:98)
        at io.micrometer.core.instrument.binder.jvm.JvmGcMetrics.<clinit>(JvmGcMetrics.java:61)
        at org.springframework.boot.actuate.autoconfigure.metrics.JvmMetricsAutoConfiguration.jvmGcMetrics(JvmMetricsAutoConfiguration.java:48)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653)
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:486)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)

I have a few SLF4J/Log4J2 jars in a common class loader, that are used for some other webapps.

Like:

log4j-api-2.14.1.jar
log4j-core-2.14.1.jar
log4j-over-slf4j-2.0.0-alpha5.jar
log4j-slf4j18-impl-2.14.1.jar
slf4j-api-2.0.0-alpha5.jar

I thought it was a conflict with the slf4j jars with the jars of the spring WAR. So i excluded all the sllf4j items from the Spring application, thinking that it would pick the classes from the common loader. But I get the above error. The application starts up fine, without any issues. But not sure how to get rid of this. My final dependency section of the of the spring application's pom is something like this:

<dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-api</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.logging.log4j</groupId>
                    <artifactId>log4j-to-slf4j</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>jul-to-slf4j</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>ch.qos.logback</groupId>
                    <artifactId>logback-classic</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
    
    </dependencies>
Ask answered 12/11, 2021 at 14:40 Comment(0)
T
10

Seems like you found a typo in the log4j-slf4j18-impl lib. The LoggerFactory from slf4j-api:2.0.0-alpha5 tries to get the requested api version from the provider (source):

String requested = PROVIDER.getRequestedApiVersion();

But seems like the actual implementation only has a method called getRequesteApiVersion

I would encourage you to open an issue in Apache's issue tracker about this.

EDIT: I have found a similar issue in the Apache issue tracker (https://issues.apache.org/jira/browse/LOG4J2-3139). Based on that information Slf4J made a non-backward compatible change for the 2.0 release (changed the getRequesteApiVersion method to getRequestedApiVersion). Since Slf4J's currently at an alpha release, Apache will only fix this once there is a stable release for Slf4j.

What you can try is either specify another provider for Slf4J or implicitly use an older version of Slf4j.

Tergum answered 12/11, 2021 at 17:21 Comment(1)
issues.apache.org/jira/browse/LOG4J2-3139 was resolved 2022-Sep-07Ramey
R
1

LOG4J2-3139 was resolved 2022-Sep-07

Be sure to heed this warning:

Use of the Log4j 2 SLF4J Binding (log4j-slf4j-impl-2.0.jar) together with the SLF4J adapter (log4j-to-slf4j-2.0.jar) should never be attempted, as it will cause events to endlessly be routed between SLF4J and Log4j 2.

https://logging.apache.org/log4j/2.x/log4j-slf4j-impl/

Ramey answered 15/12, 2022 at 22:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.