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:
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:
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.
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.