首页 > 解决方案 > 使用 @EJB 注入时出现 NullpointerException

问题描述

我在使用 @EJB 注释注入我的 bean 时遇到问题 - bean 始终为空......

首先,这是我的项目结构的相关部分。

ApplEAR.ear
|
├──WebModule.war (de.example.rest)
└──EJBModule.war (de.example.service)

所以......现在我正在尝试从我的webmodule中的ejbmodule注入一个bean:

de.example.rest.RestBean:

@Stateless(name = "RestBean")
@Path("/restElements")
public class RestBean implements IRestBean {
    
    @EJB
    private UserBean userBean;

de.example.service.UserBean:

@Stateless(name = "UserBean")
@TransactionManagement(TransactionManagementType.BEAN)
@LocalBean
public class UserBean{...

在我的 WebModule 中,我有这个类来扩展应用程序类:

@ApplicationPath("/*")
public class RestApplication extends javax.ws.rs.core.Application {
    /**
     * {@inheritDoc}
     */
    @Override
    public Set<Class<?>> getClasses() {
        Set<Class<?>> classes = new HashSet<Class<?>>();
        classes.add(de.example.rest.RestBean.class);
        return classes;
    }
}

ear 部署在具有以下已安装功能的 websphere liberty 服务器上:

<feature>localConnector-1.0</feature>
<feature>appSecurity-3.0</feature>
<feature>beanValidation-2.0</feature>
<feature>ejbLite-3.2</feature>
<feature>ejbRemote-3.2</feature>
<feature>javaMail-1.6</feature>
<feature>jca-1.7</feature>
<feature>jdbc-4.2</feature>
<feature>jndi-1.0</feature>
<feature>jpaContainer-2.2</feature>
<feature>jsf-2.3</feature>
<feature>jsp-2.3</feature>
<feature>ldapRegistry-3.0</feature>
<feature>servlet-4.0</feature>
<feature>transportSecurity-1.0</feature>
<feature>websocket-1.1</feature>
<feature>jaxws-2.2</feature>
<feature>jaxrs-2.1</feature>

我尝试了不同的方法来解决我的问题:在每个 WEB-INF/META-INF 文件夹中创建 beans.xml,尝试使用 @LocalBean 和 @Local-interface - 并使用 @EJB(lookup = "java :global/ApplEAR/EJBModule/UserBean!de.example.service.UserBean"),改用@Inject。

在...的帮助下

InitialContext ctx = new InitialContext();
            Object service = ctx.lookup(java:global/ApplEAR/EJBModule/UserBean!de.example.service.UserBean);

我可以查找 bean,但使用注释会更容易。

那么我错过了什么或做错了什么?

标签: dependency-injectionnullpointerexceptionejbwebsphere-libertyjava-ee-8

解决方案


我将给出一个没有解释的答案(因为我无法描述 JAX-RS 中 EJB 与 CDI 注入的所有细微差别、规范等)。

您可以通过从RestBean中删除 EJB 注释并添加以将其转换为 CDI 管理的 bean,从而将UserBean注入到RestBean中。@Dependent

// ... 
import javax.enterprise.context.Dependent;

//@Stateless(name = "RestBean")
@Path("/restElements")
@Dependent
public class RestBean implements IRestBean {

这假设您不需要将RestBean用作远程 EJB,并且可以仅将其用作 CDI 管理的 bean 和/或 JAX-RS 资源。

注意:这假设您启用了 CDI 功能,您可以通过/间接方式启用)。


推荐阅读