2010-08-18 64 views
6
@SessionScoped JSF2豆

[UPDATE:在Glassfish的論壇討論後/ ML在http://forums.java.net/jive/thread.jspa?messageID=480532中的錯誤提出了對Glassfish的https://glassfish.dev.java.net/issues/show_bug.cgi?id=13040對於這個問題。]「無法ejbRef轉換爲EJB」 關於CDI(焊接)注入@Stateless的EJB到Glassfish的

我想將@Stateless EJB的本地無接口視圖注入JSF2 @Named @ javax.enterprise.context.SessionScoped支持bean。 EJB是擴展抽象泛型基類的幾個之一。 「@Inject TheEJBClass varName」注入失敗,「無法將ejb TheEJBClass的ejbRef轉換爲類my.package.name.TheAbstractBase類型的業務對象」。 [編輯:事實上,事實證明,注入成功,但在從超類繼承的方法注入代理的方法解決失敗。]如果我使用「@EJB TheEJBClass varName」,那麼varName保持爲空,即沒有任何注入。

詳情:

我(的情況下,它很重要的Ubuntu 10.04),在Linux上運行的Glassfish 3.0.1,並具有處理我的數據模型的EJB注入到我的JSF2會話範圍使用CDI車型的實際問題(焊接) 。是的,在你問之前,我有beans.xml,並且CDI正在激活以執行注射。

如果我有@EJB註解注入它,例如:

@EJB TheEJBClass memberName; 

...該EJB是不實際注入,使成員名稱空。

如果我用CDI @Inject註解注入它:

@Inject TheEJBClass memberName; 

...然後當我打電話說在TheEJBClass的超實施和TheEJBClass沒有被覆蓋「成員名稱」的方法CDI抱怨其自我,報告:

java.lang.IllegalStateException: Unable to convert ejbRef for ejb TheEJBClass to a business object of type class my.package.name.TheAbstractBase 
    at 
com.sun.ejb.containers.EjbContainerServicesImpl.getBusinessObject(EjbContainerServicesImpl.java:104) 
at 
org.glassfish.weld.ejb.SessionObjectReferenceImpl.getBusinessObject(SessionObjectReferenceImpl.java:60) 
.... 

我已經試過鹼轉化爲具體的類和去它泛型化,但遇到同樣的問題,所以我不認爲我打的焊接缺陷與通用基礎( https://jira.jboss.org/browse/WELD-305,https://jira.jboss.org/browse/WELD-381,https://jira.jboss.org/browse/WELD-518)。

代碼的輪廓,與增加了清晰度註釋全包資質,是:

// JSF2 managed backing bean. 
// 
// Called via #{someJSF2Model.value} in a JSF2 page 
// 
@javax.inject.Named 
@javax.enterprise.context.SessionScoped 
public class SomeJSF2Model implements Serializable { 
    @javax.inject.Inject TheEJBClass member; 

    public Integer getValue() { 
     return member.getValue(); 
    } 
    // blah blah 
} 

// One of several EJB classes that extend TheAbstractBase 
@javax.ejb.Stateless 
public class TheEJBClass extends TheAbstractBase { 
    // blah blah 
    // does **NOT** override "getValue()" 
} 

public abstract class TheAbstractBase { 
    // blah blah 
    public Integer getValue() { 
     return 1; 
    } 
} 

注意注射確實工作,如果我重寫TheEJBClass TheAbstractBase.getValue(),或者如果我調用TheEJBClass中定義的方法,而不是任何超類。看起來這個問題與繼承有關。

非常類似的使用JSF2的內置生命週期和注入功能的代碼很有效,但考慮到這是一個新項目,並且CDI是未來事情的發展方向,我認爲最好嘗試去CDI。這裏是我開始了使用JSF2/EJB注入,這工作:

// JSF2 managed backing bean. Using @ManagedBean and JSF2's @SessionScoped 
// instead of CDI @Named and CDI @SessionScoped this time. 
// 
@javax.faces.bean.ManagedBean 
@javax.faces.bean.SessionScoped 
public class SomeJSF2Model implements Serializable { 
    @javax.ejb.EJB TheEJBClass member; 
    public Integer getValue() { 
     return member.getValue(); 
    } 
    // blah blah 
} 

// One of several EJB classes that extend TheAbstractBase 
// Unchanged from CDI version 
@javax.ejb.Stateless 
public class TheEJBClass extends TheAbstractBase { 
    // blah blah 
    // does **NOT** override "getValue()" 
} 

// Unchanged from CDI version 
public abstract class TheAbstractBase { 
    // blah blah 
    public Integer getValue() { 
     return 1; 
    } 
} 

我目前正在組建一個自包含的測試案例,但想到我現在會斷火問題的情況下,該是我只是在做一些愚蠢的事情,或者我的Google-fu找不到的解決方案。它爲什麼可以用於JSF2/EJB注入,但是CDI注入失敗?

(由於重新貼在Glassfish的論壇,http://forums.java.net/jive/thread.jspa?threadID=152567

+0

我已經構建了一個演示此問題的測試用例。這似乎歸結爲CDI生成的JavaAssist包裝器如何解析對超類中定義的方法的引用。問題實際上並不是在注入時,但當時從超類繼承的方法通過注入的包裝調用。 JSF2或CDI的命名和範圍的使用與它無關,它只是@EJB vs @Inject 請參閱評論和示例:http://www.postnewspapers.com.au/~craig/public_files_keep/ ErrorDemo.zip(src)和http://www.postnewspapers.com.au/~craig/public_files_keep/ErrorDemo.war(webapp)。 – 2010-08-18 07:38:17

+0

......並且對於加成痛苦,這個問題在JBoss AS 6中相當相反.CDI注入工作正常,但JSF2注入失敗。 – 2010-08-18 08:37:33

回答

3

如上所述,這是一個焊縫/ GlassFish的錯誤。

修復:放棄Glassfish並遷移到JBoss AS 7,這實際上在大多數情況下都有效。

+2

2010年修復,https://java.net/jira/browse/GLASSFISH-13040 – ymajoros 2014-08-11 15:04:48