2011-11-17 89 views
9

我是Java EE 6和CDI的新手。我已阅读了一些教程和焊接文档。然而,根据我的理解应该起作用的东西并不需要我需要帮助。CDI注入EJB会导致NullPointerException

我有以下情况。我使用随IDE提供的maven原型创建了一个包含NetBeans 7.0.1的Java EE 6应用程序,并将其部署到也由IDE提供的GlassFish 3.1。

beans.xml位于我的EJB jar的META-INF目录中。

我创建工作负全部作为生产者类一类为我的EJB工件(和EntityManager的)

@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; 
    }  

} 

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

但是下面没有在另一个EJB

@Inject 
private NewsEntryFacadeLocal newsEntryFacade; 

这是一个无状态会话EJB做什么注入,但是当我试图访问newsEntryFacade在我的任何业务方法抛出NullPointerException异常。所以显然没有注射正在发生或我的生产者产生空引用。

我错过了什么吗?或者应该按照CDI/Weld的这个工作吗?我试图将@ EJB注入到Web应用程序部分(但是我需要在我的.war中使用另一个生产者类来工作,这是不是应该这样?) 。

编辑:项目与蚂蚁生成(由NetBeans生成)一起使用。 NetBeans提供的Maven原型有问题吗?看来,在Maven原型中,war和ejb模块之间的CDI注入存在一些问题。我发现,如果我在Web和ejb模块中有单独的生产者,Glassfish会生成一个部署错误,指出存在两个不可区分的接口实现。但是,当我在Web模块中删除生产者时,Weld抱怨说我想注入到我的bean中的EJB模块无法解析。在Ant构建的情况下,EJB可以在没有生产者的情况下@注入,而maven构建需要类中的生产者字段。我无法解释这是如何发生的。在所有的最终部署应该大致相同之后,不是吗?

+0

的另一您尝试注入的EJB是否位于同一个EJB Jar或另一个存档中?注意:在每个部署存档中都应该存在bean-discovery(或CDI)beans.xml。用于.wars的WEB-INF和用于.jars的META-INF – stratwine

+0

是的。两者都有一个beans.xml。 –

+0

我试图将我的项目转换为蚂蚁构建。现在一切正常。我甚至不需要再为战争和ejb模块创建单独的生产者。现在的问题是:maven原型有问题吗?还是有什么特别的注意事项要考虑? –

回答

0

尝试将@Named放入EjbArtifactProducer。另外,如果产品是这种简单的,我认为最好也删除它(否则,你应该再做一次更改)。

1

如果你想使用@Inject然后注释它为@Named @ApplicationScoped,否则使用@EJB时注入你的单身。

0

很难说出什么地方出了问题,但是对我们来说确实不起作用的是在类加载器边界之间使用CDI。例如,如果您的应用程序被封装为耳朵文件,您可以将ejbs放在jar文件中,并将您的webapp放入war文件中。在这种情况下,你不能使用CDI在你的Web层注入你的ejbs。问题在于jar和war是由不同的类加载器加载的。也许更新的CDI实现行为不同,但至少JBoss 6和Glassfish有这个问题。

1

约旦丹尼森是正确的。您正在尝试使用@Inject和EJB,但您正在使用@EJB作为EJB。你是EJB类可能注释了@Stateless什么的。 @Inject应该用于注释为@Named和某种范围的会话bean。

0

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

在这种情况下,您对问题有一个清晰的分离。

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

如果你有一个干净的图层,每个都有他自己的问题,我认为你最好找到这个NullPointerException的原因..我认为你的NullPointerException不会存在这之后的任何更多...

分层:

Web浏览器 - > JSF的facelet - > CDI辅助Bean - > EJB服务(S) - > EntityManager的

+0

关于接口的有趣链接 - > http://www.adam-bien.com/roller/abien/entry/how_to_deal_with_interfaces – StefanHeimberg