部署含RESTEasy+Weld(CDI)的WAR至Jetty11失败,CDI注入失效求助
问题:Jetty 11部署RESTEasy+Weld CDI服务时,Weld无法识别Servlet容器导致@Inject字段为空
我将基于RESTEasy开发、通过Weld实现CDI的REST服务WAR包部署到Jetty 11,使用Maven的jetty-maven-plugin执行mvn jetty:run测试时功能异常,所有标注@Inject的字段均为空值。
环境信息
- RESTEasy 7.0.0.Alpha1(早期版本依赖的Jandex 2.X.X与Weld冲突,必须使用该版本)
- Weld 5.1.2.Final
- Jetty 11.0.19(客户端基于GWT 2.11.0开发,需支持JDK 11)
- WEB-INF目录下存在空白的
beans.xml文件 - 使用Jakarta Servlet 5.0,
web.xml仅配置了继承RESTEasy Application的类
Maven依赖
<!-- RESTEasy --> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-servlet-initializer</artifactId> <version>7.0.0.Alpha1</version> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-jackson2-provider</artifactId> <version>7.0.0.Alpha1</version> </dependency> <dependency> <groupId>org.jboss.resteasy</groupId> <artifactId>resteasy-cdi</artifactId> <version>7.0.0.Alpha1</version> </dependency> <!-- Jakarta EE main APIs --> <dependency> <groupId>jakarta.platform</groupId> <artifactId>jakarta.jakartaee-api</artifactId> <version>10.0.0</version> </dependency> <dependency> <groupId>jakarta.platform</groupId> <artifactId>jakarta.jakartaee-web-api</artifactId> <version>10.0.0</version> </dependency> <!-- Web Push --> <dependency> <groupId>nl.martijndwars</groupId> <artifactId>web-push</artifactId> <version>5.1.1</version> </dependency> <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcpkix-jdk15on</artifactId> <version>1.55</version> </dependency> <!-- SQL连接池 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-dbcp2</artifactId> <version>2.12.0</version> </dependency> <!-- Weld CDI支持 --> <dependency> <groupId>org.jboss.weld.servlet</groupId> <artifactId>weld-servlet-core</artifactId> <version>5.1.2.Final</version> </dependency>
Jetty Maven插件配置
<plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>11.0.19</version> </plugin>
错误日志
INFO: WELD-000900: 5.1.2 (Final) May 08, 2024 7:08:55 PM org.jboss.weld.environment.deployment.discovery.DiscoveryStrategyFactory create INFO: WELD-ENV-000020: Using jandex for bean discovery May 08, 2024 7:08:55 PM org.jboss.weld.bootstrap.WeldStartup startContainer INFO: WELD-000101: Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously. May 08, 2024 7:08:55 PM org.jboss.weld.environment.servlet.WeldServletLifecycle initialize INFO: WELD-ENV-001001: No supported servlet container detected, CDI injection will NOT be available in Servlets, Filters or Listeners
补充web.xml内容
<?xml version="1.0" encoding="UTF-8"?> <web-app 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/web-app_5_0.xsd" metadata-complete="false" version="5.0"> <!-- Servlets --> <servlet> <servlet-name>com.example.DemoApplication</servlet-name> </servlet> <servlet-mapping> <servlet-name>com.example.DemoApplication</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> <!-- 默认欢迎页 --> <welcome-file-list> <welcome-file>index.html</welcome-file> </welcome-file-list> <context-param> <param-name>org.eclipse.jetty.cdi</param-name> <param-value>CdiDecoratingListener</param-value> </context-param> <listener> <listener-class>org.jboss.weld.environment.servlet.EnhancedListener</listener-class> </listener> </web-app>
核心疑问:为什么Weld无法检测到受支持的Servlet容器?
解决方案
1. 替换Weld依赖与监听器,适配Jetty容器
当前使用的weld-servlet-core和EnhancedListener无法在Jetty 11下正确识别容器,需调整为:
- 移除
weld-servlet-core依赖,添加shaded版本避免类冲突:<dependency> <groupId>org.jboss.weld.servlet</groupId> <artifactId>weld-servlet-shaded</artifactId> <version>5.1.2.Final</version> </dependency> - 修改web.xml中的监听器,替换为Jetty官方CDI监听器:
<!-- 移除原Weld监听器 --> <!-- <listener> <listener-class>org.jboss.weld.environment.servlet.EnhancedListener</listener-class> </listener> --> <!-- 添加Jetty CDI监听器 --> <listener> <listener-class>org.eclipse.jetty.cdi.CdiListener</listener-class> </listener>
2. 配置Jetty Maven插件,启用CDI支持
Jetty 11的Maven插件需显式启用CDI模块,否则无法加载相关支持:
<plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>11.0.19</version> <configuration> <webApp> <contextParam> <param-name>org.eclipse.jetty.cdi</param-name> <param-value>enabled</param-value> </contextParam> </webApp> <!-- 强制加载CDI模块 --> <modules> <module>cdi</module> </modules> </configuration> </plugin>
3. 优化RESTEasy应用配置
在DemoApplication类中添加@ApplicationPath注解,替代web.xml中的手动Servlet配置,更符合Jakarta EE规范:
import jakarta.ws.rs.ApplicationPath; import jakarta.ws.rs.core.Application; @ApplicationPath("/rest") public class DemoApplication extends Application { // 可添加资源类注册逻辑,或保持空实现由RESTAutoDiscover扫描 }
同时可移除web.xml中手动配置的servlet和servlet-mapping,让RESTEasy通过Servlet Initializer自动注册。
4. 修正beans.xml配置
确保beans.xml适配Jakarta EE 10版本,显式设置bean发现模式:
<?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_4_0.xsd" version="4.0" bean-discovery-mode="all"> </beans>
内容的提问来源于stack exchange,提问作者Oberon
相关产品推荐
相关产品推荐

