Domanda

Sono ragionevolmente nuovo a Java EE, quindi questo potrebbe essere stupido .. orso con me pls: D

Vorrei iniettare un bean di sessione senza in un bean message-driven. In sostanza, il MDB riceve un messaggio JMS, quindi utilizza un bean di sessione per eseguire il lavoro. Il session bean detiene la logica di business.

Ecco la mia Session Bean:

@Stateless
public class TestBean implements TestBeanRemote {

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

L'interfaccia di corrispondenza:

@Remote
public interface TestBeanRemote {

  public void doSomething();
}

Ecco la mia 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();
    }
}

Finora, non è scienza missilistica, giusto?

Purtroppo, durante la distribuzione di questo per GlassFish v3, e l'invio di un messaggio al appropriata coda JMS, ottengo errori che GlassFish non è in grado di individuare il 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]]]

Quindi le mie domande sono le seguenti:

  • è questo il modo corretto di iniettare un bean di sessione in un altro bean (in particolare un messaggio guidato fagioli)?
  • il motivo per cui è la ricerca di denominazione fallendo?
È stato utile?

Soluzione 4

Ok, ho scoperto che se aggiungo le @LocalBean annotazione al bean di sessione, funziona. Ma che ...?

Altri suggerimenti

Potresti provare a definire le cose in questo modo:

@Remote
public interface TestBeanRemote {

  public void doSomething();
}

@Stateless(name="TestBeanRemote")
public class TestBean implements TestBeanRemote {

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

E poi nel 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();
    }
}

Se questo lavoro, cercherò di fornire una spiegazione:)

Credo che il problema del primo esempio è che si sta cercando di iniettare l'attuazione del EJB e non la sua interfaccia. La vista non-interfaccia locale di EJB 3.1 è solo possibile se non si definisce alcuna interfaccia, nemmeno un unico telecomando. Quindi cambiando il punto di iniezione al seguente dovrebbe funzionare:

 @EJB
 private TestBeanRemote testBean;

Se si utilizza l'applicazione all'interno di un ambiente non cluster, in modo singola JVM, si dovrebbe pensare di cambiare l'interfaccia per @Local. Non appena si accede a EJB usando la loro interfaccia remota, si stanno ottenendo un sacco di spese generali. Parametri e valori di ritorno non sono accessibili mediante riferimento più, ma per valore, in quanto sono sempre copiati (specifica dice così). Questo potrebbe portare a problemi di Prestazioni quando si tratta di oggetti complessi.

spera che ha aiutato.

Sembra che il mio problema era legato a Inversion of Control e causato dalla mia mancanza di conoscenza e suggerimenti Netbeans' per i nomi / interfaccia della classe.

ho scoperto che - al fine di trovare la giusta il fagiolo e l'interfaccia di destra - io non li nome corretto. Ecco cosa funziona:

@Remote
public interface Test {

  public void doSomething();
}

@Stateless
public class TestBean implements Test {

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

E nel MDB accedo 'Test' non '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();
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top