javax.persistence.PersistenceException: No Persistence provider for EntityManager named ... in JBoss EAP 6
Environment
Red Hat JBoss Enterprise Application Platform (EAP) 6.x
Issue
- We have a security login module where we are trying to use JPA / Hibernate EntityManager to read from a database. We have our login module inside of a custom module which depends on jpa and hibernate modules as shown below. But we are getting the error 'javax.persistence.PersistenceException: No Persistence provider for EntityManager named' when trying to get the EntityManagerFactory via:
EntityManagerFactory emf = Persistence.createEntityManagerFactory("SecurityPersistenceUnit");
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="com.examples.security.exampleLoginModule">
<resources>
<resource-root path="example-security-login-module.jar"></resource>
</resources>
<dependencies>
<module name="javax.api" export="false"></module>
<module name="javax.persistence.api" ></module>
<module name="org.hibernate" ></module>
<module name="org.picketbox"></module>
<module name="org.jboss.logging" ></module>
</dependencies>
</module>
ERROR [com.example.ExampleLoginModule] (http-localhost/127.0.0.1:8080-1) Failed to create principal: javax.persistence.PersistenceException: No Persistence provider for EntityManager named SecurityPersistenceUnit
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:69) [hibernate-jpa-2.0-api-1.0.1.Final-redhat-2.jar:1.0.1.Final-redhat-2]
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:47) [hibernate-jpa-2.0-api-1.0.1.Final-redhat-2.jar:1.0.1.Final-redhat-2]
at com.example.service.ExampleSecurityProfile.getEMF(ExampleSecurityProfile.java:21) [example-saml-security.jar:]
Resolution
Apply JBoss EAP 6.4.0 Cumulative Patch (CP) 6
As a workaround:
Create a PersistenceUtil class inside of the jar containing the META-INF/persistence.xml such as shown below, which can then be used via the security login module code. It will switch the thread context classloader which will workaround the issue.
public class PersistenceUtil {
public static EntityManagerFactory getEntityManagerFactory() {
final ClassLoader TCCL = Thread.currentThread().getContextClassLoader();
try {
// MUST reference a class that is part of the persistence module to get the class loader
Thread.currentThread().setContextClassLoader(PersistenceUtil.class.getClassLoader());
return Persistence.createEntityManagerFactory("ExamplePersistenceUunit");
} finally {
Thread.currentThread().setContextClassLoader(TCCL);
}
}
Root Cause
This use case is a non JavaEE use case, where as you are configuring the classloader directly and need to ensure everything is visible to your custom module.
Bugs may be related, depending on the use case:
This content is not included.Security ModuleClassLoaderLocator.CombinedClassLoader does not implement getResources
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.