2011-11-17 87 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