Home > Java > Asynchronous messaging using JMS on WebSphere 7.0

Asynchronous messaging using JMS on WebSphere 7.0

March 3rd, 2011

Recently I had to create quick integration for two J2EE applications. Both application use IBM Web Sphere 7.0 as Application server. Both of J2EE applications use topics/queues as destinations. What I needed to do is to write small application that will read from destination and write to different destination.
In this post I will introduce you with a simple J2SE JMS example and how to deploy it/test it on WebSphere 7.0.
In an enterprise application is common to use asynchronous messaging. It is useful when you have to deliver a message (even if the destination is down) and you do not wait for a response in real time. In Java, we’ve got the JMS (Java Messaging Service) to work with asynchronous messaging.

Setting up the JMS Provider and the Destination

Let's start with server side configuration. This setup is made only once, here we create an Integration Bus, JMS Provider, Connection Factory, Destination (in this case it will be a queue) and Activation specifications.
There are many different JMS providers but we will use Websphere Application Server 7.0 JMS Provider.

Creating the Service Integration BUS (SIB)

Run the Websphere Application Server (you can do that through the Server Perspective, right click on WAS -> Start) and open its Administrative Console (right click on WAS -> Administration -> Run Administrative console). There, go to the MENU Service Integration and click on Buses.

  • On the buses screen, click on New button.
  • Next, insert the name JMSBus and then click Next and Finish.
  • Back to the Buses screen, click on Save link and then the MDBus will be created and committed.

Now, click on JMSBus link to open a new screen.


We’re going to use the three links on the right side. The first one is the Bus Member. Click on it.
On the next screen, click on Add button. Choose the first option Server.

  • Click on Next
  • choose File store and Next again.
  • On third screen, change the values: Log size: 10, Minimum permanent store size: 20, Maximum permanent store size: 50,
  • Click on Next button, Finish and Save link.


Now, let’s create the Destionations. Few words about destinations, destination has a type (queue or topic) and a name. We can use simple api's and create destination on the fly :
Destination destination = session.createQueue(“HelloWorld”);
But in our case we will use Websphere and create destination there.
Go back to the JMSBus screen and click on Destinations link.

  • Click on New button
  • Select Queue and click on Next
  • Enter: JMSQueue as Identifier. Also, click on Next.
  • Click on Next again.
  • Finally, click on Finish.

The SIB (Service Integration Buses) is created. The next step is to create the JMS Provider. Let’s do it.

Creating the JMS Provider

Go to the menu Resources -> JMS -> JMS Providers. Select Default messaging provider where in the scope column you can find same node name where Service Integration Bus was created in previous step.

On the Default messaging provider screen, let’s create the Queue connection factory, Queue and the Activation Specification.

Creating the Queue Connection factory

Click on Queue Connection factories link. On the new screen, click on New button.
On the new screen, fill up the following fields:

  • Name (JMSQueueCF)
  • JNDI name (jms/messageCF)
  • Bus name (JMSBus)


Click on Ok button and then Save link.

Creating the Queue

Click on Queue link and then New button. On the new screen, fill up the following fields:

  • Name (JMSQueue)
  • JNDI name (jms/messageQueue)
  • Bus name (JMSBus)
  • Queue name (JMSQueue)

Click on Ok button and then Save link.

Creating the Activation specifications

Click on Activation specifications link and then click on New button.
On the new screen, fill up the following fields.

  • Name (JMSActivationSpec)
  • JNDI name (jms/activationSpec)
  • Destination type (Queue)
  • Destination JNDI name (jms/messageQueue)
  • Bus name (JMSBus)


Click on OK button and then Save link.
Both SIB and the JMS Provider were setup. Make sure to restart the Websphere server before continue this article.

Creating JMS Sender/ Receiver Client

Now we will create pair of simple applications based on what we just discussed. The first will send a message to a JMSQueue which was created in previous step. The second application will receive the message off of that Queue.

Message Sender application

First we will create an interface with Message sender methods:

public interface IMessageSender {

void close() throws Exception;

void send(String message) throws Exception;

void connect(String hostname, String portNumber, String QueueName) throws Exception;

}

Now let's implement this interface:


public class JMSMessageSender implements IMessageSender {

Connection connection=null;

Session producerSession = null;

MessageProducer producer = null;

@Override

public void close() throws JMSException {

//close resources

if (producer != null) {

producer.close();

}

if (producerSession!=null){

producerSession.close();

}

if (connection!=null){

connection.close();

}

}

@Override

public void connect(String hostname, String portNumber, String QueueName)

throws Exception {

//Here we prepare correct naming to work with WebSphere

Hashtable env = new Hashtable();

env.put(Context.PROVIDER_URL, "iiop://"+hostname+":"+portNumber+"");

env.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory");

InitialContext initialContext = new InitialContext(env);

// creating a connection factory

ConnectionFactory connectionFactory = (ConnectionFactory) initialContext.lookup("jms/messageCF");

// create destination

Destination destSend = (Destination)initialContext.lookup(QueueName);

// create a connection

connection = connectionFactory.createConnection();

System.out.println("* connection created...");

// create a session

producerSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

// create a producer

producer = producerSession.createProducer(destSend);

}

@Override

public void send(String message) throws JMSException {

TextMessage textMessage;

textMessage = producerSession.createTextMessage(message);

if (producer != null) {

//send message to JMS queue

producer.send(textMessage);

}

}

}

