2010-08-18 67 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