Play 2.3.8 的多个 SLF4J 绑定
Multiple SLF4J bindings with Play 2.3.8
我将 Play Framework 2.3.8(针对 Java)与 Scala 2.11 一起使用。
我收到此警告:
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/Users/vdanylchuk/.ivy2/cache/org.slf4j/slf4j-simple/jars/slf4j-simple-1.7.7.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/Users/vdanylchuk/.ivy2/cache/ch.qos.logback/logback-classic/jars/logback-classic-1.0.13.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
这会在 运行 时间以随机方式导致真正的问题。在一些部署的主机上,一切顺利,日志按照配置写入。在其他主机上,错误的绑定获胜,日志被写入错误的位置。部署过程是脚本化的,完全一样。所以 http://www.slf4j.org/codes.html#multiple_bindings 处的警告是正确的,这是随机的,所以我需要删除额外的绑定。
有趣的是,它们都来自 Play 框架。 logback-classic(我其实很想用)来自play库,slf4j-simple来自play sbt插件。
我在这里和邮件列表中阅读了很多类似的问题。例子:
How to fix "SLF4J: Class path contains multiple SLF4J bindings" at startup of Play 2.3.x?
常见的解决方案是使用某种形式的排除规则。 None 的建议解决方案对我有用。 [更新:事实上,它们确实存在——请参阅下面的解决方案。]我不希望 slf4j-simple 出现在最终的类路径中,但它确实出现了。尽管我将 excludeAll(ExclusionRule(organization = "org.slf4j")) 添加到项目中的每个依赖项中,但播放框架除外。
关于如何摆脱 slf4j-simple 的任何想法?最好在 sbt 项目级别,无需手动清理构建结果的类路径。
更新:复现说明
我已经通过一个小的测试项目缩小了范围。原来它是由 play sbt 插件和我们使用的 aether-deploy 插件的组合触发的。有这个小配置就够了。
build.sbt:
name := "slf4j-test"
version := "1.0"
scalaVersion := "2.11.5"
lazy val root = (project in file(".")).enablePlugins(PlayJava)
project/plugins.sbt:
resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.3.8")
addSbtPlugin("no.arktekk.sbt" % "aether-deploy" % "0.13")
project/build.属性:
sbt.version=0.13.7
然后只需 运行 "sbt test:compile" 或 "sbt run"(并查询 localhost:9000)即可看到警告。它与 scala 2.10 相同。
我的错。最后,project/plugins.sbt 中的一个简单排除解决了这个问题:
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.3.8" exclude("org.slf4j", "slf4j-simple"))
我之前尝试过,但显然犯了一个语法错误,并认为这不受支持。 捂脸
我最终不得不做一些与我在另一个 post 中看到的有所不同的事情。把它放在这里以防任何搜索可怕的多重绑定的人首先点击这个页面:
How to fix "SLF4J: Class path contains multiple SLF4J bindings" at startup of Play 2.3.x?
libraryDependencies ++= Seq(
...
).map(_.force())
libraryDependencies ~= { _.map(_.exclude("org.slf4j", "slf4j-nop")) }
我将 Play Framework 2.3.8(针对 Java)与 Scala 2.11 一起使用。
我收到此警告:
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/Users/vdanylchuk/.ivy2/cache/org.slf4j/slf4j-simple/jars/slf4j-simple-1.7.7.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/Users/vdanylchuk/.ivy2/cache/ch.qos.logback/logback-classic/jars/logback-classic-1.0.13.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
这会在 运行 时间以随机方式导致真正的问题。在一些部署的主机上,一切顺利,日志按照配置写入。在其他主机上,错误的绑定获胜,日志被写入错误的位置。部署过程是脚本化的,完全一样。所以 http://www.slf4j.org/codes.html#multiple_bindings 处的警告是正确的,这是随机的,所以我需要删除额外的绑定。
有趣的是,它们都来自 Play 框架。 logback-classic(我其实很想用)来自play库,slf4j-simple来自play sbt插件。
我在这里和邮件列表中阅读了很多类似的问题。例子: How to fix "SLF4J: Class path contains multiple SLF4J bindings" at startup of Play 2.3.x? 常见的解决方案是使用某种形式的排除规则。 None 的建议解决方案对我有用。 [更新:事实上,它们确实存在——请参阅下面的解决方案。]我不希望 slf4j-simple 出现在最终的类路径中,但它确实出现了。尽管我将 excludeAll(ExclusionRule(organization = "org.slf4j")) 添加到项目中的每个依赖项中,但播放框架除外。
关于如何摆脱 slf4j-simple 的任何想法?最好在 sbt 项目级别,无需手动清理构建结果的类路径。
更新:复现说明
我已经通过一个小的测试项目缩小了范围。原来它是由 play sbt 插件和我们使用的 aether-deploy 插件的组合触发的。有这个小配置就够了。
build.sbt:
name := "slf4j-test"
version := "1.0"
scalaVersion := "2.11.5"
lazy val root = (project in file(".")).enablePlugins(PlayJava)
project/plugins.sbt:
resolvers += "Typesafe repository" at "http://repo.typesafe.com/typesafe/releases/"
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.3.8")
addSbtPlugin("no.arktekk.sbt" % "aether-deploy" % "0.13")
project/build.属性:
sbt.version=0.13.7
然后只需 运行 "sbt test:compile" 或 "sbt run"(并查询 localhost:9000)即可看到警告。它与 scala 2.10 相同。
我的错。最后,project/plugins.sbt 中的一个简单排除解决了这个问题:
addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.3.8" exclude("org.slf4j", "slf4j-simple"))
我之前尝试过,但显然犯了一个语法错误,并认为这不受支持。 捂脸
我最终不得不做一些与我在另一个 post 中看到的有所不同的事情。把它放在这里以防任何搜索可怕的多重绑定的人首先点击这个页面:
How to fix "SLF4J: Class path contains multiple SLF4J bindings" at startup of Play 2.3.x?
libraryDependencies ++= Seq(
...
).map(_.force())
libraryDependencies ~= { _.map(_.exclude("org.slf4j", "slf4j-nop")) }