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.
That's not recommended, you should use the same versions of slf4j artifacts. From the FAQ:
With rare theoretical exceptions,
SLF4J versions are backward
compatible. This means than you can
upgrade from SLF4J version 1.0 to any
later version without problems.
However, while the SLF4J API is very
stable from the client's perspective,
SLF4J bindings such as slf4j-simple or
slf4j-log4j12 may require a specific
version of slf4j-api. Mixing
different versions of slf4j artifacts
can be problematic and is strongly
discouraged. For instance, if you
are using slf4j-api-1.5.6.jar, then
you should also use
slf4j-simple-1.5.6.jar, using
slf4j-simple-1.4.2.jar will not work.
At initialization time, if SLF4J
suspects that there may be a version
mismatch problem, it emits a warning
about the said mismatch. For the exact
details of the version mismatch
detection mechanism, please refer to
the relevant entry in this FAQ.
That's something to fix.
which builds fine with maven from the command line. But when I run the project from eclipse launch configuration I get (...)
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-log4j12
and logback-classic
). SLF4J is complaining about the later problem at runtime but you should fix both.
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.
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.
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?
To strictly answer this question about controlling versions in transitive dependencies, this can be done using the dependencyManagement
element. Here is an example:
<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>
And artifacts having slf4j-api
as dependency, such as Hibernate EntityManager, would use version 1.6.1 as shown below:
$ mvn dependency:tree
...
[INFO] +- org.hibernate:hibernate-entitymanager:jar:3.4.0.GA:compile
[INFO] | +- org.hibernate:ejb3-persistence:jar:1.0.2.GA:compile
[INFO] | +- org.hibernate:hibernate-commons-annotations:jar:3.1.0.GA:compile
[INFO] | +- org.hibernate:hibernate-annotations:jar:3.4.0.GA:compile
[INFO] | +- org.hibernate:hibernate-core:jar:3.3.0.SP1:compile
[INFO] | | +- antlr:antlr:jar:2.7.6:compile
[INFO] | | \- commons-collections:commons-collections:jar:3.1:compile
[INFO] | +- org.slf4j:slf4j-api:jar:1.6.1:compile
[INFO] | +- dom4j:dom4j:jar:1.6.1:compile
[INFO] | | \- xml-apis:xml-apis:jar:1.0.b2:compile
[INFO] | +- javax.transaction:jta:jar:1.1:compile
[INFO] | \- javassist:javassist:jar:3.4.GA:compile
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.