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, the MDB gets a JMS message, then uses a session bean to perform the work. The session bean holds the business logic.
Here's my Session Bean:
@Stateless
public class TestBean implements TestBeanRemote {
public void doSomething() {
// business logic goes here
}
}
The matching interface:
@Remote
public interface TestBeanRemote {
public void doSomething();
}
Here's my 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();
}
}
So far, not rocket science, right?
Unfortunately, when deploying this to glassfish v3, and sending a message to the appropriate JMS Queue, I get errors that glassfish is unable to locate the 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]]]
So my questions are:
A message-driven bean is an enterprise bean that allows Java EE applications to process messages asynchronously. This type of bean normally acts as a JMS message listener, which is similar to an event listener but receives JMS messages instead of events.
All message-driven beans MUST implement, directly or indirectly, the javax. jms. MessageListener interface.
The most visible difference between message-driven beans and session beans is that clients do not access message-driven beans through interfaces. Interfaces are described in the section Accessing Enterprise Beans. Unlike a session bean, a message-driven bean has only a bean class.
Message driven bean is a stateless bean and is used to do task asynchronously. Step 1 − Create table in database (Refer to EJB-Persistence chapter). Step 2 − Create Entity class corresponding to table (Refer to EJB-Persistence chapter). Step 3 − Create DataSource and Persistence Unit (Refer to EJB-Persistence chapter).
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 :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With