[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