Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate 3.4 with slf4j and log4j

I'm attempting to upgrade from Hibernate 3.2 to 3.4, which apparently uses slf4j. Our project currently uses log4j. So my assumption is that I should be using the slf4j-log4j12 wrapped implementation.

The Maven slf4j dependency is:

<dependency>
    <groupId>org.slf4j</groupId>
     <artifactId>slf4j-log4j12</artifactId>
    <version>1.5.6</version>
</dependency>

While the log4j dependency is:

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.15</version>
</dependency>

Both slf4j-log4j12 and log4j reference the latest version (that I could find in the Maven repository). When I run my app, Hibernate fails in its logging:

java.lang.NoSuchFieldError: name
    at org.slf4j.impl.Log4jLoggerAdapter.<init>(Log4jLoggerAdapter.java:75)
    at org.slf4j.impl.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:75)
    at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:103)
    at org.hibernate.cfg.Configuration.<clinit>(Configuration.java:163)
    ...

What am I missing?

Edit 1: If I remove the log4j dependency from my pom.xml I get the error:

java.lang.IllegalAccessError: tried to access field org.slf4j.impl.StaticLoggerBinder.SINGLETON from class org.slf4j.LoggerFactory
    at org.slf4j.LoggerFactory.<clinit>(LoggerFactory.java:60)
    at org.hibernate.cfg.Configuration.<clinit>(Configuration.java:163)
    ...

Edit 2: This blog claims the problem is caused by hibernate annotations shipping with the wrong version of slf4j-api.jar.

like image 408
Steve Kuo Avatar asked Jan 22 '09 02:01

Steve Kuo


People also ask

Can we use log4j and SLF4J together?

So essentially, SLF4J does not replace log4j; they both work together. It removes the dependency on log4j from your application and makes it easy to replace it in the future with the more capable library.

What version of log4j does SLF4J use?

SLF4J Binding Using Log4j – Log4j 2 SLF4J Binding.

Can SLF4J work without log4j?

Conclusion. So essentially, SLF4J does not replace Log4j, Both work together. SLF4j removes the tight coupling between the application and logging frameworks. It makes it easy to replace with any other logging framework in the future with a more capable library.


4 Answers

i have no problems with

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>3.3.1.GA</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-annotations</artifactId>
        <version>3.4.0.GA</version>
    </dependency>

and

     <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.5.6</version>
    </dependency>
    <!-- concrete Log4J Implementation for SLF4J API-->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.5.6</version>
    </dependency>
like image 99
Michael Pralow Avatar answered Oct 06 '22 06:10

Michael Pralow


This question is answered by the SLF4J FAQ. Please see

http://slf4j.org/faq.html#compatibility and http://slf4j.org/faq.html#IllegalAccessError

like image 36
Ceki Avatar answered Oct 06 '22 07:10

Ceki


I think you need to exclude the built-in SLF4J dependency from each of the Hibernate dependencies.

I use Hibernate with JPA, so my config isn't identical, but I think the crucial thing is to explicitly include log4j and SLF4J and explicitly exclude slf4j-api from all org.hibernate dependencies:

    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.15</version>
        <scope>compile</scope>
        <exclusions>
            <exclusion>
                <groupId>com.sun.jmx</groupId>
                <artifactId>jmxri</artifactId>
            </exclusion>
            <exclusion>
                <groupId>javax.jms</groupId>
                <artifactId>jms</artifactId>
            </exclusion>
            <exclusion>
                <groupId>com.sun.jdmk</groupId>
                <artifactId>jmxtools</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-annotations</artifactId>
        <version>3.4.0.GA</version>
        <exclusions>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
            </exclusion>
        </exclusions>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>3.4.0.GA</version>
        <exclusions>
            <exclusion>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
            </exclusion>
        </exclusions>
        <scope>compile</scope>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.5.6</version>
        <scope>runtime</scope>
    </dependency>
like image 24
James Shade Avatar answered Oct 06 '22 05:10

James Shade


After checking the version 1.5.6 POM for slf4j-log4j (and then slf4j-parent) you should be using log4j-1.2.14. The slf4j-log4j POM uses dependency management to inherit the appropriate version of log4j from the slf4j-parent POM.

You shouldn't, however, need to include log4j as a specific dependency as it is already a dependency of slf4j-log4j. That may have been where you caused your problem.

like image 35
Michael Rutherfurd Avatar answered Oct 06 '22 07:10

Michael Rutherfurd