【问题标题】:Hibernate-annotations 3.4.0.GA and slf4j?Hibernate-annotations 3.4.0.GA 和 slf4j?
【发布时间】:2011-04-02 14:14:14
【问题描述】:

我有一个使用 hibernate-annotations 3.4.0.GA 的 maven 项目 A,它使用 slf4j-api 版本 1.5.5(通过 pom.xml 文件中的依赖关系树检查)。进一步的项目 A 将 slf4j-log4j12 版本 1.4.2 指定为依赖项。

我有另一个依赖于项目 A 的 maven 项目 B。在项目 B 中,我指定了以下依赖项:

slf4j-api version 1.6.1,
logback-core version 0.9.24
logback-classic version 0.9.24

从命令行使用 maven 构建良好。但是当我从 Eclipse 启动配置运行项目时,我得到:

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/Users/mm/.m2/repository/org/slf4j/slf4j-log4j12/1.4.2/slf4j-log4j12-1.4.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/Users/mm/.m2/repository/ch/qos/logback/logback-classic/0.9.24/logback-classic-0.9.24.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: slf4j-api 1.6.x (or later) is incompatible with this binding.
SLF4J: Your binding is version 1.5.5 or earlier.
SLF4J: Upgrade your binding to version 1.6.x. or 2.0.x

从这条消息中它表明我需要将项目 A 中的绑定升级到 1.6.x,但我不知道这是怎么可能的,因为它包含在休眠依赖项中。

是否可以在运行项目 B 时切换绑定(更新类路径信息),使其使用 1.6.1 版本而不是 hibernate 项目中的版本?

【问题讨论】:

    标签: eclipse hibernate maven-2 slf4j


    【解决方案1】:

    我遇到了这个问题,但是在爬取了我的依赖树并修复了我的 pom 之后,我仍然遇到了问题。我的解决方案?

    mvn clean
    

    (以防万一其他人犯了我的错误!)

    【讨论】:

      【解决方案2】:

      我有一个使用 hibernate-annotations 3.4.0.GA 的 maven 项目 A,它使用 slf4j-api 版本 1.5.5(通过 pom.xml 文件中的依赖关系树检查)。进一步的项目 A 将 slf4j-log4j12 版本 1.4.2 指定为依赖项。

      不建议这样做,您应该使用相同版本的 slf4j 工件。来自常见问题解答:

      Are SLF4J versions backward compatible?

      除了极少数的理论例外, SLF4J 版本落后 兼容的。这意味着你不能 从 SLF4J 版本 1.0 升级到任何 以后的版本没有问题。

      然而,虽然 SLF4J API 非常 从客户的角度来看是稳定的, SLF4J 绑定,例如 slf4j-simple 或 slf4j-log4j12 可能需要特定的 slf4j-api 的版本。 混合 不同版本的 slf4j 工件 可能是有问题的并且是强烈的 气馁。例如,如果您 正在使用 slf4j-api-1.5.6.jar,然后 你也应该使用 slf4j-simple-1.5.6.jar,使用 slf4j-simple-1.4.2.jar 将不起作用。

      在初始化时,如果 SLF4J 怀疑可能有版本 不匹配问题,它会发出警告 关于所说的不匹配。对于确切的 版本不匹配的详细信息 检测机制,请参考 此常见问题解答中的relevant entry

      这是要解决的问题。

      从命令行使用 maven 构建良好。但是当我从 Eclipse 启动配置运行项目时,我得到 (...)

      问题是您从 B 从 A(传递地)获得 SLF4J 工件,因此您最终混合了 slf4j-api 的几个版本(1.5 .5 和 1.6.1)和几个绑定slf4j-log4j12logback-classic)。 SLF4J 在运行时抱怨后面的问题,但您应该同时解决这两个问题。

      从这条消息中它表明我需要将项目 A 中的绑定升级到 1.6.x,但我不知道这是怎么可能的,因为它包含在休眠依赖项中。

      是的,该消息建议将绑定升级到更新的版本。但是,更重要的是,它报告您在类路径上有多个 ONE 绑定:您需要在 log4j 和 logback 之间进行选择作为日志支持并提供适当的绑定,但不能同时提供两者。

      是否可以在运行项目 B 时切换绑定(更新类路径信息),使其使用 1.6.1 版本而不是 hibernate 项目中的版本?

      要严格回答有关在传递依赖项中控制版本的问题,可以使用dependencyManagement 元素来完成。这是一个例子:

      <project>
        ...
        <dependencyManagement>
          <dependencies>
            <dependency>
              <groupId>org.slf4j</groupId>
              <artifactId>slf4j-api</artifactId>
              <version>1.6.1</version>
            </dependency>
          </dependencies>
        </dependencyManagement>
        ...
        <dependencies>
          <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-entitymanager</artifactId>
            <version>3.4.0.GA</version>
          </dependency>
        </dependencies>
        ...
      </project>
      

      而具有slf4j-api 作为依赖项的工件,例如 Hibernate EntityManager,将使用 1.6.1 版本,如下所示:

      $ mvn 依赖:树 ... [信息] +- org.hibernate:hibernate-entitymanager:jar:3.4.0.GA:compile [信息] | +- org.hibernate:ejb3-persistence:jar:1.0.2.GA:compile [信息] | +- org.hibernate:hibernate-commons-annotations:jar:3.1.0.GA:compile [信息] | +- org.hibernate:hibernate-annotations:jar:3.4.0.GA:compile [信息] | +- org.hibernate:hibernate-core:jar:3.3.0.SP1:compile [信息] | | +- antlr:antlr:jar:2.7.6:compile [信息] | | \- commons-collections:commons-collections:jar:3.1:compile [信息] | +- org.slf4j:slf4j-api:jar:1.6.1:compile [信息] | +- dom4j:dom4j:jar:1.6.1:编译 [信息] | | \- xml-apis:xml-apis:jar:1.0.b2:compile [信息] | +- javax.transaction:jta:jar:1.1:compile [信息] | \- javassist:javassist:jar:3.4.GA:compile

      但正如我所说,真正的问题是您只需要在类路径上拥有一个绑定。选择 log4j 或 logback,而不是两者,并提供适当的绑定。

      【讨论】:

      • 我确实在依赖休眠的项目 A 上运行了 mvn 依赖:树。它表明 hibernate-annotations 版本 3.4.0.GA 使用 slf4j-api 版本 1.5.5 而不是 1.6.1。如果我理解正确,所有依赖于模块 A 的项目都应该使用与休眠相同的版本 - 1.5.5?对我来说似乎相当脆弱,所有相互依赖的项目都必须使用相同的版本。此外,在休眠更新到该版本之前,我无法使用 slf4j 1.6.1。
      • @tul:是的,所有项目都应该使用相同的版本。不,他们不必使用与 Hibernate 相同的版本。正如我告诉你的,你可以使用dependencyManagement 元素控制传递依赖项中工件的版本,我提供了一个示例。无需等待 Hibernate 更新他们使用的版本。只需使用dependencyManagement 元素即可。
      猜你喜欢
      • 2016-07-10
      • 1970-01-01
      • 2010-12-10
      • 1970-01-01
      • 1970-01-01
      • 2012-06-10
      • 2011-03-03
      • 2012-02-01
      • 1970-01-01
      相关资源
      最近更新 更多