2010-08-18 7 views
6

[ACTUALIZACIÓN : Después de la discusión en los foros Glassfish/ml a un http://forums.java.net/jive/thread.jspa?messageID=480532 de fallo en Glassfish https://glassfish.dev.java.net/issues/show_bug.cgi?id=13040 para este problema.]"No se puede convertir ejbRef de EJB" en la CDI (Weld) la inyección de @Stateless EJB en @SessionScoped JSF2 frijol en Glassfish

Estoy intentando inyectar una vista local sin interfaz de un EJB @Stateless en un bean de respaldo JSF2 @Named @javax.enterprise.context.SessionScoped. El EJB es uno de varios que extienden una clase base genérica abstracta. La inyección de "@Inject TheEJBClass varName" falla con "No se puede convertir ejbRef for ejb TheEJBClass en un objeto comercial de la clase de tipo my.package.name.TheAbstractBase". [edit: en realidad, resulta que la inyección tiene éxito, pero falla la resolución del método en el proxy inyectado para los métodos heredados de las superclases.] Si utilizo "@EJB TheEJBClass varName", varName permanece nulo, es decir, no se inyecta nada.

Detalles:

estoy corriendo Glassfish 3.0.1 en Linux (Ubuntu 10.04 en caso de que importa) y que tienen verdaderos problemas de manejo de la inyección de mis EJB modelo de datos en mi sesión de ámbito JSF2 modelos usando CDI (soldadura) . Y sí, antes de preguntar, tengo beans.xml en su lugar y CDI se está activando para realizar la inyección.

Si me inyecto con una anotación @EJB, por ejemplo:

@EJB TheEJBClass memberName; 

... el EJB no es realmente inyectada, dejando memberName nula.

Si me inyecto con una anotación de CDI @Inject:

@Inject TheEJBClass memberName; 

... entonces CDI se queja cuando llamo a un método de "memberName" que se implementa en una superclase de TheEJBClass y no se reemplaza en su TheEJBClass uno mismo, la presentación de informes:

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

he intentado convertir la base de clase concreta y de-generifying, pero se encuentran con el mismo problema, por lo que no creo que estoy golpeando los errores de soldadura con bases genéricas (https://jira.jboss.org/browse/WELD-305, https://jira.jboss.org/browse/WELD-381, https://jira.jboss.org/browse/WELD-518).

Un esquema del código, con la calificación paquete completo de anotaciones añadidas para mayor claridad, es decir:

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

Nota que la inyección hace trabajo si puedo reemplazar TheAbstractBase.getValue() en TheEJBClass, o si llamar a un método definido en TheEJBClass y no a ninguna superclase. Parece que el problema tiene que ver con la herencia.

Código muy similar que utilizaba características de ciclo de vida e inyección integradas de JSF2 funcionó, pero dado que este es un proyecto nuevo y CDI es el futuro, pensé que era mejor intentar ir a CDI. Esto es lo que empecé a cabo con el uso de la inyección JSF2/EJB, que trabajó:

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

Actualmente estoy trabajando en la elaboración de un caso de prueba en sí misma, pero pensé que iba a disparar la pregunta ahora en este caso es algo en lo que estoy haciendo algo tonto o hay una solución bien conocida que mi Google-fu no puede encontrar. ¿Por qué funcionó con la inyección JSF2/EJB, pero falla con la inyección CDI?

(Desde re-publicado en los foros de Glassfish como http://forums.java.net/jive/thread.jspa?threadID=152567)

+0

He creado un caso de prueba que demuestra este problema. Parece que se trata de cómo la envoltura de JavaAssist generada por CDI resuelve las referencias a los métodos definidos en las superclases. El problema no está en realidad en el momento de la inyección, sino en el momento en que se llama a un método heredado de una superclase a través del reiniciador inyectado. El uso de nomenclatura y alcance JSF2 o CDI no tiene nada que ver con eso, es solo @EJB vs @Inject Ver comentarios y ejemplos en: http://www.postnewspapers.com.au/~craig/public_files_keep/ ErrorDemo.zip (src) y http://www.postnewspapers.com.au/~craig/public_files_keep/ErrorDemo.war (webapp). –

+0

... y para el dolor adicional, el problema se revierte bastante en JBoss AS 6. La inyección CDI funciona bien, pero falla la inyección JSF2. –

Respuesta

3

Como se señaló anteriormente, se trata de un/glassfish fallo de soldadura.

Solución: renunciar a Glassfish y pasar a JBoss AS 7, que en realidad funciona la mayor parte del tiempo.

+2

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

Cuestiones relacionadas