SLF4J与Logback:NoClassDefFoundError: org/slf4j/impl/StaticLoggerBinder

12

我正在尝试使用SLF4J和Logback实现RollingFile记录器,但是我遇到了一个无法解决的异常。异常如下:

Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/impl/StaticLoggerBinder
    at org.springframework.boot.logging.logback.LogbackLoggingSystem.getLoggerContext(LogbackLoggingSystem.java:293)
    at org.springframework.boot.logging.logback.LogbackLoggingSystem.beforeInitialize(LogbackLoggingSystem.java:118)
    at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationStartingEvent(LoggingApplicationListener.java:232)
    at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:213)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:176)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:131)
    at org.springframework.boot.context.event.EventPublishingRunListener.starting(EventPublishingRunListener.java:76)
    at org.springframework.boot.SpringApplicationRunListeners.lambda$starting$0(SpringApplicationRunListeners.java:53)
    at java.util.ArrayList.forEach(ArrayList.java:1259)
    at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:117)
    at org.springframework.boot.SpringApplicationRunListeners.starting(SpringApplicationRunListeners.java:53)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:317)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1313)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1302)
    at com.upnetix.java.simeonyachev.PlexUserNameApplication.main(PlexUserNameApplication.java:13)
Caused by: java.lang.ClassNotFoundException: org.slf4j.impl.StaticLoggerBinder
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:418)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:355)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:351)
    ... 17 more

这是我的 pom.xml 文件:

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.4</version>
        <relativePath/>
    </parent>

    <dependencies>
        <!--SPRING BOOT-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
<!--            <exclusions>-->
<!--                <exclusion>-->
<!--                    <groupId>org.apache.logging.log4j</groupId>-->
<!--                    <artifactId>log4j-to-slf4j</artifactId>-->
<!--                </exclusion>-->
<!--                <exclusion>-->
<!--                    <groupId>org.apache.logging.log4j</groupId>-->
<!--                    <artifactId>log4j-api</artifactId>-->
<!--                </exclusion>-->
<!--                <exclusion>-->
<!--                    <groupId>org.slf4j</groupId>-->
<!--                    <artifactId>jul-to-slf4j</artifactId>-->
<!--                </exclusion>-->
<!--            </exclusions>-->
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.2.4.RELEASE</version>
<!--            <exclusions>-->
<!--                <exclusion>-->
<!--                    <groupId>org.jboss.logging</groupId>-->
<!--                    <artifactId>jboss-logging</artifactId>-->
<!--                </exclusion>-->
<!--            </exclusions>-->
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>2.2.4.RELEASE</version>
            <scope>test</scope>
        </dependency>

        <!-- LOGBACK -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>2.0.0-alpha1</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.3.0-alpha5</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.3.0-alpha5</version>
        </dependency>
    </dependencies>

我甚至不确定我是否需要这些排除,但我已经尝试了两种方式开始我的应用程序,但都没有解决问题。

下面是我的logback.xml文件:

<configuration>
<property name="LOGS" value="./logs"/>

<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${LOGS}/logFile.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
        <fileNamePattern>${LOGS}/logFile%i.log</fileNamePattern>
        <minIndex>1</minIndex>
        <maxIndex>20</maxIndex>
    </rollingPolicy>
    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
        <maxFileSize>10MB</maxFileSize>
    </triggeringPolicy>
    <encoder>
        <pattern>%date %-5level --- [%thread] - %-50logger{40} : %message %ex{short} %n</pattern>
    </encoder>
</appender>

<logger name="com.java.simeon" level="INFO">
    <appender-ref ref="FILE"/>
</logger>

<root level="INFO">
    <appender-ref ref="FILE" />
</root>

我对这个主题进行了深入研究,并发现自从 slf4j-api.1.8.x 及以后版本发布以来,不再使用 StaticLoggerBinder。根据官方的 slf4j 网站(这里这里)的说法,使用最新版本的 slf4j-api(2.x.x) 和 logback-classic(1.3.x),应该可以解决这个问题(通过使用新的 ServiceLoader 机制,并消除对 StaticLoggerBinder 的需求)。

我尝试过使用较旧版本的 slf4j-api 和 logback-classic,但没有成功。

问题是为什么我的程序需要 StaticLoggerBinder,并在我使用最新版本的 slf4j-api 和 logback-classic 的情况下抛出与之相关的异常?

如果有解决问题的建议,将不胜感激!


这个回答解决了你的问题吗?为什么在Java中会出现NoClassDefFoundError错误? - Danubian Sailor
1个回答

12

因为您正在使用Spring Boot Starter Parent的2.4.4版本。 Spring Boot使用 StaticLoggerBinder 来获取日志工厂。 在logback-classic的1.3.x版本中已删除 StaticLoggerBinder 。 以下是解决此问题的两种方法:

  1. 使用没有Spring Boot的slf4j-api(2.x.x)和logback-classic(1.3.x)版本。
  2. 使用Spring Boot的默认logback依赖项。
    <dependencies>
        <!-- omit spring boot -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>2.0.0-alpha1</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.3.0-alpha5</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.3.0-alpha5</version>
        </dependency>
    </dependencies>

1
你还依赖于Spring Boot吗?如果你想使用Logback-Classic的1.3.x版本,可以省略Spring Boot。 - BlackC
太好了!现在一切都很好。我没有意识到Spring Boot包含slf4j/Logback,我不需要它们的依赖项。我现在已经将它们移除了,只剩下Spring Boot Starter依赖项,这已经足够了。非常感谢! - Simeon Yachev
2
我不确定这会影响哪些版本的boot 2.x,但是从2.7.8开始,Spring文档表示logback默认配置为与“starters”一起使用以进行控制台输出。可选的文件输出可以添加。 https://docs.spring.io/spring-boot/docs/2.7.8/reference/html/features.html#features.logging - IchBin
1
Spring的默认日志组件是logback,当您在pom.xml中同时导入spring和logback时,可能存在多个版本的logback。这可能会导致版本兼容性问题。 - BlackC
1
选择了Spring Boot的默认Logback依赖项,解决了两个不同POM文件中StaticLoggerBinder实现冲突的问题... - solujic
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接