You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

部署含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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 14:04:54