Thursday, February 17, 2011

Message Driven Bean with a Datasource

My question is how do I configure an EJB 3.0 style message driven bean to use a configured JMS datasource in jboss.

For example, my MDB looks something like:

@MessageDriven(mappedName = "ExampleMDB", activationConfig = {

        @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
        @ActivationConfigProperty(propertyName = "destination", propertyValue = "MyTopic"),
        @ActivationConfigProperty(propertyName = "channel", propertyValue = "MyChannel"),

})
@ResourceAdapter(value = "wmq.jmsra.rar")
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
@TransactionManagement(TransactionManagementType.BEAN)
public class MyMDB implements MessageListener {
 .....
}

But I would like the bean to attached to a given JMS datasource ( in the case of jboss 4.2.2 this is in deploy/jms/jms-ds.xml). Perhaps this is not even possible but is worth asking.

From stackoverflow
  • If I understood your problem correctly, MyMDB listens to a topic on WebLogic, and you want to use an additional JMS destination provided by JBoss, defined in a deployed configuration file and identified by its JNDI name (by default, deploy/jms/jms-ds.xml only contains the configuration for the JMS provider and connection factories -- no data sources).

    The easiest way is to let the container inject the JMS destination and a connection factory via its JNDI name (in JBoss the JMS destinations are configured by deploying xxx-service.xml files). On startup you can then initialize the connection, and perform cleanup as soon as the MDB is released.

    The following examples shows injection (@Resource) and resource managemend (@PostConstruct and @PreDestroy). The JMS connection and destination is used in useJmsDestination(String) to send a text message.

    public class MyMDB implements MessageListener {
    
     @Resource(mappedName = "queue/YourQueueName") // can be topic too
     private Queue targetDestination;
    
     @Resource(mappedName = "QueueConnectionFactory") // or ConnectionFactory
     private QueueConnectionFactory factory;
    
     private Connection conn;
    
     public void onMessage(Message m) {
      // parse message and do what you need to do
      ...
      // do something with the message and the JBoss JMS destination
      useJmsDestination(messageString);   
     }
    
     private void useJmsDestination(String text) {
      Session session = null;
      MessageProducer producer = null;
    
      try {
       session = conn.createSession(true, Session.AUTO_ACKNOWLEDGE);
       producer = session.createProducer(targetDestination);
       TextMessage msg = session.createTextMessage(text);
       producer.send(msg);
      } catch (JMSException e) {
       throw new RuntimeException(e);
      } finally {
       try {
        if (producer != null) {
         producer.close();
        }
        if (session != null) {
         session.close();
        }
       } catch (JMSException e) {
        // handle error, should be non-fatal, as the message is already sent.
       }
      }
     }
    
    
     @PostConstruct
     void init() {
      initConnection();
      // other initialization logic
      ...
     }
    
     @PreDestroy
     void cleanUp() {
      closeConnection();
      // other cleanup logic
      ...
     }
    
     private void initConnection() {
      try {
       conn = factory.createConnection();
      } catch (JMSException e) {
       throw new RuntimeException("Could not initialize connection", e);
      }
     }
    
     private void closeConnection() {
      try {
       conn.close();
      } catch (JMSException e) {
       // handle error, should be non-fatal, as the connection is being closed
      }
     }
    }
    

    I hope this can help you.

  • I think what you are asking is "How do I specify the JNDI location of the JMS datasource to use for an MDB?"

    In which case the answer is:

    @ActivationConfigProperty(propertyName = "providerAdapterJNDI", propertyValue = "java:/DefaultJMSProvider")
    

    Also, take a look at the following page which provides loads of useful details on configuring MDBs in jBoss: http://www.jboss.org/community/docs/DOC-9352

0 comments:

Post a Comment