How to inject a Session Bean into a Message Driven Bean?

前端 未结 4 807
鱼传尺愫
鱼传尺愫 2021-01-19 00:43

I\'m reasonably new to Java EE, so this might be stupid.. bear with me pls :D

I would like to inject a stateless session bean into a message-driven bean. Basically,

相关标签:
4条回答
  • 2021-01-19 01:31

    It seems that my problem was related to Inversion of Control and caused by my lack of knowledge and Netbeans' suggestions for Class/Interface names.

    I found out that - in order to find the the right bean and the right interface - I should name them properly. Here's what works:

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

    And in the MDB I access 'Test' not '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();
        }
    }
    
    0 讨论(0)
  • 2021-01-19 01:36

    Ok, I found out that if I add the annotation @LocalBean to the session bean, it works. What the ...?

    0 讨论(0)
  • 2021-01-19 01:46

    I think the problem of the very first example is that you are trying to inject the implementation of the EJB and not its interface. The local no-interface view of EJB 3.1 is just possible if you do not define any interface, not even a remote one. So changing the injection point to the following should work out:

     @EJB
     private TestBeanRemote testBean;
    

    If you are using your application within a non clustered environment, so single JVM, you should think about changing the interface to @Local. As soon as you are accessing EJBs using their remote interface, you are getting a lot of overhead. Parameters and return values can not be accessed by reference anymore, but by value, as they are always copied (specification says so). This might lead to performence issues when dealing with more complex objects.

    Hoped that helped.

    0 讨论(0)
  • 2021-01-19 01:50

    Could you try to define things like this:

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

    And then in the 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();
        }
    }
    

    If this work, I'll try to provide an explanation :)

    0 讨论(0)
提交回复
热议问题