The problem
I’m having trouble trying to make Hibernate run in a project that have modules. I am trying to modernize an old tool that uses and old version of Hibernate with javax-based JPA and I am trying to migrate it to a newer version and make it jakarta-based.
Long story short, it fails with ExceptionInInitializerError
when trying to instantiate the HibernatePersistenceProvider
class due to some module problem when handling JBoss Logging. The tool use the HibernatePersistenceProvider
to call the createContainerEntityManagerFactory
method.
In order to isolate the problem, I built a MCVE.
MCVE
I’m using Gradle 8.10.2 and Java 23. All the other package versions are in the gradle.build
file.
This is the build.gradle
file:
plugins {
id("java-library")
id("project-report")
}
description = "MCVE for a problem in Hibernate"
group = "com.example"
version = "1.0"
def artifactName = "com.example"
def moduleName = "com.example"
def versionApiguardian = "1.1.2"
def versionHibernate = "7.0.0.Beta1"
def versionJakartaAnno = "3.0.0"
def versionJakartaCdi = "4.1.0"
def versionJakartaEl = "6.0.1"
def versionJakartaInj = "2.0.1"
def versionJakartaInt = "2.2.0"
def versionJakartaJpa = "3.2.0"
def versionJakartaJta = "2.0.1"
def versionJBossLog = "3.6.1.Final"
def versionJunit = "5.11.2"
def versionJunitPlatf = "1.11.2"
dependencies {
// Jakarta, JPA and friends.
testImplementation(group: "jakarta.annotation" , name: "jakarta.annotation-api" , version: versionJakartaAnno)
testImplementation(group: "jakarta.enterprise" , name: "jakarta.enterprise.cdi-api" , version: versionJakartaCdi )
testImplementation(group: "jakarta.enterprise" , name: "jakarta.enterprise.lang-model", version: versionJakartaCdi )
testImplementation(group: "jakarta.persistence", name: "jakarta.persistence-api" , version: versionJakartaJpa )
testImplementation(group: "jakarta.transaction", name: "jakarta.transaction-api" , version: versionJakartaJta )
testImplementation(group: "jakarta.inject" , name: "jakarta.inject-api" , version: versionJakartaInj )
testImplementation(group: "jakarta.interceptor", name: "jakarta.interceptor-api" , version: versionJakartaInt )
testImplementation(group: "jakarta.el" , name: "jakarta.el-api" , version: versionJakartaEl )
// JUnit.
testImplementation(group: "org.junit.platform", name: "junit-platform-launcher", version: versionJunitPlatf )
testImplementation(group: "org.junit.jupiter" , name: "junit-jupiter-api" , version: versionJunit )
testImplementation(group: "org.junit.jupiter" , name: "junit-jupiter-params" , version: versionJunit )
testImplementation(group: "org.junit.jupiter" , name: "junit-jupiter-engine" , version: versionJunit )
testImplementation(group: "org.apiguardian" , name: "apiguardian-api" , version: versionApiguardian)
// Hibernate.
testImplementation(group: "org.hibernate.orm", name: "hibernate-core", version: versionHibernate)
// JBoss Logging.
testImplementation(group: "org.jboss.logging", name: "jboss-logging", version: versionJBossLog)
}
repositories {
mavenLocal()
mavenCentral()
gradlePluginPortal()
}
tasks.withType(JavaCompile) {
options.encoding = "UTF-8"
options.debug = true
options.fork = true
options.compilerArgs << "-parameters"
doFirst {
options.compilerArgs += [
"--module-path", classpath.asPath
]
classpath = files()
}
}
test {
useJUnitPlatform()
defaultCharacterEncoding = "UTF-8"
testLogging.showStandardStreams = true
}
And, here is the /src/test/java/module-info.java
file:
open module com.example {
requires org.hibernate.orm.core;
requires org.junit.jupiter.api;
}
And here is the /src/test/java/com/example/SomeTest.java
file:
package com.example;
import org.hibernate.jpa.HibernatePersistenceProvider;
import org.junit.jupiter.api.Test;
public class SomeTest {
@Test
public void testIt() {
new HibernatePersistenceProvider();
}
}
Running that with this command line:
gradle build --info
Will produce this inside all the output:
SomeTest > testIt() FAILED
java.lang.ExceptionInInitializerError
at com.example/com.example.SomeTest.testIt(SomeTest.java:9)
Caused by:
java.lang.IllegalArgumentException: This library does not have private access to interface org.hibernate.internal.EntityManagerMessageLogger
at org.jboss.logging@3.6.1.Final/org.jboss.logging.Logger.getMessageLogger(Logger.java:2572)
at org.jboss.logging@3.6.1.Final/org.jboss.logging.Logger.getMessageLogger(Logger.java:2552)
at org.hibernate.orm.core@7.0.0.Beta1/org.hibernate.internal.HEMLogging.messageLogger(HEMLogging.java:28)
at org.hibernate.orm.core@7.0.0.Beta1/org.hibernate.internal.HEMLogging.messageLogger(HEMLogging.java:24)
at org.hibernate.orm.core@7.0.0.Beta1/org.hibernate.jpa.HibernatePersistenceProvider.<clinit>(HibernatePersistenceProvider.java:42)
... 1 more
1 test completed, 1 failed
Trying to downgrade JBoss-Logging to 3.5.0.Final
(which is the version declared as a dependency for Hibernate 7.0.0.Beta1
accordingly to this) will give a different error instead:
SomeTest > testIt() FAILED
java.lang.IllegalAccessError: superclass access check failed: class org.jboss.logging.JBossLogRecord (in module org.jboss.logging) cannot access class java.util.logging.LogRecord (in module java.logging) because module org.jboss.logging does not read module java.logging
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1026)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1103)
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:182)
at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:821)
at java.base/jdk.internal.loader.BuiltinClassLoader.findClassInModuleOrNull(BuiltinClassLoader.java:741)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:665)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:528)
at org.jboss.logging@3.5.0.Final/org.jboss.logging.JDKLoggerProvider.getLogger(JDKLoggerProvider.java:29)
at org.jboss.logging@3.5.0.Final/org.jboss.logging.LoggerProviders.logProvider(LoggerProviders.java:150)
at org.jboss.logging@3.5.0.Final/org.jboss.logging.LoggerProviders.tryJDK(LoggerProviders.java:106)
at org.jboss.logging@3.5.0.Final/org.jboss.logging.LoggerProviders.findProvider(LoggerProviders.java:101)
at org.jboss.logging@3.5.0.Final/org.jboss.logging.LoggerProviders.find(LoggerProviders.java:32)
at org.jboss.logging@3.5.0.Final/org.jboss.logging.LoggerProviders.<clinit>(LoggerProviders.java:29)
at org.jboss.logging@3.5.0.Final/org.jboss.logging.Logger.getLogger(Logger.java:2465)
at org.jboss.logging@3.5.0.Final/org.jboss.logging.Logger.doGetMessageLogger(Logger.java:2573)
at org.jboss.logging@3.5.0.Final/org.jboss.logging.Logger.getMessageLogger(Logger.java:2530)
at org.jboss.logging@3.5.0.Final/org.jboss.logging.Logger.getMessageLogger(Logger.java:2516)
at org.hibernate.orm.core@7.0.0.Beta1/org.hibernate.internal.HEMLogging.messageLogger(HEMLogging.java:28)
at org.hibernate.orm.core@7.0.0.Beta1/org.hibernate.internal.HEMLogging.messageLogger(HEMLogging.java:24)
at org.hibernate.orm.core@7.0.0.Beta1/org.hibernate.jpa.HibernatePersistenceProvider.<clinit>(HibernatePersistenceProvider.java:42)
at com.example/com.example.SomeTest.testIt(SomeTest.java:9)
1 test completed, 1 failed
The workaround
As a proof of concept, if I sacrifice modularity, remove the module-info.java
file and comment out the doFirst
block in the gradle.build
file, it works!
However, I can’t really sacrifice modularity in my environment.
My questions
- Maybe I should add something to the
module-info.java
file? - Or maybe I should change the version of some package?
- Or perhaps add some
--add-opens
command line options somewhere ingradle.build
? - Or should I avoid to ever directly instantiate
HibernatePersistenceProvider
and it was no more than an accident that this ever worked? - Is this a bug in Hibernate 7.0.0 Beta 1?
Or put simply:
- What I am doing wrong?
- How can I fix this?
- Any ideas?
I tried a lot of things to fix this issue, and other than just throwing modularity out of the window, nothing worked so far.
You need to sign in to view this answers
Leave feedback about this