[
更新
:在Glassfish论坛上讨论后/ml
http://forums.java.net/jive/thread.jspa?messageID=480532
一只虫子被用来对付玻璃鱼。
https://glassfish.dev.java.net/issues/show_bug.cgi?id=13040
关于这个问题。]
我正在尝试将@stateless EJB的本地无接口视图注入名为@javax.enterprise.context.sessionscoped backing bean的jsf2。EJB是扩展抽象泛型基类的几种类型之一。“@inject theejbclass varname”的注入失败,原因是“无法将ejb的ejbRef转换为class my.package.name.theabstractBase类型的业务对象”。
[编辑:事实上,事实证明注入成功,但是从超类继承的方法的注入代理中的方法解析失败。]
如果我使用“@ejb theejbclass varname”,那么varname将保持为空,即不注入任何内容。
细节:
我在Linux上运行Glassfish 3.0.1(如果有问题的话,可以使用Ubuntu10.04),在处理使用CDI(Weld)将数据模型EJB注入JSF2会话范围的模型时遇到了实际问题。是的,在您询问之前,我已经准备好beans.xml,CDI正在激活以执行注入。
如果我用@ejb注释注入它,例如:
@EJB TheEJBClass memberName;
…实际上没有注入EJB,membername为空。
如果我用cdi@inject注释注入它:
@Inject TheEJBClass memberName;
…然后,当我调用“membername”方法时,CDI会抱怨,该方法是在jbclass的超类中实现的,而不是在jbclass本身中重写的,报告:
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;
}
}
注意注射
做
如果我重写了jbClass中的bstractBase.getValue(),或者如果我调用了jbClass中定义的方法,而不是任何超类,则可以工作。这似乎与继承有关。
使用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
)