使用log4j-over-slf4j遇No SLF4J providers found错误的解决咨询
错误原因
你碰到的问题核心是对log4j-over-slf4j的定位理解偏差:它不是SLF4J的日志实现(Provider),只是一个桥接器——作用是把原有基于log4j 1.x API的调用,转换为SLF4J的API调用。
而SLF4J本身只是日志门面,必须搭配一个实际的日志实现(Provider)才能输出日志。你当前只配置了slf4j-api(门面)和log4j-over-slf4j(桥接器),没有真正的日志实现,所以SLF4J找不到Provider,只能默认用无输出的NOP实现。而slf4j-simple本身就是轻量的SLF4J Provider,所以添加后能正常输出。
正确配置方案
分两种场景给出配置:
场景1:你的代码直接用SLF4J API(如你当前的App代码)
如果你的业务代码本身就是基于SLF4J的Logger和LoggerFactory编写的,完全不需要log4j-over-slf4j,直接给SLF4J配一个日志实现即可。
比如选reload4j(log4j 1.x的官方替代),修改build.gradle的依赖:
dependencies { compile 'org.slf4j:slf4j-api:2.0.7' // SLF4J到reload4j的绑定(即日志实现) compile 'org.slf4j:slf4j-reload4j:2.0.7' }
然后在src/main/resources下添加log4j配置文件log4j.properties,示例配置:
# 根日志级别 log4j.rootLogger=ERROR, stdout # 控制台输出配置 log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
场景2:有旧代码用log4j 1.x API,需转接至SLF4J
如果项目里存在直接调用log4j 1.x API的旧代码(比如org.apache.log4j.Logger),想通过SLF4J统一日志体系,才需要用到log4j-over-slf4j。
步骤1:清理冲突依赖
确保项目中没有直接引入log4j:log4j的依赖,避免和桥接器冲突。
步骤2:添加依赖组合
比如用logback作为最终的日志实现(性能更好,推荐):
dependencies { compile 'org.slf4j:slf4j-api:2.0.7' // 桥接log4j 1.x API到SLF4J compile 'org.slf4j:log4j-over-slf4j:2.0.7' // SLF4J的日志实现:logback compile 'ch.qos.logback:logback-classic:1.4.8' }
如果坚持用log4j系的实现,也可以选reload4j:
dependencies { compile 'org.slf4j:slf4j-api:2.0.7' // 桥接log4j 1.x API到SLF4J compile 'org.slf4j:log4j-over-slf4j:2.0.7' // SLF4J到reload4j的绑定 compile 'org.slf4j:slf4j-reload4j:2.0.7' }
步骤3:添加配置文件
- 用logback的话,在
src/main/resources下添加logback.xml; - 用reload4j的话,添加
log4j.properties(参考场景1的示例)。
关键注意事项
- 绝对不要同时添加
log4j-over-slf4j和slf4j-log4j12:前者是把log4j转成SLF4J,后者是把SLF4J转成log4j,同时存在会触发循环调用,导致异常。 - SLF4J相关依赖的版本必须保持一致:你用的是2.0.7,所以
slf4j-api、log4j-over-slf4j、slf4j-reload4j等都要对应2.x版本。
内容的提问来源于stack exchange,提问作者AlexA