There is nothing special in the code above. We implemented method connect where we created connection factory using naming WebSphere naming convention then we created connection, session producer and destination.
Now let's talk about not trivial stuff. If server and SIB service differs from default configuration we will face a problem connecting to a server and to our JMSQueue. Few things need to be checked in that case.

In Websphere Administration console open :
Servers->Application servers -> server1(my server name) -> Ports in communication tab.

In the Ports tab check ports for Bootstrap server and  for SIB_END_POINT.

BOOTSTRAP_ADDRESS port need to be used as portnumber in the Connect method:
And  if SIB_END_POINT differs from 7276 (which is default sib service port) we need to change it in the WebSphere Queue Connection factory properties.
Resources-> JMS -> Queue Connection factories -> select JMSQueueCF and add to Provider endpoints new servername:SIB_ENDPOINT_ADDRESS:transport chain name:

Message Receiver application

First we will create an interface with Message receiver methods:


public interface IMessageReceiver {

void close() throws Exception;

TextMessage receive() throws Exception;

void connect(String hostName, String portNumber, String connectionFactoryString,

String consumerJNDIName) throws Exception;

}

Now let's implement this interface:



public class JMSMessageReceiver implements IMessageReceiver {

Connection connection = null;

Session consumerSession = null;

MessageConsumer consumer = null;

@Override

public void close() throws Exception {

//close resources

if (consumer != null) {

consumer.close();

}

if (consumerSession!=null){

consumerSession.close();

}

if (connection!=null){

connection.close();

}

}

@Override

public void connect(String hostName, String portNumber,

String connectionFactoryString, String consumerJNDIName)

throws Exception {

Hashtable env = new Hashtable();

env.put(Context.PROVIDER_URL, "iiop://"+hostName+":"+portNumber+"");

env.put(Context.INITIAL_CONTEXT_FACTORY, "com.ibm.websphere.naming.WsnInitialContextFactory");

InitialContext initialContext = new InitialContext(env);

ConnectionFactory connectionFactory = (ConnectionFactory) initialContext.lookup(connectionFactoryString);

connection = connectionFactory.createConnection();

connection.start();

// create destination - JMSQueue

Destination destinationReceiver = (Destination)initialContext.lookup(consumerJNDIName);

consumerSession = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

consumer = consumerSession.createConsumer(destinationReceiver);

}

@Override

public TextMessage receive() throws Exception {

TextMessage msg = (TextMessage) consumer.receive();

return msg;

}

}

The code above is similar to sender implementation. We implemented method connect where we created connection factory using naming WebSphere naming convention then we created connection, session producer and destination.

Creating Testing Application

Now we will create simple J2SE application that will send and receive messages from WebSphere Queue that was created.


package client;

import javax.jms.*;

import message.IMessageReceiver;

import message.IMessageSender;

import message.JMSMessageReceiver;

import message.JMSMessageSender;

public class JMSTester {

public static void main(String[] args) {

String hostName = "localhost";

String hostPort = "2810";

String QueueName="jms/messageQueue";

String ConnectionFactoryName= "jms/messageCF";

IMessageSender messageSender = null;

IMessageReceiver messageReceiver =null;

messageSender = new JMSMessageSender();

try {

System.out.println("calling messageSender connect(" + hostName +", " + hostPort + ", " + QueueName + ")");

messageSender.connect(hostName, hostPort, QueueName);

} catch (Exception e) {

System.out.println(e.getMessage());

}

try {

String message = "Hello World";

messageSender.send(message);

System.out.println("send message(" + message + ")");

} catch (Exception e) {

System.out.println(e.getMessage());

}

messageReceiver = new JMSMessageReceiver();

try {

System.out.println("calling messageReceiver connect(" + hostName +", " + hostPort + ", " + ConnectionFactoryName + ", " + QueueName + ")");

messageReceiver.connect(hostName, hostPort, ConnectionFactoryName, QueueName);

} catch (Exception e) {

System.out.println(e.getMessage());

}

try {

// receive our message

TextMessage m = messageReceiver.receive();

System.out.println("Received message(" + m.getText() + ")");

} catch (Exception e) {

System.out.println(e.getMessage());

}

}

}

Compiling JMS code

