同一JAR模块内EJB Bean注入失败问题排查
你遇到的空指针问题,大概率和运行环境、注解使用逻辑或者实例获取方式有关,下面是几个关键排查点和解决办法:
1. 必须在Java EE容器中运行,不能用普通Java SE环境
你添加的javaee-api依赖是<scope>provided</scope>,这意味着这个API只在编译阶段生效,运行时的实际实现要靠Java EE容器(比如WildFly、Payara、GlassFish等)提供。如果是用普通main方法直接跑代码,或者在没有CDI/EJB容器的环境中执行,容器根本不会帮你完成依赖注入,自然会得到null。
解决办法:
- 把你的JAR部署到完整的Java EE应用服务器中运行
- 本地测试时,用容器提供的测试框架(比如Arquillian)模拟容器环境
2. 检查@Singleton注解的类型
Java EE里有两个功能不同的@Singleton注解:
javax.ejb.Singleton:EJB规范下的单例Beanjavax.inject.Singleton:CDI规范下的单例Bean
你代码里用的是EJB的@Singleton,虽然EJB Bean默认会被CDI当作候选Bean,但部分容器可能需要额外配置来启用EJB和CDI的集成。你可以尝试换成CDI的javax.inject.Singleton注解,确保A是CDI直接管理的Bean,这样@Inject注入逻辑会更直接:
import javax.inject.Singleton; @Singleton public final class A { public String getS() { return ""; } }
3. 绝对不能手动new实例,必须通过容器获取B
如果你的代码里是直接new B()创建实例,CDI容器完全没参与这个过程,自然不会帮你注入A的实例。必须通过容器获取B:
- 在另一个CDI/EJB管理的Bean中用
@Inject B b;来注入B - 通过JNDI查找EJB的方式获取B(比如
InitialContext.lookup("java:module/B"))
4. 检查beans.xml的配置是否符合容器版本
Java EE 7+允许beans.xml是空文件,但如果你的容器是Java EE 6这类旧版本,需要确保beans.xml包含正确的schema:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> </beans>
对于Java EE 7+,可以显式设置Bean发现模式(默认是annotated,你的类都有注解,所以没问题):
<?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_1_1.xsd" bean-discovery-mode="annotated"> </beans>
5. 确认模块的部署方式正确
如果你的JAR是独立模块,要确保容器能正确识别它是CDI/EJB模块。有些容器要求把JAR打包到EAR中,或者放在指定的部署目录(比如WildFly的standalone/deployments)。
内容的提问来源于stack exchange,提问作者michalavis

