[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)
我已經構建了一個演示此問題的測試用例。這似乎歸結爲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
......並且對於加成痛苦,這個問題在JBoss AS 6中相當相反.CDI注入工作正常,但JSF2注入失敗。 – 2010-08-18 08:37:33