Servlet中@EJB注入报NullPointerException问题(Intellij+Tomcat环境)
EJB注入到Servlet时出现NullPointerException的解决方案
根本原因
Tomcat是轻量级Servlet/JSP容器,不具备EJB容器的功能,无法识别和处理@EJB注解的依赖注入逻辑,因此customerDAO始终为null。你手动new CustomerDAO()能运行是因为直接创建了对象,没有依赖EJB容器的管理,但这不符合依赖注入的设计需求。
解决方案
方案一:更换为支持EJB的Java EE应用服务器
Tomcat不支持EJB,你需要改用完整的Java EE应用服务器,比如WildFly、GlassFish、Payara,这些服务器内置EJB容器,原生支持@EJB注入:
- 在IntelliJ中配置目标服务器(以WildFly为例):下载对应版本的WildFly,在
Run/Debug Configurations中添加WildFly服务器 - 将项目部署到该服务器,
@EJB注解会被自动处理,注入逻辑正常生效。
方案二:改用CDI(上下文和依赖注入)继续使用Tomcat
如果你想继续使用Tomcat,可以通过添加CDI实现(Weld)来替代EJB的依赖注入功能:
- 添加Maven依赖(如果使用Maven管理项目):
<dependency> <groupId>org.jboss.weld.servlet</groupId> <artifactId>weld-servlet-core</artifactId> <version>4.0.2.Final</version> <!-- 适配Jakarta EE 9,根据你的项目依赖调整版本 --> </dependency>
- 创建CDI配置文件:
在src/main/webapp/WEB-INF目录下创建beans.xml文件(空配置即可,用于启用CDI):
<?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" version="3.0" bean-discovery-mode="annotated"> </beans>
- 修改代码适配CDI:
- 修改
CustomerDAO.java,将EJB的@Stateless替换为CDI的作用域注解(比如@ApplicationScoped):package dao; import jakarta.enterprise.context.ApplicationScoped; @ApplicationScoped public class CustomerDAO extends AbstractFacade<Customer> implements CustomerDAOI { public CustomerDAO() { super(Customer.class); } public boolean createCustomer(Customer customer){ try{ this.create(customer); return true; } catch (Exception e){ return false; } } } - 修改
SignUp.java,将@EJB替换为CDI的@Inject注解:package controller; import jakarta.inject.Inject; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import dao.CustomerDAO; import model.Customer; import java.io.IOException; @WebServlet(name = "SignUp", value = "/SignUp") public class SignUp extends HttpServlet { @Inject private CustomerDAO customerDAO; @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { Customer customer = new Customer("John"); customerDAO.createCustomer(customer); } }
- 修改
- 重新部署项目到Tomcat,CDI会自动处理依赖注入,
customerDAO不再为null。
为什么你之前的尝试无效
- 安装Jakarta EE EJB插件只是解决了IDE的语法提示问题,无法让Tomcat具备EJB容器功能
@ManagedBean是JSF组件的注解,和EJB依赖注入无关ejb-local-ref配置需要EJB容器支持,Tomcat无法识别该配置
内容的提问来源于stack exchange,提问作者IamL
相关产品推荐
相关产品推荐

