Problem
When working with Hibernate 5 in JBoss EAP 6.4 you can get the following error:
java.lang.NoSuchMethodError: org.jboss.logging.Logger.debugf(Ljava/lang/String;I)V
Caused by: java.lang.NoSuchMethodError: org.jboss.logging.Logger.debugf(Ljava/lang/String;I)V
at org.hibernate.internal.NamedQueryRepository.checkNamedQueries(NamedQueryRepository.java:149)
at org.hibernate.internal.SessionFactoryImpl.checkNamedQueries(SessionFactoryImpl.java:769)
at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:484)
at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:444)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:708)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:724)
at org.springframework.orm.hibernate5.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:416)
at org.springframework.orm.hibernate5.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:401)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1637)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574)
Cause
The root cause is that Hibernate 5 requires
jboss-logging-3.3.0.Final.jar library, while JBoss EAP packs
jboss-logging-3.1.4.GA-redhat-2.jar. This error is produced when NamedQueryRepository class is trying to call the
debugf(String format, Object param1) method of
org.jboss.logging.Logger class.
This method exists in version 3.3.0 but not in version 3.1.4. As Jboss loads the former one, there is one incompatibiltiy.
This is the hibernate code which calls this method,
org.hibernate.internal.NamedQueryRepository:
And this is the method implementation in
org.jboss.logging.Logger:
Jboss EAP 6.4 is integrated with hibernate-core-4.2.18.Final (
https://access.redhat.com/articles/112673#EAP_6), which in turn required jboss-logging-3.1.0 (
https://mvnrepository.com/artifact/org.hibernate/hibernate-core/4.2.18.Final)
Solution
In thease cases the solution is obvious. Just use jboss-deployment-structure and exclude Hibernate and Logging stuff in order to use all dependencies packet in the application´s lib directory. So, the first guess would be something like this:
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
<deployment>
<exclude-subsystems>
<subsystem name="jpa" />
<subsystem name="logging" />
</exclude-subsystems>
<exclusions>
<module name="org.hibernate"/>
<module name="javax.persistence.api"/>
<module name="org.hibernate.envers"/>
<module name="org.hibernate.validator"/>
<module name="org.hibernate.commons-annotations"/>
<module name="org.jboss.as.jpa.hibernate"/>
<module name="org.jboss.as.jpa"/>
<module name="org.jboss.as.jpa.util"/>
<module name="org.jboss.as.jpa.hibernate "/>
<module name="org.jboss.as.jpa.spi"/>
<module name="org.jboss.as.osgi.jpa"/>
<module name="org.jboss.logging" />
<module name="org.apache.commons.logging" />
<module name="org.apache.log4j" />
<module name="org.slf4j" />
<module name="org.jboss.logging.jul-to-slf4j-stub" />
</exclusions>
</deployment>
</jboss-deployment-structure>
Unfortunately this doesn't work. There must be some kind of bug in Jboss EAP 6.4 and jboss-logging 3.1.0 is still be using. For the record, this do works with Jboss EAP 6.2.
After some digging, the solution appears to be to exclude org.jboss.resteasy.resteasy-jaxrs too. The final jboss-deployment-structure will be this:
<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure>
<deployment>
<exclude-subsystems>
<subsystem name="jpa" />
<subsystem name="logging" />
</exclude-subsystems>
<exclusions>
<module name="org.jboss.resteasy.resteasy-jaxrs"/>
<module name="org.hibernate"/>
<module name="javax.persistence.api"/>
<module name="org.hibernate.envers"/>
<module name="org.hibernate.validator"/>
<module name="org.hibernate.commons-annotations"/>
<module name="org.jboss.as.jpa.hibernate"/>
<module name="org.jboss.as.jpa"/>
<module name="org.jboss.as.jpa.util"/>
<module name="org.jboss.as.jpa.hibernate "/>
<module name="org.jboss.as.jpa.spi"/>
<module name="org.jboss.as.osgi.jpa"/>
<module name="org.jboss.logging" />
<module name="org.apache.commons.logging" />
<module name="org.apache.log4j" />
<module name="org.slf4j" />
<module name="org.jboss.logging.jul-to-slf4j-stub" />
</exclusions>
</deployment>
</jboss-deployment-structure>