WildFly 27上JakartaEE REST服务CDI注入失败问题及解决
问题解决记录与原问题咨询
更新:问题已解决
问题根源在于web.xml。我之前按照教程创建了包含如下servlet定义的web.xml:
<servlet> <servlet-name>Jersey REST Service</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>jersey.config.server.provider.packages</param-name> <param-value>de.gst.lern.javaee.products.backend.rest</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Jersey REST Service</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping>
我移除了该servlet定义,转而添加了一个简单的Application类:
package de.gst.lern.javaee.products.backend.rest; import jakarta.ws.rs.ApplicationPath; import jakarta.ws.rs.core.Application; @ApplicationPath("/rest") public class ProductServiceApplication extends Application { }
现在CDI可以正常工作了,虽然我还有些困惑,但问题确实解决了。
原问题描述
我正在重新学习JakartaEE技术,开发一个基础REST应用,项目结构如下:
products-backend |- pom.xml \ products-backend-entities |- pom.xml |-- src/main/java/{}/Product.java -> 简单的实体Bean \ products-backend-dao |- pom.xml |- src/main/java/{}/ProductDao.java -> 包含增删改查方法的基础DAO |- src/main/resources/META-INF/beans.xml: JakartaEE的beans.xml,bean-discovery-mode="annotated" \ products-backend-rest |- pom.xml |- src/main/java/{}/ProductService.java -> 包含REST注解的服务类 |- src/main/webapp/WEB-INF/beans.xml: JakartaEE的beans.xml,bean-discovery-mode="annotated"
项目部署到WildFly 27成功,但访问REST服务URL触发依赖注入时,出现如下错误:
Caused by: org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available in __HK2_Generated_0 for injection at SystemInjecteeImpl(requiredType=ProductHelpDao,parent=ProductService,qualifiers={},position=-1,optional=false,self=false,unqualified=null,856067323)
请问我遗漏了什么配置?
开发环境为Eclipse 2023。
细节补充
ProductService使用@Inject注入ProductDao实例:
import jakarta.inject.Inject; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; import jakarta.ws.rs.PathParam; import jakarta.ws.rs.Produces; import jakarta.ws.rs.core.MediaType; import jakarta.ws.rs.core.Response; @Path("/products") public class ProductService { @Inject private ProductDao productDao; @GET @Produces(MediaType.APPLICATION_JSON) public List<Product> getAllProducts() { return productDao.listAllProducts(); } @GET @Path("{id}") @Produces(MediaType.APPLICATION_JSON) public Response getById(@PathParam("id") int id) { Optional<Product> byId = productDao.findById(id); if(byId.isEmpty()) { return Response.status(Response.Status.NOT_FOUND).build(); } return Response.ok(byId.get()).build(); } }
ProductDao标注了@ApplicationScoped,作为模拟数据库后端:
import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped public class ProductDao { private final Map<Integer, Product> productsById = new HashMap<>(); public List<Product> listAllProducts() { return new ArrayList<>(productsById.values()); } public Optional<Product> findById(int id) { Product product = productsById.get(id); return product == null ? Optional.<Product> empty() : Optional.of(product); } public boolean add(final Product product) { return productsById.putIfAbsent(product.getId(), product) == null; } public boolean replace(final Product product) { if(!productsById.containsKey(product.getId())) { productsById.put(product.getId(), product); return true; } Product current = productsById.get(product.getId()); if(!current.equals(product)) { productsById.put(product.getId(), product); return true; } return false; } public boolean remove(Product product) { return productsById.remove(product.getId()) != null; } }
products-backend的pom.xml:
<packaging>pom</packaging> <modules> <module>products-backend-entities</module> <module>products-backend-dao</module> <module>products-backend-rest</module> </modules>
products-backend-dao的pom.xml:
<?xml version="1.0" encoding="UTF-8"?> <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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <artifactId>products-backend</artifactId> <groupId>de.gst.lern.javaee.products</groupId> <version>1.0-SNAPSHOT</version> </parent> <artifactId>products-backend-dao</artifactId> <packaging>jar</packaging> <name>products-backend-dao</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>de.gst.lern.javaee.products</groupId> <artifactId>products-backend-entities</artifactId> <version>${project.version}</version> </dependency> <dependency> <groupId>jakarta.platform</groupId> <artifactId>jakarta.jakartaee-api</artifactId> <version>10.0.0</version> </dependency> <!-- https://mvnrepository.com/artifact/jakarta.enterprise/jakarta.enterprise.cdi-api --> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> </plugin> </plugins> </build> </project>
products-backend-entities的pom.xml:
<packaging>jar</packaging> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> </plugin> </plugins> </build> </project>
我查阅了大量教程,多数提到添加beans.xml启用CDI,我已配置,但问题仍存在,寻求解决方案。
内容的提问来源于stack exchange,提问作者Gunnar Stahl
相关产品推荐
相关产品推荐

