Estoy razonablemente nueva de Java EE, así que esto podría ser estúpido.. llevar conmigo pls 😀

Me gustaría inyectar un bean de sesión sin estado en un message-driven bean. Básicamente, el MDB obtiene un mensaje JMS, a continuación, utiliza un bean de sesión para realizar el trabajo. El bean de sesión contiene la lógica de negocio.

Aquí está mi Bean de Sesión:

@Stateless
public class TestBean implements TestBeanRemote {

  public void doSomething() {
    //business logic goes here
  }
}

La coincidencia de interfaz:

@Remote
public interface TestBeanRemote {

  public void doSomething();
}

Aquí está mi MDB:

@MessageDriven(mappedName = "jms/mvs.TestController", activationConfig =  {
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
    })
public class TestController implements MessageListener {

 @EJB
 private TestBean testBean;

    public TestController() {
    }

    public void onMessage(Message message) {
      testBean.doSomething();
    }
}

Hasta el momento, no es ciencia de cohetes, ¿verdad?

Por desgracia, cuando la implementación de este a glassfish v3, y el envío de un mensaje a la Cola JMS, me da errores de que glassfish es capaz de localizar la TestBean EJB:

java.lang.IllegalStateException: Exception attempting to inject Remote ejb-ref name=mvs.test.TestController/testBean,Remote 3.x interface =mvs.test.TestBean,ejb-link=null,lookup=null,mappedName=,jndi-name=mvs.test.TestBean,refType=Session into class mvs.test.TestController
Caused by: com.sun.enterprise.container.common.spi.util.InjectionException: Exception attempting to inject Remote ejb-ref name=mvs.test.TestController/testBean,Remote 3.x interface =mvs.test.TestBean,ejb-link=null,lookup=null,mappedName=,jndi-name=mvs.test.TestBean,refType=Session into class mvs.test.TestController
Caused by: javax.naming.NamingException: Lookup failed for 'java:comp/env/mvs.test.TestController/testBean' in SerialContext  [Root exception is javax.naming.NamingException: Exception resolving Ejb for 'Remote ejb-ref name=mvs.test.TestController/testBean,Remote 3.x interface =mvs.test.TestBean,ejb-link=null,lookup=null,mappedName=,jndi-name=mvs.test.TestBean,refType=Session' .  Actual (possibly internal) Remote JNDI name used for lookup is 'mvs.test.TestBean#mvs.test.TestBean' [Root exception is javax.naming.NamingException: Lookup failed for 'mvs.test.TestBean#mvs.test.TestBean' in SerialContext  [Root exception is javax.naming.NameNotFoundException: mvs.test.TestBean#mvs.test.TestBean not found]]]

Así que mis preguntas son:

  • es esta la forma correcta de la inyección de un bean de sesión en otro bean (particularmente de un bean controlado por mensajes)?
  • ¿por qué es la nomenclatura de búsqueda fallando?

OriginalEl autor Hank | 2010-03-17

4 Comentarios

  1. 6

    Podría intentar definir cosas como esta:

    @Remote
    public interface TestBeanRemote {
    
      public void doSomething();
    }
    
    @Stateless(name="TestBeanRemote")
    public class TestBean implements TestBeanRemote {
    
      public void doSomething() {
        //business logic goes here
      }
    }

    Y, a continuación, en el MDB:

    @MessageDriven(mappedName = "jms/mvs.TestController", activationConfig =  {
    @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
        })
    public class TestController implements MessageListener {
    
        @EJB(beanName="TestBeanRemote")
        private TestBeanRemote testBean;
    
        public TestController() {
        }
    
        public void onMessage(Message message) {
          testBean.doSomething();
        }
    }

    Si este trabajo, voy a tratar de dar una explicación 🙂

    Lo siento, que por desgracia no funciona bien. Creo que voy a ir con lo que me enteré de la Coi. Gracias de todos modos!
    Raro, a mi entender lo que debe. Estoy confundido…

    OriginalEl autor Pascal Thivent

  2. 6

    Creo que el problema de la primer ejemplo es que usted está tratando de inyectar la implementación de EJB y no de su interfaz. El local no-interfaz de vista de EJB 3.1 es sólo posible si no se define ninguna interfaz, ni siquiera un solo control remoto. Para cambiar el punto de inyección a los siguientes trabajos:

     @EJB
     private TestBeanRemote testBean;

    Si usted está utilizando su aplicación dentro de un no agrupado entorno, tan solo JVM, usted debe pensar acerca de cómo cambiar la interfaz a @Local. Tan pronto como usted está accediendo a los Ejb utilizando su interfaz remota, de que está recibiendo un montón de sobrecarga. Los parámetros y valores de retorno no puede ser visitada por referencia, sino más bien por su valor, ya que siempre se copian (especificación dice así). Esto podría conducir a la performence problemas al tratar con objetos más complejos.

    Espera que ayudó.

    OriginalEl autor Roland Tiefenbrunner

  3. 4

    Parece que mi problema estaba relacionado con la Inversión de Control y causado por mi falta de conocimiento y de Netbeans sugerencias para la Clase/Interfaz de nombres.

    Me enteré de que – con el fin de encontrar a la derecha de frijol y el derecho de la interfaz debería nombrar correctamente. He aquí lo que funciona:

    @Remote
    public interface Test {
    
      public void doSomething();
    }
    
    @Stateless
    public class TestBean implements Test {
    
      public void doSomething() {
        //business logic goes here
      }
    }

    Y en el MDB puedo acceder a ‘Prueba’ no ‘TestBean’:

    @MessageDriven(mappedName = "jms/mvs.TestController", activationConfig =  {
    @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
        })
    public class TestController implements MessageListener {
    
        @EJB
        private Test testBean;
    
        public TestController() {
        }
    
        public void onMessage(Message message) {
          testBean.doSomething();
        }
    }
    Se puede agregar cualquier referencia en sus conclusiones acerca de las convenciones de nomenclatura?
    Tratar aquí: java.sun.com/blueprints/code/namingconventions.html
    Ok, me estoy empezando a entender esto más y más ahora. Mi ejemplo anterior sería correcto, si la interfaz sería @Local. Cuando me inyecto un bean de sesión en algo, estoy inyectando <componente-nombre>. El contenedor, a continuación, intenta encontrar la clase de implementación (<componente-nombre>Bean), así como la interfaz apropiada (por @Locales de uso: <componente-nombre> o <componente-nombre>Local, por @de usar el control Remoto: <componente-nombre>mando a distancia). Así que el problema no era JNDI, fue no cumplir con las convenciones de nomenclatura!
    El enlace a las Convenciones de Nomenclatura Documento fue dejado de trabajar. Esta debe ser la correcta: oracle.com/technetwork/java/namingconventions-139351.html

    OriginalEl autor Hank

  4. 3

    Ok, me enteré de que si puedo añadir la anotación @LocalBean para el bean de sesión, funciona. Lo que el …?

    Estoy un poco más ahora. @LocalBean identifica un grano sin una Interfaz. Así que esto no es lo que yo quiero, aunque funciona 😀
    Usted debe haber utilizado «@EJB privado TestBeanRemote testBean;»

    OriginalEl autor Hank

Dejar respuesta

Please enter your comment!
Please enter your name here