Jakarta EE 9+Spring Data在WildFly 27中注入GameRepository失败
我在Wildfly 27.0.1 Final上运行基于Jakarta EE 9(Java JDK 17)且使用Spring-data的项目,此前在Wildfly 20.0.1 Final上运行Java EE 8(Java SDK 8)的类似配置无问题。
我的pom.xml配置如下:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>ProjectName</groupId> <artifactId>ProjectName</artifactId> <version>1.0</version> <packaging>war</packaging> <name>ProjectName</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>17</source> <target>17</target> </configuration> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>3.2.2</version> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.22</version> <scope>provided</scope> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.6</version> </dependency> <dependency> <groupId>jakarta.platform</groupId> <artifactId>jakarta.jakartaee-web-api</artifactId> <version>9.0.0</version> <scope>provided</scope> </dependency> <!-- https://mvnrepository.com/artifact/jakarta.ejb/jakarta.ejb-api --> <dependency> <groupId>jakarta.ejb</groupId> <artifactId>jakarta.ejb-api</artifactId> <version>4.0.1</version> </dependency> <dependency> <groupId>org.json</groupId> <artifactId>json</artifactId> <version>20160810</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/com.google.guava/guava --> <dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>28.1-jre</version> </dependency> <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.6.4</version> </dependency> <dependency> <groupId>com.auth0</groupId> <artifactId>java-jwt</artifactId> <version>3.8.3</version> </dependency> <!-- <dependency>--> <!-- <groupId>org.springframework.data</groupId>--> <!-- <artifactId>spring-data-jpa</artifactId>--> <!-- <version>1.11.23.RELEASE</version>--> <!-- </dependency>--> <!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-annotations</artifactId> <version>3.5.6-Final</version> </dependency> <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.8</version> </dependency> <dependency> <groupId>com.googlecode.json-simple</groupId> <artifactId>json-simple</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.4</version> </dependency> <!-- https://mvnrepository.com/artifact/commons-io/commons-io --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.6</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.17.0</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> <version>1.11.23.RELEASE</version> </dependency> <dependency> <groupId>org.postgresql</groupId> <artifactId>postgresql</artifactId> <version>42.5.1</version> </dependency> </dependencies> </project>
为使EntityManager可用,我添加了CdiConfig类:
public class CdiConfig { @Produces @Dependent @PersistenceContext public EntityManager entityManager; }
同时设置仓储类预初始化:
@Eager public interface GameRepository extends CrudRepository<Game, Long> { Game findByUniqueId(String uniqueId); }
在Facade类中尝试注入该仓储:
@Stateless public class GameFacade { @Inject GameRepository repository; ... }
我还在/webapp/WEB-INF/下添加了beans.xml以确保仓储可被发现:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_3_0.xsd" bean-discovery-mode="all"> </beans>
但仍出现以下错误:
Caused by: org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type GameRepository with qualifiers @Default at injection point [BackedAnnotatedField] @Inject com.example.project.facade.GameFacade.repository at com.example.project.facade.GameFacade.repository(GameFacade.java:0)
1. 修复Spring Data JPA依赖冲突
pom.xml中同时引入了spring-data-jpa 3.0.1和1.11.23.RELEASE,两个版本适配的EE规范完全不同,3.0.x对应Jakarta EE 9,1.11.x对应Java EE 8,必须删除其中一个。保留3.0.1版本,移除1.11.23.RELEASE的依赖项。
2. 添加Spring Data CDI扩展依赖
Spring Data JPA的Repository默认由Spring容器管理,要让CDI(Wildfly的Weld容器)识别并注入这些Repository,需要引入Spring Data的CDI扩展:
<dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-cdi</artifactId> <version>3.0.1</version> </dependency>
该扩展会自动为Spring Data Repository生成CDI可识别的Bean实例。
3. 修正EntityManager Producer的CDI作用域
CdiConfig类需要被CDI容器扫描识别,添加@ApplicationScoped注解,同时移除多余的@Dependent(@PersistenceContext注入的EntityManager本身由容器管理):
@ApplicationScoped public class CdiConfig { @Produces @PersistenceContext public EntityManager entityManager; }
4. 移除非标准的@Eager注解
@Eager不是Spring Data或Jakarta EE的标准注解,CDI容器无法识别它,会导致Repository初始化异常。如果需要提前初始化Repository,可通过CDI的@Startup+@Singleton Bean触发,不要直接在Repository接口上添加非标准注解。
5. 删除老旧的Hibernate依赖
Wildfly 27自带适配Jakarta EE 9的Hibernate 6.x版本,你引入的hibernate-annotations 3.5.6-Final是Java EE 5时代的老旧依赖,完全不兼容,直接删除该依赖即可。
6. 清理重复的Jackson依赖
pom.xml中重复引入了jackson-databind 2.9.8和2.9.4,删除其中一个,建议保留较新版本的2.9.8。
7. 验证Persistence配置
确保persistence.xml位于src/main/resources/META-INF/目录,且使用Jakarta EE 3.0的命名空间:
<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="https://jakarta.ee/xml/ns/jakartaee" version="3.0"> <persistence-unit name="YourPersistenceUnit" transaction-type="JTA"> <jta-data-source>java:/YourDataSource</jta-data-source> <class>com.example.project.model.Game</class> <properties> <property name="hibernate.hbm2ddl.auto" value="update"/> <property name="hibernate.show_sql" value="true"/> </properties> </persistence-unit> </persistence>
完成以上步骤后,重新构建部署项目,CDI容器即可正确识别并注入GameRepository。
内容的提问来源于stack exchange,提问作者user3362334

