使用sbt-assembly构建über-JAR后Logback日志失效问题求助
问题解决:sbt-assembly构建的Uber-JAR运行时SLF4J无Provider错误
问题原因
你的sbt-assembly合并策略中,将所有META-INF目录下的文件都设置为MergeStrategy.discard,但SLF4J用来识别日志实现的服务注册文件就在META-INF/services目录下(具体是org.slf4j.spi.SLF4JServiceProvider),这个文件由logback-classic提供,被丢弃后SLF4J找不到对应的日志实现,就会默认使用无操作(NOP)日志器。
修复方案
修改assemblyMergeStrategy,不要全盘丢弃META-INF下的内容,针对不同子目录做差异化处理:保留META-INF/services下的服务注册文件(若多个依赖提供同类文件,用MergeStrategy.concat合并),仅丢弃不需要的META-INF文件(如签名文件、MANIFEST等)。
修改后的sbt配置如下:
lazy val app = (project in file(".")) .settings( assembly / mainClass := Some("com.example.app.Main"), assembly / assemblyJarName := "gcm.jar", assembly / assemblyMergeStrategy := { case PathList("META-INF", "services", xs@_*) => MergeStrategy.concat // 合并服务注册文件 case PathList("META-INF", "MANIFEST.MF") => MergeStrategy.discard // 丢弃MANIFEST文件 case PathList("META-INF", xs@_*) if xs.exists(_.matches(".*\\.(SF|DSA|RSA)$")) => MergeStrategy.discard // 丢弃签名文件 case PathList("reference.conf") => MergeStrategy.concat case x => MergeStrategy.first } )
验证步骤
- 重新执行
sbt assembly构建Uber-JAR - 运行生成的
gcm.jar,此时SLF4J可正常识别logback实现,日志功能恢复正常
内容的提问来源于stack exchange,提问作者Hannes
相关产品推荐
相关产品推荐

