Eclipse or SUNrise...

Eclipse or SUNrise...
...JAVA for sure

Monday, October 11, 2010

Configuration of WebSphere Application Server with WebSphere MQ to implement Message Driven Beans part 2

In my last post I showed how to configure WebSphere Application Server with WebSphere MQ. In this post I will implement a sample Message Driven Bean and use it in this environment.

I want to stress that I will create MDB using EJB2.1 specification. I explained the reasons for that in previus post. To create and test the MDB I will use Rational Application Developer version 7.5, but any current version of Eclipse will be good enough.

To start with, let's create a Java Project. Under New Project wizard select EJB project. In next window input the project name (TestAppMDB in my case) and select EJB Module version to 2.1. Also be sure to add an EAR project for our MDB jar. My EAR project which I will deploy on WebSphere Application Server is TestAppMDBEAR. Click finish, we will use the default options for the rest of EJB configurations.



Now, we will create the MDB instance implementation. To do that, switch to Java EE perspective and open Deployment Descriptor. Under Bean tab click "Add..." button to add new bean. In the popup window select Message-driven-bean



For purpose of this sample, you can leave the default options and finish the creator wizard. Now we have to configure couple of settings of the bean. First find a WebSphere Bindings tab under the same Bean tab and select Listener Port checkbox. Under Listener port name type your listener port. In my case it is EmdebListenerPort.



Now another important thing - the references. Go to the next, References tab, select the bean and click Add... button again. A popup window will appear. We have to create two references - both of Resource reference type. Click next and fill the input of the next screen in the following way:



The most important thing is to select Type javax.jms.ConnectionFactory for the factory reference and javax.jms.Queue for the queue reference.



After creating both properties, select one of them. You should see the following screen:



Note that after creating a reference which is a local resource, we have to bind it with the real - JNDI resource. The place to do this is under WebSphere Bindings tab in JNDI name field. Type real JNDI context defined in the WebSphere in previous part. In my case it was jms/EmdebOutConnectionFactory. Remember to do the same thing for the queue definition.

After this part we can finally prepare some implementation. Remember that we will use local references to show the proper J2EE design pattern. The most important method of the MDB is onMessage, which is invoked when the bean instance is created. My, sample onMessage code looks like this:


public void onMessage(javax.jms.Message message) {
System.out.println("onMessage");

try {
if (message instanceof javax.jms.TextMessage) {

String recievedMsg = ((javax.jms.TextMessage) message)
.getText();
System.out.println("[EmdebBean] Recieved Text Message: "
+ recievedMsg);

System.out.println("Message ID: " + message.getJMSMessageID());
System.out.println("Correlation ID: "
+ message.getJMSCorrelationID());

String newTextMessage = "1400";

System.out.println("Messege to sent: " + newTextMessage);
sendResponse((javax.jms.TextMessage) message, message
.getJMSMessageID(), newTextMessage);

} else if (message instanceof javax.jms.BytesMessage) {
System.out.println("[EmdebBean] SAMPLE MDB: Bytes Message ");
} else if (message instanceof javax.jms.StreamMessage) {
System.out.println("[EmdebBean] SAMPLE MDB: Stream Message ");
} else if (message instanceof javax.jms.ObjectMessage) {
System.out.println("[EmdebBean] SAMPLE MDB: Object Message ");
} else if (message instanceof javax.jms.MapMessage) {
System.out.println("[EmdebBean] SAMPLE MDB: Map Message ");
} else {
System.out
.println("[EmdebBean] SAMPLE MDB: Unknown Message Type ");
}
} catch (javax.jms.JMSException e) {
...
} catch (Exception e) {
...
} finally {
...
}
}


Following method prints out the message, which it received and sends a response. To simplify the code I will show the rest of the logic inside on method (which reads properties for the JNDI resources). The code for sendResponse method:


public void sendResponse(javax.jms.TextMessage message, String messageId, String data) {

Context ctx = new InitialContext();
ConnectionFactory connFactory = (ConnectionFactory) ctx
.lookup("java:comp/env/jms/OutConnectionFactory");

connection = connFactory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination dest = (Queue) ctx.lookup("java:comp/env/jms/OutQueue");
producer = session.createProducer(dest);

System.out.println("copying the msg id to corellation id");
message.setJMSCorrelationID(messageId);
message.clearBody();
message.setText(data);
System.out.println("Sending...");
producer.send(message);

System.out.println("Succesfully sent");
}


Remember about the catches and finally clause in your code and some better logging capabilities like common loggings or log4j. Not that in my code I rewrite the message ID to correlation ID. It is important for the client to let him know that this is a response for his request. Also note, thet I use local names to lookup JNDI resources:

  • java:comp/env/jms/OutConnectionFactory,

  • java:comp/env/jms/OutQueue


This is a clear and nice way to separete the configuration of JNDI in J2EE. And that's it. Now, you can test the MDB by deploying it in the application server environment and putting a sample text message in the queue.

You can check the response message attributes using RFHUtil tool for example - just like in my previous post.