Java EJB的CDI注入导致NullPointerException

Java EJB的CDI注入导致NullPointerException,java,java-ee-6,glassfish-3,cdi,ejb-3.1,Java,Java Ee 6,Glassfish 3,Cdi,Ejb 3.1,我不熟悉JavaEE6和CDI。我已经阅读了一些教程和焊接文档。然而,从我的理解来看,有些事情应该起作用,但我不需要帮助 我有以下情况。我使用IDE提供的maven原型创建了一个带有NetBeans 7.0.1的JavaEE6应用程序,并将其部署到同样由IDE提供的GlassFish 3.1中 xml位于EJBJAR的META-INF目录中 我已经创建了一个类,它作为EJB工件(和EntityManager)的生产者类单独工作 我试图将@products注释直接应用于方法上的字段,如上图所示 但

我不熟悉JavaEE6和CDI。我已经阅读了一些教程和焊接文档。然而,从我的理解来看,有些事情应该起作用,但我不需要帮助

我有以下情况。我使用IDE提供的maven原型创建了一个带有NetBeans 7.0.1的JavaEE6应用程序,并将其部署到同样由IDE提供的GlassFish 3.1中

xml位于EJBJAR的META-INF目录中

我已经创建了一个类,它作为EJB工件(和EntityManager)的生产者类单独工作

我试图将@products注释直接应用于方法上的字段,如上图所示

但是,以下内容不会在另一个EJB中注入任何内容

@Inject
private NewsEntryFacadeLocal newsEntryFacade;
这是在无状态会话ejb中完成的,但当我尝试在任何业务方法中访问NewEntryFacade时,会引发NullPointerException。所以很明显,没有注入发生,或者我的生产者产生空引用

我错过什么了吗?还是应该按照CDI/Weld进行操作

奇怪的是,当我试图@injectejb到web应用程序部分时,它似乎是这样工作的(但是我需要在我的.war中添加一个额外的producer类才能工作,这是它应该做的吗?)


编辑:该项目使用ant构建(由NetBeans生成)。NetBeans提供的Maven原型是否存在问题?对于Maven原型,war和ejb模块之间的CDI注入似乎存在一些问题。我发现,如果在web和ejb模块中有单独的生产者,Glassfish会生成一个部署错误,指出一个接口有两个不可区分的实现。但是,当我删除web模块中的生产者时,Weld抱怨说,我想要注入web模块中bean的EJB无法解析。同样,在Ant构建中,EJB可以在没有生产者的情况下被@注入,而maven构建需要类上的生产者字段。我无法解释这是怎么发生的。毕竟最终的部署应该或多或少是相等的,不是吗?

试着把@Named放到EjbArtifactProducer中。此外,如果产品是这种简单的,我认为最好也删除它(否则,您应该再做一次更改)。

如果您想使用
@Inject
则将其注释为
@Named@ApplicationScoped
,否则,在注入单例时使用
@EJB

很难判断出哪里出了问题,但对我们来说肯定不起作用的是在类装入器边界之间使用CDI。例如,如果您的应用程序打包为ear文件,那么您的EJB将保存在jar文件中,而webapp将保存在war文件中。在这种情况下,您不能使用CDI将EJB注入web层。问题是jar和war是由不同的类装入器装入的。也许新的CDI实现表现不同,但至少JBoss 6和Glassfish有这个问题。

Jordan Denison是正确的。您试图
@注入
和EJB,但您正在为EJB使用
@EJB
。您的EJB类可能被注释为
@Stateless
或其他东西
@Inject
应该用于带有
@命名的
和某种范围注释的会话bean。

您混合了两个不同的概念。。。使用CDI作为JSF的支持bean。(Web容器中的CDI)并在业务层中使用EJB和JPA。。。CDI层可以注入EJB来调用特定的业务方法

在这种情况下,您在关注点上有一个清晰的分离

顺便说一句:您根本不需要任何EJB接口!如果您需要从远程通信,请仅使用接口。。。(@Remote)。通过@LocalBean注释,您可以直接注入EJB本身

如果你有一个清晰的层分离,每个层都有自己的关注点,我想你最好找到这个NullPointerException的原因。。我想你的NullPointerException在这之后就不存在了

分层:


Web浏览器-->JSF Facelet-->CDI支持Bean-->EJB服务-->EntityManager

您尝试注入的另一个EJB是在同一个EJB Jar中还是在另一个存档中?注意:要启用bean发现(或CDI),每个部署档案中都应该有beans.xml。在WEB-INF for.wars和META-INF for.jarsI中,我试图将我的项目转换为ant构建。现在一切都好了。我甚至不再需要为war和ejb模块创建单独的生产者。现在的问题是:maven原型有什么问题吗?或者有什么特别的注意事项吗?也许你的注射不是在一个被管理的豆科或其他支持注射的EE组件?它是什么/在哪里?让我感到困扰的是,几乎完全相同的代码(一切都是一样的,除了EJB没有生产者定义)适用于ant构建,但不适用于maven构建。关于接口的有趣链接-->
@Stateless
public class EjbArtifactProducer {

    @PersistenceContext(unitName = "trackProfiler-PU")    
    private EntityManager em;

    @EJB
    private UserFacadeLocal userFacade;

    @EJB
    private AuthServiceLocal authService;

    @EJB
    private NewsEntryFacadeLocal newsEntryFacade;

    @EJB
    private RoleFacadeLocal roleFacade;

    @EJB
    private TrackCommentFacade trackCommentFacade;

    @EJB
    private TrackFacade trackFacade;

    @EJB
    private TrackTypeFacade trackTypeFacade;

    @EJB
    private WaypointFacadeLocal waypointFacade;

    @Produces
    public AuthServiceLocal getAuthService() {
    return authService;
    }

    @Produces
    public EntityManager getEm() {
    return em;
    }

    @Produces
    public NewsEntryFacadeLocal getNewsEntryFacade() {
    return newsEntryFacade;
    }

    @Produces
    public RoleFacadeLocal getRoleFacade() {
    return roleFacade;
    }

    @Produces
    public TrackCommentFacade getTrackCommentFacade() {
    return trackCommentFacade;
    }

    @Produces
    public TrackFacade getTrackFacade() {
    return trackFacade;
    }

    @Produces
    public TrackTypeFacade getTrackTypeFacade() {
    return trackTypeFacade;
    }

    @Produces
    public UserFacadeLocal getUserFacade() {
    return userFacade;
    }

    @Produces
    public WaypointFacadeLocal getWaypointFacade() {
    return waypointFacade;
    }    

}