“Impossibile convertire ejbRef per EJB” sul CDI (Weld) iniezione di @Stateless EJB in @SessionScoped JSF2 fagiolo in Glassfish
-
29-09-2019 - |
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 )
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