You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从sbt发布的jar包中排除logback-classic日志传递依赖

Scala类库SLF4J依赖配置最优方案

不要使用全局exclude()处理logback依赖,该方式无法同时满足本地开发日志输出、发布不传递绑定依赖、assembly打包内置实现三个核心需求,按以下步骤配置即可完全符合SLF4J官方规范:

基础依赖配置

在build.sbt中按作用域声明依赖:

  • slf4j-api作为常规编译依赖,随构件对外传递,符合类库依赖要求
  • logback-classic声明为Provided作用域,该作用域的依赖在本地sbt runMain、testOnly、IntelliJ运行/调试场景下会自动加入类路径,可正常输出日志;同时发布构件生成的pom文件中,该依赖为provided范围,不会作为传递依赖被下游用户拉取,不会强制用户使用指定日志实现
libraryDependencies ++= Seq(
  "org.slf4j" % "slf4j-api" % "2.0.9",
  "ch.qos.logback" % "logback-classic" % "1.4.11" % Provided
)

注意:不要将logback-classic放在Test作用域下,该作用域的依赖仅在测试阶段可用,sbt runMain启动应用时类路径中无日志实现,会出现SLF4J无绑定的警告,无法输出日志。

sbt-assembly打包适配

sbt-assembly插件默认会排除Provided作用域的依赖,因此添加以下配置,定向将logback相关依赖加入fat jar,其余Provided依赖仍保持默认排除逻辑,避免不必要的包打入可执行jar:

// sbt-assembly 2.x 版本适配
assembly / assemblyMergedJars := {
  val (providedJars, regularJars) = (assembly / assemblyFullClasspath).value
    .partition(_.configuration.contains(Provided.name))
  val logbackIncluded = providedJars.filter { jar =>
    jar.get(moduleID.key).exists(mod => mod.organization == "ch.qos.logback")
  }
  regularJars ++ logbackIncluded
}

效果核验

配置完成后可满足所有需求:

  • 本地开发:IntelliJ导入项目、sbt执行runMain启动应用、testOnly跑单元测试时,logback正常生效,日志按配置输出
  • 构件发布:下游用户引入你的类库时,不会传递拉取logback-classic,用户可自由选择任意SLF4J绑定实现,完全符合官方规范
  • 可执行包:sbt assembly生成的fat jar内置logback实现,直接通过java -jar启动即可正常输出日志,无需额外添加日志依赖

类库、框架这类嵌入式组件不应声明对任何SLF4J绑定/实现提供者(如logback-classic)的依赖,仅需依赖slf4j-api即可。若类库声明了对特定SLF4J绑定的传递依赖,相当于将该绑定强制强加给终端用户,违背了SLF4J的设计初衷。注意,声明绑定的非传递依赖(例如仅用于测试场景)不会对终端用户造成影响。

内容的提问来源于stack exchange,提问作者Keith Alcock

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 23:48:39