Pergunta

Estou razoavelmente novo para Java EE, então isso pode ser estúpido..tenha paciência comigo pls :D

Eu gostaria de injetar um stateless session bean em um message-driven bean.Basicamente, o MDB recebe uma mensagem de JMS, em seguida, usa um bean de sessão para executar o trabalho.O bean de sessão que contém a lógica de negócios.

Aqui está o meu Bean de Sessão:

@Stateless
public class TestBean implements TestBeanRemote {

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

A interface correspondente:

@Remote
public interface TestBeanRemote {

  public void doSomething();
}

Aqui está o meu 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();
    }
}

Até agora, não é ciência do foguete, certo?

Infelizmente, ao implantar este glassfish v3, e o envio de uma mensagem para o adequado Fila JMS, eu recebo erros que o glassfish é não é possível localizar o 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]]]

Então minhas perguntas são:

  • é esta a maneira correta de injeção de um bean de sessão para outra feijão (em particular, message driven bean)?
  • qual é a nomeação de pesquisa falhando?
Foi útil?

Solução 4

Ok, descobri que, se eu adicionar a anotação @localbean ao feijão da sessão, ele funciona. O que ...?

Outras dicas

Você poderia tentar definir coisas assim:

@Remote
public interface TestBeanRemote {

  public void doSomething();
}

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

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

E então no 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 isso funcionar, tentarei fornecer uma explicação :)

Eu acho que o problema do primeiro exemplo é que você está tentando injetar a implementação do EJB e não a sua interface.O local não-interface de vista do EJB 3.1 é possível apenas se você não definir qualquer interface, nem mesmo um remoto.Para alterar o ponto de injeção para o seguinte deve funcionar out:

 @EJB
 private TestBeanRemote testBean;

Se você estiver usando seu aplicativo em um ambiente de cluster não, de forma única JVM, você deve pensar em mudar a interface para @Local.Assim que você estiver acessando EJBs usando sua interface remota, você está recebendo um monte de sobrecarga.Parâmetros e valores de retorno não pode ser acessado por referência, mas, por valor, como eles sempre são copiados (especificação diz isso).Isso pode levar a problemas de desempenho ao lidar com objetos mais complexos.

Espera-se que ajudaram.

Parece que meu problema estava relacionado à inversão de controle e causado pela minha falta de conhecimento e sugestões de NetBeans para nomes de classe/interface.

Descobri que - para encontrar o feijão direito e a interface certa - devo nomeá -los corretamente. Aqui está o que funciona:

@Remote
public interface Test {

  public void doSomething();
}

@Stateless
public class TestBean implements Test {

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

E no MDB eu acesse 'teste' não '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();
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top