springboot Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory

Environment introduction

Spring Boot 2.0.2 Java 8

mission details

Since Spring Boot 2.0 uses logback as the logging system by default, I hope to switch to log4j2.

pom.xml content definition

Here is a new log component in spring-boot in pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

Error message encountered in the first run

Run directly and report the following error message in the console:

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/D:/DevSpace/M2Space/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/D:/DevSpace/M2Space/org/apache/logging/log4j/log4j-slf4j-impl/2.10.0/log4j-slf4j-impl-2.10.0.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]
13:55:11.713 [main] DEBUG org.springframework.boot.devtools.settings.DevToolsSettings - Included patterns for restart : []
13:55:11.721 [main] DEBUG org.springframework.boot.devtools.settings.DevToolsSettings - Excluded patterns for restart : [/spring-boot-actuator/target/classes/, /spring-boot-devtools/target/classes/, /spring-boot/target/classes/, /spring-boot-starter-[\w-]+/, /spring-boot-autoconfigure/target/classes/, /spring-boot-starter/target/classes/]
13:55:11.722 [main] DEBUG org.springframework.boot.devtools.restart.ChangeableUrls - Matching URLs for reloading : [file:/D:/CodeSpace/photobuyapi/target/classes/]
Logging system failed to initialize using configuration from 'classpath:log4j2.xml'
java.lang.IllegalStateException: Logback configuration error detected: 
ERROR in ch.qos.logback.core.joran.spi.Interpreter@3:17 - no applicable action for [properties], current ElementPath  is [[configuration][properties]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:35 - no applicable action for [property], current ElementPath  is [[configuration][properties][property]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@7:16 - no applicable action for [appenders], current ElementPath  is [[configuration][appenders]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@9:53 - no applicable action for [Console], current ElementPath  is [[configuration][appenders][Console]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@10:92 - no applicable action for [PatternLayout], current ElementPath  is [[configuration][appenders][Console][PatternLayout]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@16:91 - no applicable action for [RollingRandomAccessFile], current ElementPath  is [[configuration][appenders][RollingRandomAccessFile]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@17:106 - no applicable action for [PatternLayout], current ElementPath  is [[configuration][appenders][RollingRandomAccessFile][PatternLayout]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@18:23 - no applicable action for [Policies], current ElementPath  is [[configuration][appenders][RollingRandomAccessFile][Policies]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@19:45 - no applicable action for [TimeBasedTriggeringPolicy], current ElementPath  is [[configuration][appenders][RollingRandomAccessFile][Policies][TimeBasedTriggeringPolicy]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@21:48 - no applicable action for [DefaultRolloverStrategy], current ElementPath  is [[configuration][appenders][RollingRandomAccessFile][DefaultRolloverStrategy]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@25:14 - no applicable action for [loggers], current ElementPath  is [[configuration][loggers]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@27:58 - no applicable action for [logger], current ElementPath  is [[configuration][loggers][logger]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@30:74 - no applicable action for [logger], current ElementPath  is [[configuration][loggers][logger]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@31:42 - no applicable action for [appender-ref], current ElementPath  is [[configuration][loggers][logger][appender-ref]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@32:46 - no applicable action for [appender-ref], current ElementPath  is [[configuration][loggers][logger][appender-ref]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@36:28 - no applicable action for [root], current ElementPath  is [[configuration][loggers][root]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@37:42 - no applicable action for [appender-ref], current ElementPath  is [[configuration][loggers][root][appender-ref]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@38:46 - no applicable action for [appender-ref], current ElementPath  is [[configuration][loggers][root][appender-ref]]
    at org.springframework.boot.logging.logback.LogbackLoggingSystem.loadConfiguration(LogbackLoggingSystem.java:166)
    at org.springframework.boot.logging.AbstractLoggingSystem.initializeWithSpecificConfig(AbstractLoggingSystem.java:67)
    at org.springframework.boot.logging.AbstractLoggingSystem.initialize(AbstractLoggingSystem.java:57)
    at org.springframework.boot.logging.logback.LogbackLoggingSystem.initialize(LogbackLoggingSystem.java:114)
    at org.springframework.boot.context.logging.LoggingApplicationListener.initializeSystem(LoggingApplicationListener.java:269)
    at org.springframework.boot.context.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:237)
    at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:200)
    at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:173)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127)
    at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:74)
    at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:54)
    at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:358)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:317)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1255)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1243)
    at com.jd.ai.cv.api.PubAPIApplication.main(PubAPIApplication.java:17)
    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.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)

From the above logs, it can be found that the logback-classic log component is used by default, so it conflicts with the logging component referenced here.

Comment out logback

Comment out the reference class library of logback in logback.xml in pom.xml, search for the logback class library in Dependency Hierarchy in Eclipse, right-click to select, select Exclude Maven Artifact... operation, the exclude rules are written to pom.xml bingo.
Write picture description here
As you can see from the above figure, here is that the Logging component itself has a dependency on logback, and here should be Excluded from the logback dependency package from Logging, but...the problem has arisen. In pom.xml, you will see the following Exclude rules:

<dependency>
     <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
         <exclusions>
                <exclusion>
                    <groupId>ch.qos.logback</groupId>
                    <artifactId>logback-classic</artifactId>
                </exclusion>
         </exclusions>
</dependency>
<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

Although what you can see from the figure is inconsistent with the actual Exclude rules in pom.xml, the actual Exclude rules have been put into the Web component, so why is it so?
There can only be one explanation. Web components essentially depend on Logging components. In the design of the components, only the logback class package is put into the Logging component, but the Web components in Spring Boot directly use the logback class library. Therefore, the Exclude rule occurs in Spring Boot's web components.

Problems encountered in the second execution

After Exclude logback, re-execute the entire project, hoping to start the project normally, the result is still the problem, but the error message is different. . . . . It can be found from the error message that an infinite loop has occurred. Where did the infinite loop come from? It is an endless loop during the instantiation of Log4j.

Exception in thread "main" java.lang.StackOverflowError
at org.apache.logging.log4j.util.StackLocator.getCallerClass(StackLocator.java:112)
at org.apache.logging.log4j.util.StackLocator.getCallerClass(StackLocator.java:125)
at org.apache.logging.log4j.util.StackLocatorUtil.getCallerClass(StackLocatorUtil.java:55)
at org.apache.logging.slf4j.Log4jLoggerFactory.getContext(Log4jLoggerFactory.java:42)
at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:46)
at org.apache.logging.slf4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:29)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:358)
at org.apache.logging.slf4j.SLF4JLoggerContext.getLogger(SLF4JLoggerContext.java:39)
at org.apache.logging.slf4j.Log4jLoggerFactory.newLogger(Log4jLoggerFactory.java:37)
at org.apache.logging.slf4j.Log4jLoggerFactory.newLogger(Log4jLoggerFactory.java:29)
at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:52)
at org.apache.logging.slf4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:29)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:358)
at org.apache.logging.slf4j.SLF4JLoggerContext.getLogger(SLF4JLoggerContext.java:39)
at org.apache.logging.slf4j.Log4jLoggerFactory.newLogger(Log4jLoggerFactory.java:37)
at org.apache.logging.slf4j.Log4jLoggerFactory.newLogger(Log4jLoggerFactory.java:29)
at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:52)
at org.apache.logging.slf4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:29)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:358)


Problem solving

After several minutes of helpless thinking, I wanted to give it a try. Because the Web component directly relies on the Logging component, the whole problem occurs. Can the Logging component be directly Excluded from the Web, and then the Logging component can be directly imported into the pom.xml? Can the problem be solved?
Boldly assume, carefully verify, come on.

<dependency>
    <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
         <exclusions>
            <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
            <exclusion>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
        </exclusion>
    </exclusions>
</dependency>

If the above method still does not solve your problem, simply exclude the logging component based on the following method:

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

Re-run

The system starts normally and the problem is resolved.

to sum up

The crux of the problem here is the conflict between the logging component and the log4j2 component in the Spring Boot system. Only one of them can be excluded here to start the system normally.

 

Guess you like

Origin blog.csdn.net/zhaofuqiangmycomm/article/details/115032869