Spring Boot 2.0下配置Log4j2下的错误问题分析与解决

环境介绍

Spring Boot 2.0.2 Java 8

任务描述

由于Spring Boot 2.0 默认情况下是使用logback作为日志系统的,这里希望切换到log4j2.

pom.xml内容定义

这里在pom.xml新增了spring-boot中的日志组件

<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>

第一次运行碰到的错误信息

直接运行,在控制台中报出如下的错误信息:

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 [email protected]:17 - no applicable action for [properties], current ElementPath  is [[configuration][properties]]
ERROR in [email protected]:35 - no applicable action for [property], current ElementPath  is [[configuration][properties][property]]
ERROR in [email protected]:16 - no applicable action for [appenders], current ElementPath  is [[configuration][appenders]]
ERROR in [email protected]:53 - no applicable action for [Console], current ElementPath  is [[configuration][appenders][Console]]
ERROR in [email protected]:92 - no applicable action for [PatternLayout], current ElementPath  is [[configuration][appenders][Console][PatternLayout]]
ERROR in [email protected]:91 - no applicable action for [RollingRandomAccessFile], current ElementPath  is [[configuration][appenders][RollingRandomAccessFile]]
ERROR in [email protected]:106 - no applicable action for [PatternLayout], current ElementPath  is [[configuration][appenders][RollingRandomAccessFile][PatternLayout]]
ERROR in [email protected]:23 - no applicable action for [Policies], current ElementPath  is [[configuration][appenders][RollingRandomAccessFile][Policies]]
ERROR in [email protected]:45 - no applicable action for [TimeBasedTriggeringPolicy], current ElementPath  is [[configuration][appenders][RollingRandomAccessFile][Policies][TimeBasedTriggeringPolicy]]
ERROR in [email protected]:48 - no applicable action for [DefaultRolloverStrategy], current ElementPath  is [[configuration][appenders][RollingRandomAccessFile][DefaultRolloverStrategy]]
ERROR in [email protected]:14 - no applicable action for [loggers], current ElementPath  is [[configuration][loggers]]
ERROR in [email protected]:58 - no applicable action for [logger], current ElementPath  is [[configuration][loggers][logger]]
ERROR in [email protected]:74 - no applicable action for [logger], current ElementPath  is [[configuration][loggers][logger]]
ERROR in [email protected]:42 - no applicable action for [appender-ref], current ElementPath  is [[configuration][loggers][logger][appender-ref]]
ERROR in [email protected]:46 - no applicable action for [appender-ref], current ElementPath  is [[configuration][loggers][logger][appender-ref]]
ERROR in [email protected]:28 - no applicable action for [root], current ElementPath  is [[configuration][loggers][root]]
ERROR in [email protected]:42 - no applicable action for [appender-ref], current ElementPath  is [[configuration][loggers][root][appender-ref]]
ERROR in [email protected]: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)

从上述日志中,可以发现,默认使用了logback-classic的日志组件,所以和这里引用的logging组件发生了冲突。

注释掉logback

在pom.xml中注释掉logback.xml中的logback的引用类库,在Eclipse中的Dependency Hierarchy中搜索logback类库,右击选中,选择Exclude Maven Artifact…操作,就将exclude规则写到了pom.xml中了。

从上图中可以看到,这里是Logging组件本身对于logback有依赖,这里应该是从Logging中将logback的依赖包Exclude掉,但是…..问题出现了。在pom.xml,将看到如下的Exclude规则:

<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>

虽然从图中看到的和pom.xml中的实际Exclude规则是不一致的,实际的Exclude规则被放到了Web的组件中了, 那为什么会是这样的?
那只能有一种解释,Web组件实质上依赖于Logging组件的,在组件的设计中,只是将logback类包放入到了Logging组件中,但是Spring Boot中的Web组件是直接使用logback类库的。所以,Exclude规则是发生在了Spring Boot的Web组件中。

第二次执行碰到的问题

在Exclude了logback之后,重新执行整个项目,希望可以正常启动项目,结果问题依然,只是错误信息不同了。。。。。

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)

从错误信息中可以发现,发生死循环了,哪里来的死循环呢?是Log4j的实例化过程中死循环。

问题的解决

在经历了若干个分钟的无奈思考之后,于是想尝试一下。由于Web组件中直接依赖了Logging组件,导致了整个问题的发生,是否可以直接将Logging组件从Web中Exclude掉,然后在pom.xml中直接引入Logging组件。是否就可以解决问题?
大胆假设,小心求证,来吧。

<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>

如果上述的方法依然无法解决您的问题,就基于如下的方式,直接排除掉logging的组件:

<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>

重新执行

系统正常启动,问题已解决。

总结

这里的问题症结点在logging组件与log4j2组件在Spring Boot体系中的彼此冲突问题,这里只能Exclude掉其中一个,方可正常地启动系统。

原文地址:https://www.cnblogs.com/jpfss/p/12111187.html

时间: 2024-08-28 05:31:10

Spring Boot 2.0下配置Log4j2下的错误问题分析与解决的相关文章

Spring Boot 2.0+ 自定义配置类扩展springMVC的功能

