21

I realised that one of my projects uses slf4j 1.5.8 and Hibernate uses slf4j 1.6. While building with Maven it downloads both jars but I guess the class files of 1.5.8 are used. So, when I run the program i get following error:

SLF4J: The requested version 1.5.8 by your slf4j binding is not compatible with [1.6]

In pom.xml I have put

<dependencyManagement>    
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.6.1</version>
    </dependency>
</dependencyManagement>

The 1.5.8 is part of dependency so it's downloaded on its own.

Kalle Richter
  • 8,008
  • 26
  • 77
  • 177
harshit
  • 7,925
  • 23
  • 70
  • 97

3 Answers3

27

As you discovered yourself, there are two libraries (Hibernate and some other) transitively importing SLF4J in two different versions. Unfortunately the older version is being picked up by maven (there are some rules which dependency should be chosen by maven in this situation). The solution is to add the exclusion in the dependency that imports older version of SLF4J (com.example:foo-bar is example here):

<dependency>
  <groupId>com.example</groupId>
  <artifactId>foo-bar</artifactId>
  <version>1.2.3</version>
   <exclusions>
     <exclusion>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
     </exclusion>
   </exclusions>
</dependency>

If you still experience this problem, issue:

$ mvn dependency:tree

Look for 1.5.8 version and exclude it from all libraries importing it.

Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • 4
    Excluding is quite unnecessary. Instead, explicitly include the slf4j-api with the desired version in your projects pom file. That's it! – Ceki Mar 30 '11 at 07:24
  • 2
    @Ceki If you don't exclude you can't be sure which version is picked up first. – Kalle Richter Jul 15 '17 at 18:09
8

Excluding is quite unnecessary and maybe quite misleading. Instead, explicitly include the slf4j-api with the desired version in your projects pom file. That's it!

This approach takes advantage of Maven's transitivity rules: the nearest dependency declaration wins.

Ceki
  • 26,753
  • 7
  • 62
  • 71
  • 2
    This doesn't work for me: I have to exclude the transient dependency so I can specify my own. – end-user Oct 28 '11 at 13:51
  • 3
    @Ceki could you comment on end-user's experience? Should this be possible without excluding? – Traveler Sep 09 '12 at 16:08
  • It may be unnecessary but its documentation, it shows the users that you've altered a library that your other library expects. If theres an error there then it is clearer. – Wes Mar 16 '16 at 10:44
  • You are making assumptions which maybe incorrect, in particular you are not excluding a specific version whereas with my proposal you are including a specific version. – Ceki Mar 16 '16 at 17:39
1

you can exclude the wrong version with something like this:

<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate</artifactId>
  <version>3.2.7.ga</version>
  <exclusions>
    <exclusion>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
    </exclusion>
  </exclusions>
</dependency>