Log4J version mismatch causing Hibernate runtime exception

Problem:

When using Hibernate API in an EJB application, the following exception occurs during runtime.

java.lang.NoSuchFieldError: org/apache/log4j/Level.TRACELorg/apache/log4j/Level;
    at org.jboss.logging.Log4jLogger.translate(Log4jLogger.java:64)
    at org.jboss.logging.Log4jLogger.isEnabled(Log4jLogger.java:39)
    at org.jboss.logging.Logger.logv(Logger.java:1953)
    at org.hibernate.internal.CoreMessageLogger_$logger.tracev(CoreMessageLogger_$logger.java:443)
    at org.hibernate.cfg.EJB3DTDEntityResolver.resolveEntity(EJB3DTDEntityResolver.java:58)
    at weblogic.xml.jaxp.ChainingEntityResolver.resolveEntity(ChainingEntityResolver.java:87)
    at weblogic.xml.jaxp.ChainingEntityResolver.resolveEntity(ChainingEntityResolver.java:87)

Solution:

The problem occurs because the Log4J version (1.2.8) specified in the server classpath, which is loaded by System Classloader, is different from the Log4J needed (in this case 1.2.12) by that specific Hibernate version (or dependant libraries). This can be fixed by requesting the Application Classloader specifically to load the Log4J packaged with the application.

In order to fix this in an application running on Weblogic, please see documentation for details:

β€œTo configure the FilteringClassLoader to specify a certain package is loaded from an application, add a prefer-application-packages descriptor element to the weblogic-application.xml which details the list of packages to be loaded from the application. The following example specifies that org.apache.log4j.* and antlr.* packages are loaded from the application, not the system classloader:

<prefer-application-packages>
  <package-name>org.apache.log4j.*</package-name>
  <package-name>antlr.*</package-name>
</prefer-application-packages>”
Written on March 19, 2012