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?
That’s not recommended, you should use the same versions of slf4j artifacts. From the FAQ:
That’s something to fix.
The problem is that you get the SLF4J artifacts from B and those from A (transitively) and you thus end up mixing several versions of the
slf4j-api(1.5.5 and 1.6.1) and several bindings (slf4j-log4j12andlogback-classic). SLF4J is complaining about the later problem at runtime but you should fix both.Yes, the message suggests upgrading a binding to a more recent version. But, more important, it reports that you have more than ONE binding on the class path: you need to choose between log4j and logback as logging backed and to provide the appropriate binding, but not both of them.
To strictly answer this question about controlling versions in transitive dependencies, this can be done using the
dependencyManagementelement. Here is an example:And artifacts having
slf4j-apias dependency, such as Hibernate EntityManager, would use version 1.6.1 as shown below:But as I said, the real problem is that you need to have only one binding on the classpath. Either choose log4j or logback, just not both, and provide the appropriate binding.