WildFly11中jboss-deployment-structure注入持久化单元报错求助
注:此问题与Stack Overflow上类似问题重复,但原问题无有效答案且无法评论,故开新帖求助。
场景描述
我有一个client.jar,需要依赖另一个modele.jar中的实体类与DAO组件。client.jar中的核心代码如下:
public class ImportService implements IServices { @EJB(mappedName = "java:global/tab.transmodel/VersionHoraireHome!org.avm.business.transmodel.VersionDAO") private VersionDAO<VersionHoraire, Integer> vdhDao; }
在client.jar的src/main/resources/META-INF目录下,我配置了jboss-deployment-structure.xml:
<?xml version="1.0"?> <jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <deployment> <dependencies> <module name="deployment.modele.jar"/> </dependencies> </deployment> </jboss-deployment-structure>
遇到的问题
情况1:注释掉<module name="deployment.modele.jar"/>
出现类找不到错误:
(...) Caused by: java.lang.NoClassDefFoundError: Lorg/avm/business/transmodel/VersionDAO; at java.base/java.lang.Class.getDeclaredFields0(Native Method) at java.base/java.lang.Class.privateGetDeclaredFields(Class.java:3024) at java.base/java.lang.Class.getDeclaredFields(Class.java:2205) at org.jboss.as.server//org.jboss.as.server.deployment.reflect.ClassReflectionIndex.<init>(ClassReflectionIndex.java:72) at org.jboss.as.server//org.jboss.as.server.deployment.reflect.DeploymentReflectionIndex.getClassIndex(DeploymentReflectionIndex.java:70) ... 10 more
情况2:保留该行依赖配置
出现持久化单元注入错误:
Caused by: java.lang.IllegalArgumentException: WFLYWELD0037: Error injecting persistence unit into CDI managed bean. Can't find a persistence unit named 'manager' in deployment client.jar for injection point private javax.persistence.EntityManager org.avm.business.transmodel.EquipementHome.entityManager at org.jboss.as.weld.jpa//org.jboss.as.weld.services.bootstrap.WeldJpaInjectionServices.getScopedPUName(WeldJpaInjectionServices.java:114) at org.jboss.as.weld.jpa//org.jboss.as.weld.services.bootstrap.WeldJpaInjectionServices.registerPersistenceContextInjectionPoint(WeldJpaInjectionServices.java:77) at org.jboss.weld.core//org.jboss.weld.injection.ResourceInjectionFactory$PersistenceContextResourceInjectionProcessor.getResourceReferenceFactory(ResourceInjectionFactory.java:350) at org.jboss.weld.core//org.jboss.weld.injection.ResourceInjectionFactory$PersistenceContextResourceInjectionProcessor.getResourceReferenceFactory(ResourceInjectionFactory.java:338) at org.jboss.weld.core//org.jboss.weld.injection.ResourceInjectionFactory$ResourceInjectionProcessor.createFieldResourceInjection(ResourceInjectionFactory.java:216)
补充说明:modele.jar的src/main/resources/META-INF下存在persistence.xml,其中定义了名为manager的持久化单元:
<persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" version="2.0"> <persistence-unit name="manager"> <jta-data-source>java:/OracleDS</jta-data-source> <properties> <property name="hibernate.hbm2ddl.auto" value="update" /> <property name="hibernate.cache.use_second_level_cache" value="true" /> </properties> </persistence-unit> </persistence>
环境信息:WildFly 11、Java 1.8、Eclipse。
看起来你遇到的是WildFly中跨JAR依赖时持久化单元识别的典型问题,我来给你几个针对性的解决方案:
1. 调整jboss-deployment-structure.xml的依赖配置
问题核心在于:当你把modele.jar作为模块依赖引入时,WildFly会将其视为独立模块,模块内的persistence.xml不会被自动纳入当前client.jar的部署上下文。你需要修改配置,让modele.jar的持久化单元能被当前部署访问:
修改client.jar的jboss-deployment-structure.xml:
<?xml version="1.0"?> <jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <deployment> <dependencies> <!-- 导出modele.jar的资源,让当前部署能访问到它的类和配置 --> <module name="deployment.modele.jar" export="true" /> <!-- 显式引入Java Persistence和Hibernate的API模块,避免依赖缺失 --> <module name="javax.persistence.api" export="true" /> <module name="org.hibernate" export="true" /> </dependencies> <!-- 显式关联modele.jar中的持久化单元到当前部署 --> <persistence-unit-refs> <persistence-unit-ref name="manager"> <persistence-unit-name>manager</persistence-unit-name> <module>deployment.modele.jar</module> </persistence-unit-ref> </persistence-unit-refs> </deployment> </jboss-deployment-structure>
2. 确认DAO的EJB标识与注入配置
你的VersionDAO是通过@EJB注入的,务必确保modele.jar中的实现类(VersionHoraireHome)被正确标记为EJB,并且持久化上下文注入正确:
@Stateless(name = "VersionHoraireHome") public class VersionHoraireHome implements VersionDAO<VersionHoraire, Integer> { // 这里要确保unitName和persistence.xml中的名称完全一致 @PersistenceContext(unitName = "manager") private EntityManager entityManager; // ... 业务方法实现 }
3. 验证部署结构与命名
- 如果你是将
modele.jar作为独立EJB JAR部署,要确认它的部署名称是tab.transmodel——这对应你@EJB中mappedName的前缀java:global/tab.transmodel/...,WildFly的部署名称会影响JNDI路径。 - 如果
client.jar是WAR包的一部分,建议直接将modele.jar放到WEB-INF/lib目录下,这样WildFly会自动扫描它的persistence.xml,可能不需要复杂的模块配置。
4. 检查CDI管理类的标识
如果ImportService不是EJB(没有@Stateless/@Stateful等注解),需要添加CDI注解让容器管理它,比如@Named或者@ApplicationScoped,否则CDI容器不会处理它的@EJB注入:
@ApplicationScoped public class ImportService implements IServices { @EJB(mappedName = "java:global/tab.transmodel/VersionHoraireHome!org.avm.business.transmodel.VersionDAO") private VersionDAO<VersionHoraire, Integer> vdhDao; }
5. 验证数据源配置
确保WildFly中java:/OracleDS数据源已经正确配置并启动,你可以通过WildFly的管理控制台(默认http://localhost:9990)查看数据源的状态,避免因为数据源不可用间接导致持久化单元加载失败。
内容的提问来源于stack exchange,提问作者Lbro