在spring boot1.0+,我们可以使用WebMvcConfigurerAdapter来扩展springMVC的功能,其中自定义的拦截器并不会拦截静态资源(js.css等). 在Spring Boot2.0版本中,WebMvcConfigurerAdapter这个类被弃用了. @Deprecated public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer { 那么我们如何来扩展关于MVC的配置呢?

Spring Boot 2.0干货系列:(一)Spring Boot1.5X升级到2.0指南

前言Spring Boot已经发布2.0有满久了,多了很多新特性,一些坑也慢慢被填上,最近有空,就把本博客中Spring Boot干货系列对应的源码从1.5X升级到Spring Boot 2.0,顺便整理下升级的时候遇到的一些坑,做个记录.后续的教程就以最新的2.03版本为主.依赖 JDK 版本升级 2.x 至少需要 JDK 8 的支持,2.x 里面的许多方法应用了 JDK 8 的许多高级新特性,所以你要升级到 2.0 版本,先确认你的应用必须兼容 JDK 8. 另外,2.x 开始了对 JDK

Spring Boot 2.0(一):【重磅】Spring Boot 2.0权威发布

就在昨天Spring Boot2.0.0.RELEASE正式发布,今天早上在发布Spring Boot2.0的时候还出现一个小插曲,将Spring Boot2.0同步到Maven仓库的时候出现了错误,然后Spring Boot官方又赶紧把 GitHub 上发布的 v2.0.0.RELEASE 版本进行了撤回.到了下午将问题修复后,又重新进行了上传,至此Spring Boot2.0正式推出! 要知道这是Spring Boot1.0发布4年之后第一次重大修订,因此有多的新功能和特性值得大家期待!在S

阿里P9告诉你 Spring Boot 2.0正式发布,升还是不升呢?

Spring帝国Spring几乎是每一位Java开发人员都耳熟能详的开发框架,不论您是一名初出茅庐的程序员还是经验丰富的老司机,都会对其有一定的了解或使用经验.在现代企业级应用架构中,Spring技术栈几乎成为了Java语言的代名词,那么Spring为什么能够在众多开源框架中脱颖而出,成为业内一致认可的技术解决方案呢?我们不妨从最初的Spring Framework开始,看看它为什么能够横扫千军,一统江湖! 挑战权威,一战成名 2004年3月,Spring的第一个版本以及其创始人Rod John

Spring boot 2.0 新特性之动态 Banner

Spring Boot 2.0 提供了很多新特性,其中就有一个小彩蛋:动态 Banner,今天我们就先拿这个来尝尝鲜. 配置依赖 使用 Spring Boot 2.0 首先需要将项目依赖包替换为刚刚发布的 2.0 RELEASE,现在网站https://start.spring.io/也将 Spring Boot 2.0 设置为默认版本. <parent> <groupId>org.springframework.boot</groupId> <artifactI

Spring Boot 2.0(五):Docker Compose + Spring Boot + Nginx + Mysql 实践

我知道大家这段时间看了我写关于 docker 相关的几篇文章,不疼不痒的,仍然没有感受 docker 的便利,是的,我也是这样认为的,I know your felling . 前期了解概念什么的确实比较无聊,请不要着急精彩马上开始,当大家对 docker 相关概念有所了解之后,后面我会结合 Spring Boot 给大家来一系列的小例子,会让大家感受到使用 Docker 就是这么爽! 今天给大家演出的导演是 Docker 家族的 docker-compare ,主演是 Spring Boot.

Spring Boot 2.0(六):使用 Docker 部署 Spring Boot 开源软件云收

只需三步即可部署开源项目云收藏,打造专属个人的收藏系统,就是这么简单! 云收藏项目已经开源2年多了,作为当初刚开始学习 Spring Boot 的练手项目,使用了很多当时很新的技术,现在看来其实很多新技术是没有必要使用的,但做为学习案例来讲确实是一个绝佳的 Spring Boot 实践. 从开源到现在,写了一些教程给大家介绍如何部署云收藏,如何在IDE中运行云收藏,但是仍然有很多的朋友不知道如何使用,如何部署?就像"请提供一份云收藏数据结构" 这样的问题我至少都回答了一百多次,并且在

Spring Boot 2.0 热部署指南

Spring Boot 2.0 支持热部署,实现方法很简单 Spring Boot 2.0 有几种热重载的选项. 推荐的方法是使用spring-boot-devtools 因为它提供了额外的开发时间功能,例如支持快速应用程序重启和LiveReload以及合理的开发时配置(如模板缓存). Devtools通过监视类路径的变化来工作. 这意味着静态资源更改必须"建立",以使更改生效. 默认情况下,当您保存更改时,这会在Eclipse中自动发生. 在IntelliJ IDEA中,Make P

Spring Boot 2.0——SpringApplication 深入探索

前言 在 Spring Boot 项目的启动类中常见代码如下: @SpringBootApplicationpublic class SpringbotApplication {    public static void main(String[] args) {         SpringApplication.run(SpringbotApplication.class, args);     } } 其中也就两个比较引人注意的地方: @SpringBootApplication Spr