“Impossibile convertire ejbRef per EJB” sul CDI (Weld) iniezione di @Stateless EJB in @SessionScoped JSF2 fagiolo in Glassfish

StackOverflow https://stackoverflow.com/questions/3509255

Domanda

[ Aggiorna : Dopo la discussione sul forum Glassfish / ML a http://forums.java.net/jive/thread.jspa?messageID=480532 un bug è stata depositata contro Glassfish https://glassfish.dev.java.net/issues/show_bug.cgi?id=13040 per questo problema.]

Sto cercando di iniettare una vista senza interfaccia locale di un @Stateless EJB in un JSF2 @Named @ javax.enterprise.context.SessionScoped backing bean. Il bean è uno dei tanti che si estendono una classe astratta di base generico. Iniezione di "@Inject TheEJBClass varName" viene a mancare con "Impossibile convertire ejbRef per EJB TheEJBClass ad un oggetto business di tipo classe my.package.name.TheAbstractBase". [edit:. In realtà, si scopre che l'iniezione riesce, ma la risoluzione metodo nel proxy iniettato per metodi ereditati da superclassi fallisce] Se uso "@EJB TheEJBClass varName" quindi varName rimane nullo, cioè nulla viene iniettato.

dettagli:

Io corro Glassfish 3.0.1 su Linux (Ubuntu 10.04 nel caso in cui è importante) e avendo reali problemi di gestione iniezione dei miei EJB modello dati nella mia sessione JSF2 modelli utilizzando CDI (Weld) ambito. E sì, prima di chiedere, ho beans.xml a posto e CDI sta attivando per effettuare l'iniezione.

Se faccio l'iniezione con un'annotazione @EJB, ad esempio:

@EJB TheEJBClass memberName;

... il bean non è effettivamente iniettata, lasciando memberName nullo.

Se faccio l'iniezione con un'annotazione CDI @Inject:

@Inject TheEJBClass memberName;

... poi CDI si lamenta quando chiamo un metodo di "memberName" che è implementata in una superclasse di TheEJBClass e non sottoposto a override in TheEJBClass sua auto, riportando:

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

Ho provato a convertire la base per classe concreta e de-generifying, ma lo stesso problema, quindi non penso che sto colpendo i bug di saldatura con basi generiche ( https://jira.jboss.org/browse/WELD-305 , https://jira.jboss.org/browse/WELD-381 , https://jira.jboss.org/browse/WELD-518 ).

Un profilo del codice, con la qualificazione pacchetto completo sulle annotazioni aggiunte per chiarezza, è:

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

Si noti che l'iniezione ha lavoro se sovrascrivo TheAbstractBase.getValue () in TheEJBClass, o se chiamo un metodo definito nella TheEJBClass e non alcuna superclasse. Sembra che il problema è qualcosa a che fare con l'ereditarietà.

Codice Molto simile che ha utilizzato di JSF2 built-in del ciclo di vita e iniezione caratteristiche funzionato, ma dato che si tratta di un nuovo progetto e CDI è dove le cose si stanno dirigendo in futuro, ho pensato che fosse meglio per cercare di andare per CDI. Ecco quello che ho iniziato con l'utilizzo di JSF2 / iniezione EJB, che ha funzionato:

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

Al momento sto lavorando a mettere insieme un caso di test self-contained, ma ho pensato di sparare la questione ora nel caso in cui questo è qualcosa in cui sto solo facendo qualcosa di sciocco o c'è una soluzione ben nota la mia Google- fu non è fino a trovare. Perché il lavoro con JSF2 / iniezione EJB, ma non riescono ad iniezione CDI?

(Da ri-postato sui forum Glassfish come http: // forum. java.net/jive/thread.jspa?threadID=152567 )

È stato utile?

Soluzione

Come notato sopra, si tratta di una saldatura / bug pesci vetro.

Fix:. Rinunciare a Glassfish e mossa per JBoss AS 7, che funziona in realtà la maggior parte del tempo

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top