4

I have a maven project A that use hibernate-annotations 3.4.0.GA which use the slf4j-api version 1.5.5 (checked through the dependency tree in the pom.xml file). Further project A specifies slf4j-log4j12 version 1.4.2 as a dependency.

I have another maven project B which depend on project A. In project B I have specified the following dependencies:

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

which builds fine with maven from the command line. But when I run the project from eclipse launch configuration I get:

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

From this message its indicated to that I need to upgrade the binding in project A to 1.6.x, but I don't see how that is possible since its included in the hibernate dependency.

Is it possible to switch the binding (updating the classpath info) when running project B so it use the 1.6.1 version instead of the version from the hibernate project?

4

2 回答 2

9

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

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

SLF4J 版本是否向后兼容?

除了极少数的理论例外,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 怀疑可能存在版本不匹配问题,它会发出关于所述不匹配的警告。关于版本不匹配检测机制的具体细节,请参考本FAQ中的相关条目

这是要解决的问题。

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

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

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

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

运行项目 B 时是否可以切换绑定(更新类路径信息),以便它使用 1.6.1 版本而不是来自休眠项目的版本?

要严格回答有关在传递依赖中控制版本的问题,可以使用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,而不是两者,并提供适当的绑定。

于 2010-08-23T15:09:06.657 回答
0

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

mvn clean

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

于 2012-07-06T17:41:16.943 回答