Spring Boot 日志记录中的 ClassCastException

Posted

技术标签:

【中文标题】Spring Boot 日志记录中的 ClassCastException【英文标题】:ClassCastException in SpringBoot Logging 【发布时间】:2020-02-27 19:48:42 【问题描述】:

我的应用程序启动时遇到问题。应用程序在配置日志级别时失败,出现 ClassCastException java.util.HashMap cannot be cast to org.springframework.boot.logging.LogLevel

我尝试在我的application.properties 中设置logging.level.root=INFO 并出现同样的错误。不知道还能尝试什么。

我刚刚升级到SpringBoot 2.x,专门使用这个依赖BOM:

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>$springframework.boot.version</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

请找到依赖树的相关部分:

[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:2.2.0.RELEASE:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter:jar:2.2.0.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot:jar:2.2.0.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-autoconfigure:jar:2.2.0.RELEASE:compile
[INFO] |  |  +- org.springframework.boot:spring-boot-starter-logging:jar:2.2.0.RELEASE:compile
[INFO] |  |  |  +- ch.qos.logback:logback-classic:jar:1.2.3:compile
[INFO] |  |  |  |  \- ch.qos.logback:logback-core:jar:1.2.3:compile
[INFO] |  |  |  +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.12.1:compile
[INFO] |  |  |  |  \- org.apache.logging.log4j:log4j-api:jar:2.12.1:compile
[INFO] |  |  |  \- org.slf4j:jul-to-slf4j:jar:1.7.28:compile
[INFO] |  |  +- org.springframework:spring-core:jar:5.2.0.RELEASE:compile
[INFO] |  |  |  \- org.springframework:spring-jcl:jar:5.2.0.RELEASE:compile
[INFO] |  |  \- org.yaml:snakeyaml:jar:1.25:runtime
[INFO] |  +- org.springframework.boot:spring-boot-starter-json:jar:2.2.0.RELEASE:compile
[INFO] |  |  +- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:jar:2.10.0:compile
[INFO] |  |  +- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.10.0:compile
[INFO] |  |  \- com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.10.0:compile
[INFO] |  +- org.springframework.boot:spring-boot-starter-validation:jar:2.2.0.RELEASE:compile
[INFO] |  |  +- jakarta.validation:jakarta.validation-api:jar:2.0.1:compile
[INFO] |  |  \- org.hibernate.validator:hibernate-validator:jar:6.0.17.Final:compile
[INFO] |  |     \- org.jboss.logging:jboss-logging:jar:3.4.1.Final:compile
[INFO] |  +- org.springframework:spring-web:jar:5.2.0.RELEASE:compile
[INFO] |  \- org.springframework:spring-webmvc:jar:5.2.0.RELEASE:compile
[INFO] |     +- org.springframework:spring-aop:jar:5.2.0.RELEASE:compile
[INFO] |     +- org.springframework:spring-context:jar:5.2.0.RELEASE:compile
[INFO] |     \- org.springframework:spring-expression:jar:5.2.0.RELEASE:compile
[INFO] +- org.springframework.boot:spring-boot-starter-tomcat:jar:2.2.0.RELEASE:provided
[INFO] |  +- jakarta.annotation:jakarta.annotation-api:jar:1.3.5:compile
[INFO] |  +- org.apache.tomcat.embed:tomcat-embed-core:jar:9.0.27:provided
[INFO] |  +- org.apache.tomcat.embed:tomcat-embed-el:jar:9.0.27:provided
[INFO] |  \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:9.0.27:provided
[INFO] +- org.springframework.boot:spring-boot-starter-actuator:jar:2.2.0.RELEASE:compile
[INFO] |  +- org.springframework.boot:spring-boot-actuator-autoconfigure:jar:2.2.0.RELEASE:compile
[INFO] |  |  \- org.springframework.boot:spring-boot-actuator:jar:2.2.0.RELEASE:compile
[INFO] |  \- io.micrometer:micrometer-core:jar:1.3.0:compile
[INFO] |     +- org.hdrhistogram:HdrHistogram:jar:2.1.11:compile
[INFO] |     \- org.latencyutils:LatencyUtils:jar:2.0.3:compile
[INFO] |  |  +- org.springframework.cloud:spring-cloud-starter-oauth2:jar:2.0.0.RELEASE:compile
[INFO] |  |  |  +- org.springframework.cloud:spring-cloud-starter-security:jar:2.0.0.RELEASE:compile
[INFO] |  |  |  |  +- org.springframework.cloud:spring-cloud-starter:jar:2.0.0.RELEASE:compile
[INFO] |  |  |  |  |  +- org.springframework.cloud:spring-cloud-context:jar:2.0.0.RELEASE:compile
[INFO] |  |  |  |  |  |  \- org.springframework.security:spring-security-crypto:jar:5.2.0.RELEASE:compile
[INFO] |  |  |  |  |  +- org.springframework.cloud:spring-cloud-commons:jar:2.0.0.RELEASE:compile
[INFO] |  |  |  |  |  \- org.springframework.security:spring-security-rsa:jar:1.0.5.RELEASE:compile
[INFO] |  |  |  |  \- org.springframework.cloud:spring-cloud-security:jar:2.0.0.RELEASE:compile
[INFO] |  |  |  |     \- org.springframework.boot:spring-boot-starter-security:jar:2.2.0.RELEASE:compile
[INFO] |  |  |  \- org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:jar:2.0.0.RELEASE:compile
[INFO] |  |  |     \- org.springframework.security:spring-security-jwt:jar:1.0.9.RELEASE:compile
[INFO] |  |  |        \- org.bouncycastle:bcpkix-jdk15on:jar:1.56:compile
[INFO] |  |  |           \- org.bouncycastle:bcprov-jdk15on:jar:1.56:compile

这是堆栈跟踪:

Caused by: java.lang.ClassCastException: java.util.HashMap cannot be cast to org.springframework.boot.logging.LogLevel
    at java.util.HashMap.forEach(HashMap.java:1289)
    at org.springframework.boot.context.logging.LoggingApplicationListener.setLogLevels(LoggingApplicationListener.java:398)
    at org.springframework.boot.context.logging.LoggingApplicationListener.initializeFinalLoggingLevels(LoggingApplicationListener.java:337)
    at org.springframework.boot.context.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:288)
    at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:245)
    at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:222)
    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:76)
    at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:53)
    at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:345)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:308)