Now that you have created the JMS components and defined them in JNDI, we must make WebSphere Application Server to support our client. To do this download and install sibc.jms.jar , sibc.jndi.jar  into the project.

Look at the Console view, the whole producing and consuming messaging process, will be printed on the console, like image below.

The article ends here. It was a simple article, but I think it was a good starting point for whom wants to get started on JMS world.
Hope it was fun. See you on the next article.

zp8497586rq
Categories: Java Tags: , ,
  1. Rafael
    May 10th, 2011 at 21:49 | #1

    Hey, nice article! But, can you provide us the code? All information are in images, I’m not able to copy that :(
    Thanks

  2. NZ
    June 14th, 2011 at 14:24 | #2

    code provided :)

  3. Hussein
    August 5th, 2011 at 16:41 | #3

    great work thanks

  4. Jose Manuel
    October 4th, 2011 at 22:59 | #4

    Hello, good work!! I have tried this queue configurations in 2 servers, one with the standard ports and the other with different port numbers, with the second case I’m having some problems, I can’t connect with the queue… can you be more explicit how can i can configure the ConnectionFactory and wich is the part of code that I have to modify…

    Thanl you so much! =)

  5. Siva
    October 23rd, 2011 at 15:18 | #5

    Excellent.

  6. February 23rd, 2012 at 12:57 | #6

    is this code available for .net

    • NZ
      February 23rd, 2012 at 16:22 | #7

      I am not an expert in .Net, but I can say that you can configure Websphere 7.0 as described, then you should use .Net WCF capabilities creating connection to Queues and topics.
      But it’s impossible to use this code “as is” in .Net.

  7. February 24th, 2012 at 07:59 | #8

    Thanks…it will be useful if u post some links related to .net

  8. NZ
    February 26th, 2012 at 15:40 | #9

    some info about WCF and Websphere MQ you can find here : http://publib.boulder.ibm.com/infocenter/wmqv7/v7r0/index.jsp?topic=%2Fcom.ibm.mq.csqzav.doc%2Fun12260_.htm
    it’s not exactly what you need but with some adjustments it should work.
    Generally try google you will find there all you need :))))))

  9. February 27th, 2012 at 06:36 | #10

    Thanks a lot…. :D

  10. May 13th, 2012 at 18:37 | #11

    It’s fantastic that you are getting ideas from this piece of writing as well as from our argument made at this place.

  11. buch
    June 22nd, 2012 at 15:23 | #12

    hi
    Im not using default SIB_END_POINT 7276 and when starting my applciation server nothing is listening on that port ? DO you know what should I do ?How to enable that ports ?

    SIB_ENDPOINT_ADDRESS 31024
    SIB_ENDPOINT_SECURE_ADDRESS 31025

  12. dhaval vyas
    December 27th, 2012 at 00:04 | #13

    The port number for webspehre 7.0 is 2809.

  13. December 29th, 2012 at 12:00 | #14

    My programmer is trying to convince me to move to .net from PHP.
    I have always disliked the idea because of the expenses.
    But he’s tryiong none the less. I’ve been using Movable-type on various websites for about a year and am anxious about switching to another platform.
    I have heard fantastic things about blogengine.net.
    Is there a way I can import all my wordpress content into it?
    Any kind of help would be greatly appreciated!

  14. Arun
    March 7th, 2013 at 22:56 | #15

    @Arun
    Sorry …
    It is working. I have made changes but i am not restarted the server.

  15. Vin
    March 25th, 2013 at 14:18 | #16

    Hi I have tried to follow ur article and getting this error. The port numbers are same as defined in communcation->ports. Can somebody guide me over that?

    calling messageSender connect(localhost, 2810, jms/messageQueue)
    CWSIA0241E: An exception was received during the call to the method JmsManagedConnectionFactoryImpl.createConnection: com.ibm.websphere.sib.exception.SIResourceException: CWSIT0006E: It is not possible to connect to bus JMSBus because the following bootstrap servers could not be contacted [localhost:7287:BootstrapSecureMessaging, localhost:7277:BootstrapBasicMessaging] and the following bootstrap servers returned an error condition []. See previous messages for the reason for each bootstrap server failure..
    null
    calling messageReceiver connect(localhost, 2810, jms/messageCF, jms/messageQueue)
    CWSIA0241E: An exception was received during the call to the method JmsManagedConnectionFactoryImpl.createConnection: com.ibm.websphere.sib.exception.SIResourceException: CWSIT0006E: It is not possible to connect to bus JMSBus because the following bootstrap servers could not be contacted [localhost:7287:BootstrapSecureMessaging, localhost:7277:BootstrapBasicMessaging] and the following bootstrap servers returned an error condition []. See previous messages for the reason for each bootstrap server failure..
    null

  16. MegB
    September 6th, 2013 at 19:56 | #17

    Can you please email me the code. I am not able to copy from the images.
    Thanks

Comments are closed.