Search code examples
hibernatejpawildflyjboss7.xjava-ee-8

java.lang.IllegalArgumentException: WFLYWELD0037: Error injecting persistence unit into CDI managed bean


The error I am seeing is similar to this one documented here. However, there is no direct ejb injection between my EAR and WAR project.

Environment: Application server: JBoss EAP 7.3

I have the project set up as: EJB-EAR:

  • Contains a DataManagement.jar that has all the DAO objects, JPA related stuff and persistence.xml
  • persistence.xml is located under main/resources/META-INF/ within the jar

persistence.xml:

<persistence version="2.1"
   xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
        http://xmlns.jcp.org/xml/ns/persistence
        http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
   <persistence-unit name="primary">
      <!-- If you are running in a production environment, add a managed
         data source, this example data source is just for development and testing! -->
      <jta-data-source>java:jboss/datasources/PcosDS</jta-data-source>
      <properties>
         <!-- Properties for Hibernate -->
         <property name="hibernate.hbm2ddl.auto" value="create-drop" />
         <property name="hibernate.show_sql" value="false" />
      </properties>
   </persistence-unit>
</persistence>

an example DAO object looks like

 @Stateless
 public class LoginAttemptDAO {
    
     private static final ILogger logger = LoggerFactory
                .getLogger(LoginAttemptDAO.class);
    
     @Inject
     private EntityManager entityManager;

and producer is defined as:

public class Resources {
      @Produces
      @PersistenceContext(unitName="primary")
      private EntityManager em;
}

WAR:

  • The WAR project starts up application and contains other jars in its WEB-INF/lib. One of these jars eventually accesses the jar in EAR project via EJB look up.
  • WAR contains jboss-deployment-structure.xml and jboss-all.xml under /src/main/webapp/META-INF

jboss-deployment-structure.xml

<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2">
    <deployment>
        <dependencies>            
            <module name="deployment.pts-ear-1.0-SNAPSHOT.ear.DataManagement.jar"/>
        </dependencies>
        <exclusions>
        
        </exclusions>
    </deployment>
</jboss-deployment-structure>

jboss-all.xml

<jboss umlns="urn:jboss:1.0">
    <jboss-deployment-dependencies xmlns="urn:jboss:deployment-dependencies:1.0">
        <dependency name="pts-ear-1.0-SNAPSHOT.ear" />
    </jboss-deployment-dependencies>
</jboss>

The EAR deploys fine and I do see test database gets prepopulated with initial data. The problem occurs as soon as I deploy the war project and error I am seeing is

Caused by: java.lang.IllegalArgumentException: WFLYWELD0037: Error injecting persistence unit into CDI managed bean. Can't find a persistence unit named 'primary' in deployment InitializeServlet-war-1.0-SNAPSHOT.war for injection point private javax.persistence.EntityManager com.lmco.pts.pcos.inf.DataManagement.dao.Resources.em at [email protected]//org.jboss.as.weld.services.bootstrap.WeldJpaInjectionServices.getScopedPUName(WeldJpaInjectionServices.java:105) at [email protected]//org.jboss.as.weld.services.bootstrap.WeldJpaInjectionServices.registerPersistenceContextInjectionPoint(WeldJpaInjectionServices.java:68) at [email protected]//org.jboss.weld.injection.ResourceInjectionFactory$PersistenceContextResourceInjectionProcessor.getResourceReferenceFactory(ResourceInjectionFactory.java:174) at [email protected]//org.jboss.weld.injection.ResourceInjectionFactory$PersistenceContextResourceInjectionProcessor.getResourceReferenceFactory(ResourceInjectionFactory.java:162)

Everything works if I have the DataManagement.jar packaged in the WEB-INF/lib of the WAR project. I am trying to move the DataManagement.jar out of the war project so it can be used by other projects and serve as a dynamic resources to other projects deployed on the application server. I am suspecting that the persistence unit is somehow not visible to the WAR but the WAR doesn't really need the persistence unit. It just calls the service from the JAR which performs database access.


Solution

  • Turns out one of the missing information I didn't post was the beans.xml configuration for DataManagement.jar. Its discovery mode for beans was set to all to allow the unannotated producer class Resource to be discovered:

    <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="
          http://xmlns.jcp.org/xml/ns/javaee
          http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd"
        bean-discovery-mode="all">
    </beans>
    

    After removing this file (latest CDI does not require this file and by default bean discovery mode is set to annotated) or change the discovery mode to "annotated" and annotating the producer class as:

    @Stateless
    public class Resources {
          @PersistenceContext(unitName="primary")
          private EntityManager em;
          
          @Produces
          public EntityManager entityManager(){
              return em;
          }
    }
    

    The WAR deployed is able to successfully access the DataManagement.jar by performing ejb lookups.