0
votes

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.

2
Are the DataManagement.jar and WAR in the same EAR? - James R. Perkins
only DataManagement.jar is packaged in the EAR. The idea is to allow multiple WARs to access the same jar. Actually I managed to resolve the issue and it has something to do with combination of beans.xml and producer class. I will post the solution shortly. - MidTierDeveloper

2 Answers

0
votes

If I understand you correctly, you are assuming that a separate JAR is a dedicated deployment that you can just refer to, but this is not the case. A persistence unit must be part of a deployment. Maybe it's possible to create a JBoss Module for the JAR and refer to that, but in the end, it will start the Persistence Unit for every deployment that refers to that module. What's wrong with just putting that JAR into WEB-INF/lib? You can just package the JAR into other WARs as well.

0
votes

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.