Tomcat 10未识别SLF4J日志提供者问题排查求助
将Spring(非Boot)应用部署到Tomcat 10.1.18后,服务器日志输出如下:
SLF4J(W): No SLF4J providers were found.
SLF4J(W): Defaulting to no-operation (NOP) logger implementation
SLF4J(W): See https://www.slf4j.org/codes.html#noProviders for further details.
SLF4J(W): Class path contains SLF4J bindings targeting slf4j-api versions 1.7.x or earlier.
SLF4J(W): Ignoring binding found at [jar:file:/C:/Users/IvanKarotki/Program_Files/apache-tomcat-10.1.18/webapps/opera-agent-war/WEB-INF/lib/log4j-slf4j-impl-2.22.1.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J(W): See https://www.slf4j.org/codes.html#ignoredBindings for an explanation.
应用已迁移到Java 17和Tomcat 10兼容版本,但启动失败无可见原因,此前为Spring(非Boot)+Vaadin迁移到Tomcat10的场景。Tomcat的webapps/myapp/web-inf/lib目录已包含所有依赖jar包。
pom.xml 配置片段
<!-- Logging --> <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.4.14</version> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.tomcat/tomcat-juli --> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-juli</artifactId> <version>10.0.10</version> </dependency> <dependency> <groupId>com.github.tomcat-slf4j-logback</groupId> <artifactId>tomcat10-slf4j-logback</artifactId> <version>10.1.18</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>${log4j.version}</version> </dependency> <!-- Required to override tetris "provided" scope --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> <scope>compile</scope> </dependency> <!-- So Spring logs through LOG4J2 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>${slf4j.version}</version> <scope>compile</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-slf4j2-impl --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j2-impl</artifactId> <version>${log4j.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>${log4j.version}</version> <scope>compile</scope> </dependency>
版本属性配置
<log4j.version>2.22.1</log4j.version> <slf4j.version>2.0.11</slf4j.version>
用户疑问:
- 为何Tomcat提示未找到提供者却又忽略绑定?
- 是缺失还是被忽略?
- 如何配置完整本地日志?
一、日志报错原因解析
1. 双报错的核心原因
你使用的SLF4J API是2.0.11版本,该版本对日志绑定机制做了重大变更:
- 旧版SLF4J(1.7.x及更早)依赖
StaticLoggerBinder类识别日志实现 - 新版SLF4J 2.x改用ServiceLoader机制加载
SLF4JServiceProvider接口的实现类
而你引入的log4j-slf4j-impl-2.22.1.jar是适配SLF4J 1.x的绑定包,仅包含旧版的StaticLoggerBinder,没有新版要求的SLF4JServiceProvider实现。因此:
- SLF4J 2.x找不到符合要求的提供者,触发「No SLF4J providers were found」提示
- 同时检测到旧版绑定类,判定其与当前API版本不兼容,直接忽略,输出「Ignoring binding」
本质是绑定包版本与SLF4J API版本不匹配,既不是单纯缺失,也不是无理由忽略,是版本兼容冲突问题。
二、修复与配置步骤
1. 替换兼容的日志绑定包
移除旧的log4j-slf4j-impl依赖,改用适配SLF4J 2.x的log4j-slf4j2-impl,并将其scope从test改为compile:
<!-- 删除旧的SLF4J 1.x绑定 --> <!-- <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>${log4j.version}</version> <scope>compile</scope> </dependency> --> <!-- 使用适配SLF4J 2.x的绑定包 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j2-impl</artifactId> <version>${log4j.version}</version> <scope>compile</scope> </dependency>
2. 清理冲突依赖
- 同时引入logback和log4j2会导致日志实现冲突,建议只保留一套。若选择log4j2,可移除
logback-classic和tomcat10-slf4j-logback(后者是Tomcat自身用logback的适配包,无需则删除) - 执行
mvn dependency:tree命令排查是否有其他依赖间接引入SLF4J 1.x绑定包,如有则通过<exclusions>标签排除
3. 配置Log4j2本地日志
在src/main/resources下添加log4j2.xml配置文件,示例如下:
<?xml version="1.0" encoding="UTF-8"?> <Configuration status="INFO"> <Appenders> <!-- 控制台输出 --> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> </Console> <!-- 本地文件日志,按天滚动 --> <RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/app-%d{yyyy-MM-dd}.log"> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> <Policies> <TimeBasedTriggeringPolicy/> </Policies> </RollingFile> </Appenders> <Loggers> <!-- 根日志级别 --> <Root level="info"> <AppenderRef ref="Console"/> <AppenderRef ref="RollingFile"/> </Root> <!-- Spring相关日志可单独调整级别 --> <Logger name="org.springframework" level="warn"/> </Loggers> </Configuration>
4. 启动失败排查建议
日志无法输出导致启动失败无可见原因,修复日志配置后重新部署,查看Tomcat的catalina.out或你配置的本地日志文件,即可看到具体启动异常信息,针对性解决Spring和Vaadin迁移到Tomcat10的兼容问题(如Servlet API版本、类路径冲突等)。
内容的提问来源于stack exchange,提问作者Ivan Karotki

