Stateless Bean注入为空求助:Jersey升级后@EJB注入失败
原程序使用Jersey 1.1运行正常,升级后调用/ejb2/webapi/register时出现NullPointerException,提示this.userBean is null——Service类中通过@EJB注入的UserSessionBeanLocal实例未被正确注入。同时日志存在WELD-000146: BeforeBeanDiscovery.addAnnotatedType(AnnotatedType<?>) used for class com.sun.faces.flow.FlowDiscoveryCDIHelper is deprecated from CDI 1.1!警告。
核心原因
Jersey 2.x与1.x的实例化机制存在差异:Jersey 2.x默认自行创建JAX-RS资源类(如Service)的实例,不会触发Java EE容器的依赖注入逻辑(包括@EJB注入)。只有让CDI(上下文与依赖注入)接管资源类的生命周期,才能让@EJB注入生效。
解决方案
1. 将Service类标记为CDI托管Bean
给Service类添加CDI作用域注解,让CDI识别并管理该类的实例:
import javax.ejb.EJB; import javax.enterprise.context.RequestScoped; import javax.ws.rs.FormParam; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; @Path("") @RequestScoped // 添加CDI请求作用域注解 public class Service { @EJB UserSessionBeanLocal userBean; @POST @Produces(MediaType.APPLICATION_JSON) @Path("register") public Response register(@FormParam("userName") final String name, @FormParam("userPassword") final String pass, @FormParam("userEmail") String email) { if (userBean.isUserPresent(email)) return Response.ok("Email already registered!!").build(); userBean.addUser(new User(name, email, pass)); return Response.ok("Registered!!").build(); } }
2. 确保beans.xml配置正确
在WEB-INF目录下创建或修改beans.xml,设置正确的Bean发现模式:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd" version="2.0" bean-discovery-mode="annotated"> <!-- 仅托管带有CDI/EE注解的类,也可设为"all"托管所有类 --> </beans>
3. 配置Jersey委托CDI创建资源实例
在web.xml中添加Jersey的CDI集成参数,确保Jersey不自行创建资源实例,而是委托CDI处理:
<servlet> <servlet-name>Jersey Web Application</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>jersey.config.server.provider.packages</param-name> <param-value>com.enovate.assignment.ejb2</param-value> </init-param> <!-- 添加该参数,指定资源类使用请求作用域 --> <init-param> <param-name>jersey.config.server.provider.scope</param-name> <param-value>REQUEST</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet>
4. 检查依赖(若使用外部Jersey库)
如果未使用WildFly自带的Jersey,需引入Jersey的CDI集成依赖,以Maven为例:
<dependency> <groupId>org.glassfish.jersey.containers</groupId> <artifactId>jersey-container-servlet</artifactId> <version>你的Jersey版本号</version> </dependency> <dependency> <groupId>org.glassfish.jersey.ext.cdi</groupId> <artifactId>jersey-cdi1x</artifactId> <version>你的Jersey版本号</version> <scope>provided</scope> <!-- 若WildFly自带Jersey,使用provided避免冲突 --> </dependency>
关于CDI警告
日志中的FlowDiscoveryCDIHelper警告属于JSF组件的过时API提示,与当前@EJB注入问题无关,可忽略。
内容的提问来源于stack exchange,提问作者Prashant Kumar

