2010-08-18 4 views
6

[UPDATE: Après discussion sur les forums Glassfish/ML à http://forums.java.net/jive/thread.jspa?messageID=480532 un bug a été déposée contre Glassfish https://glassfish.dev.java.net/issues/show_bug.cgi?id=13040 J'essaie d'injecter une vue locale sans interface d'un EJB @Stateless dans un bean backing JSF2 @Named @ javax.enterprise.context.SessionScoped. L'EJB est l'un de plusieurs qui étendent une classe de base générique abstraite. L'injection de "@Inject TheEJBClass varName" échoue avec "Impossible de convertir ejbRef pour ejb TheEJBClass en objet métier de type my.package.name.TheAbstractBase". [edit: En fait, il s'avère que l'injection réussit, mais la résolution de méthode dans le proxy injecté pour les méthodes héritées des superclasses échoue.] Si j'utilise "@EJB TheEJBClass varName" alors varName reste nul, ie rien n'est injecté."Impossible de convertir ejbRef pour ejb" sur CDI injection (soudure) de @Stateless EJB en haricot @SessionScoped JSF2 dans Glassfish

Détails:

Je suis en Glassfish 3.0.1 sur Linux (Ubuntu 10.04 au cas où il importe) et ayant des problèmes réels de traitement par injection de mes EJBs modèle de données dans ma session de JSF2 scope modèles utilisant CDI (soudure) . Et oui, avant de demander, j'ai beans.xml en place et CDI est en cours d'activation pour effectuer l'injection.

Si j'injectent avec une annotation @EJB, par exemple:

@EJB TheEJBClass memberName; 

... l'EJB est pas réellement injecté, laissant nulle nomMembre.

Si j'injectent avec une annotation CDI @Inject:

@Inject TheEJBClass memberName; 

... puis CDI quand je plaint appelle une méthode de « nomMembre » qui est mis en œuvre dans une superclasse de TheEJBClass et non redéfinie dans son TheEJBClass auto, rapports:

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) 
.... 

J'ai essayé de convertir la base en classe et en béton de-generifying, mais rencontre le même problème, donc je ne pense pas que je suis frappé les bugs de soudure avec des bases génériques (https://jira.jboss.org/browse/WELD-305, https://jira.jboss.org/browse/WELD-381,).

Un aperçu du code, avec la qualification de package complet sur les annotations ajoutées pour plus de clarté, est:

// 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; 
    } 
} 

Notez que l'injection ne travail si j'Override TheAbstractBase.getValue() dans TheEJBClass, ou si je appelle une méthode définie dans TheEJBClass et non une superclasse. Il semble que la question est quelque chose à voir avec l'héritage.

Le code très similaire qui a utilisé les fonctions intégrées de cycle de vie et d'injection de JSF2 a fonctionné, mais étant donné qu'il s'agit d'un nouveau projet et que CDI se dirige vers l'avenir, j'ai pensé qu'il était préférable d'opter pour CDI. Voici ce que j'ai commencé avec l'utilisation de l'injection JSF2/EJB, qui a travaillé:

// 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; 
    } 
} 

Je travaille actuellement à mettre ensemble un test autonome, mais je pensais que je virerais de la question maintenant dans le cas où cette est quelque chose où je fais juste quelque chose de stupide ou il y a une solution bien connue mon Google-fu n'est pas à trouver. Pourquoi cela a-t-il fonctionné avec l'injection de JSF2/EJB, mais a échoué avec l'injection de CDI?

(Depuis re-posté sur les forums comme Glassfish http://forums.java.net/jive/thread.jspa?threadID=152567)

+0

J'ai créé un scénario de test qui illustre ce problème. Il semble se résumer à la manière dont l'encapsuleur JavaAssist généré par CDI résout les références aux méthodes définies dans les superclasses. Le problème n'est pas réellement au moment de l'injection, mais au moment où une méthode héritée d'une superclasse est appelée via l'enveloppe injectée. L'utilisation de la dénomination et de la portée JSF2 ou CDI n'a rien à voir avec cela, c'est juste @EJB vs @Inject Voir les commentaires et l'exemple dans: http://www.postnewspapers.com.au/~craig/public_files_keep/ ErrorDemo.zip (src) et http://www.postnewspapers.com.au/~craig/public_files_keep/ErrorDemo.war (webapp). –

+0

... et pour la douleur bonus, le problème est à peu près inversé dans JBoss AS 6. L'injection CDI fonctionne bien, mais l'injection JSF2 échoue. –

Répondre

3

Comme indiqué ci-dessus, il est un bug de soudure/GlassFish. Correction: Abandonnez Glassfish et passez à JBoss AS 7, qui fonctionne réellement la plupart du temps.

+2

corrigé en 2010, https://java.net/jira/browse/GLASSFISH-13040 – ymajoros

Questions connexes