【问题标题】:Multiple SLF4J bindings with Play 2.3.8Play 2.3.8 的多个 SLF4J 绑定
【发布时间】:2015-06-21 06:18:40
【问题描述】:

我将 Play Framework 2.3.8(用于 Java)与 Scala 2.11 一起使用。

我收到此警告:

SLF4J:类路径包含多个 SLF4J 绑定。
SLF4J:在 [jar:file:/Users/vdanylchuk/.ivy2/cache/org.slf4j/slf4j-simple/jars/slf4j-simple-1.7.7.jar!/org/slf4j/impl/StaticLoggerBinder.class 中找到绑定]
SLF4J:在 [jar:file:/Users/vdanylchuk/.ivy2/cache/ch.qos.logback/logback-classic/jars/logback-classic-1.0.13.jar!/org/slf4j/impl/StaticLoggerBinder 中找到绑定.class]
SLF4J:请参阅http://www.slf4j.org/codes.html#multiple_bindings 以获得解释。

这会以随机方式在运行时导致真正的问题。在一些已部署的主机上,一切顺利,日志按照配置写入。在其他主机上,错误的绑定获胜,日志写入错误的位置。部署过程是脚本化的并且完全相同。所以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? 常见的解决方案是使用某种形式的排除规则。建议的解决方案都不适合我。 [更新:事实上,他们确实这样做了——请参阅下面的解决方案。] 我不希望 slf4j-simple 出现在最终的类路径中,但确实如此。尽管我将 excludeAll(ExclusionRule(organization = "org.slf4j")) 添加到项目中的每个依赖项中,但 play 框架除外。

关于如何摆脱 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)


项目/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")


项目/build.properties:

sbt.version=0.13.7

然后只需运行“sbt test:compile”或“sbt run”(并查询 localhost:9000)即可查看警告。它与 scala 2.10 相同。

【问题讨论】:

  • 一个简单的解决方案是将其从类路径中排除,而不是从依赖项中排除:externalDependencyClasspath in Compile ~= (_.filterNot(_.data.toString.contains("slf4j-simple"))) 但感觉有点“脏”...
  • @giladhoch 不幸的是,这无济于事。 slf4j-simple 没有出现在 externalDependencyClasspath 中。我只能从 ~/.ivy2/cache 中的 xml 文件中跟踪它的依赖链。
  • 所以请改用fullClasspath
  • @giladhoch 是的,我也尝试了 fullClasspath。它也不在那里。

标签: scala playframework sbt aether


【解决方案1】:

我的错。最后,在 project/plugins.sbt 中的一个简单排除解决了这个问题:

addSbtPlugin("com.typesafe.play" % "sbt-plugin" % "2.3.8" exclude("org.slf4j", "slf4j-simple"))

我之前尝试过,但显然犯了语法错误,并认为这不受支持。 掌心

【讨论】:

    【解决方案2】:

    我最终不得不做一些我在另一篇文章中看到的有点不同的事情。把它放在这里,以防任何搜索可怕的多重绑定的人首先点击这个页面:

    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")) }
    

    【讨论】:

      猜你喜欢
      • 2018-07-10
      • 2012-09-28
      • 2016-01-09
      • 2015-04-24
      • 1970-01-01
      • 2012-12-11
      • 2017-05-26
      • 2016-03-12
      • 2014-05-18
      相关资源
      最近更新 更多