application.properties

logging.level.root=warn
logging.level.org.springframework.web=debug
logging.level.org.hibernate=error
logging.level.com.my.package.name=error

很明显,这里的问题是 levels 映射中的值是哈希映射,而不是字符串......虽然不知道为什么会这样。

【问题讨论】:

你能分享你的application.properties文件吗? 嗨@ShishirKumar。它有一些特定于组织的相关属性,但除此之外它只有logging.level.root=INFO 这很奇怪,显然Spring代码在配置环境时变得混乱。如果有帮助,您可以在这里找到有问题的代码:github.com/spring-projects/spring-boot/blob/master/… 也许您可以尝试在Binder binder = Binder.get(environment); 中设置断点并检查返回的结构为binder logging.level.org.springframework=ERROR .. 或者使用包级别 logging.level.com.foo=DEBUG 你能用这个验证吗 【参考方案1】:

尝试将日志记录值设置为 WARN 和 debug=true 并进行检查。

在你的属性文件中设置这样的值

logging.level.root=warn
logging.level.org.springframework.web=debug
logging.level.org.hibernate=error

log4j.xml 中会如下所示

<root>
        <level value="WARN"/>
        <appender-ref ref="console" />
        <appender-ref ref="file"/>

</root>

有关登录 Spring Boot 的更多详细信息,请阅读以下链接 https://howtodoinjava.com/spring-boot2/logging/spring-boot-logging-configurations/

【讨论】:

谢谢,请查看我更新的问题。我已经尝试过了,同样的问题也出现了。【参考方案2】:

切换到 logback,它可以让您更好地控制日志级别和附加程序。 见https://dzone.com/articles/configuring-logback-with-spring-boot

【讨论】:

以上是关于Spring Boot 日志记录中的 ClassCastException的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot 之日志记录

Spring Boot 中的记录器问题

Spring Boot application.properties 中的日志级别问题

在 Spring Boot 上禁用应用程序的控制台日志记录

Spring Boot - 日志记录

Spring Boot 中使用Spring Aop实现日志记录功能