Scala+Akka打包Jar运行时遇"No SLF4J Providers found"问题求助
问题根源与解决方案
你的核心问题出在sbt assembly的合并策略以及冗余的SLF4J依赖配置上,以下是分步解决方法:
1. 修复Assembly合并策略,保留SLF4J提供者配置
你当前的合并策略直接丢弃了所有META-INF目录下的文件,但SLF4J 2.x是通过META-INF/services/org.slf4j.spi.SLF4JServiceProvider文件发现日志实现提供者的。logback-classic、slf4j-simple这类依赖都包含该文件,被丢弃后JVM找不到任何SLF4J实现,才会出现警告。
修改assembly/assemblyMergeStrategy,对SLF4J服务文件单独处理:
assembly/assemblyMergeStrategy := { // 保留SLF4J服务提供者文件,多个实现共存时合并内容 case PathList("META-INF", "services", "org.slf4j.spi.SLF4JServiceProvider") => MergeStrategy.concat // 丢弃无意义的META-INF文件 case PathList("META-INF", "MANIFEST.MF") => MergeStrategy.discard case PathList("META-INF", "maven", xs@_*) => MergeStrategy.discard case PathList("META-INF", "INDEX.LIST") => MergeStrategy.discard // 保留一份许可证文件 case PathList("META-INF", "LICENSE*") => MergeStrategy.first // 原有规则保留 case PathList("google", "protobuf", xs@_*) => MergeStrategy.first case PathList("module-info.class") => MergeStrategy.last case path if path.endsWith("/module-info.class") => MergeStrategy.last case PathList("reference.conf") => MergeStrategy.concat case x => val oldStrategy = (assembly/assemblyMergeStrategy).value oldStrategy(x) }
2. 清理冗余的SLF4J依赖
logback-classic已经包含slf4j-api依赖,不需要单独添加slf4j-api、slf4j-simple、slf4j-jdk14——多个SLF4J实现共存会引发冲突,导致日志加载逻辑混乱。
从libraryDependencies中删除后来添加的三个SLF4J依赖,仅保留"ch.qos.logback" % "logback-classic" % "1.5.16"即可。
3. 确保配置文件位置正确
logback.xml必须放在src/main/resources目录下,才能被打包进Jar根路径,让logback自动加载。application.conf同样要放在src/main/resources目录下,确保Akka能读取到日志配置。
最终验证步骤
- 执行
sbt clean assembly重新打包,确保所有修改生效。 - 运行Jar包:
java -jar JAR_NAME.jar,此时SLF4J警告会消失,Akka和Hibernate的日志都能正常输出。
内容的提问来源于stack exchange,提问作者Kris Rice
相关产品推荐
相关产品推荐

