IBM WebSphere Developer Technical Journal: Building an Enterprise Service Bus with WebSphere Application Server V6 -- Part 3

A simple JMS messaging example

In Part 3 of this series on using the new messaging engine in IBM® WebSphere® Application Server V6 to build an Enterprise Service Bus (ESB), we will set up a message-driven bean to listen to messages on a JMS queue and a J2EE client application to send a message to that JMS queue. We will also look at the setup needed to send the JMS message through the message bus in the application server.

Share:

Rachel Reinitz (rreinitz@us.ibm.com), Senior Consulting IT Specialist, IBM

Rachel ReinitzRachel Reinitz is an IBM Distinguished Engineer with IBM Software Services for WebSphere and a member of the IBM Academy of Technology. She has built much of IBM’s internal and external intellectual capital and education on SOA, Enterprise Service Bus, and Web services. Rachel focuses on how to get started with SOA and ESB best practices. She consults with clients and ISVs on how SOA and ESB can be used to achieve their business and technical objectives. She is a frequent conference presenter and written many developerWorks articles on ESB and Web services. Rachel lives in the Bay Area in California, and enjoys hiking, socializing, and international travel.



Andre Tost, Senior Technical Staff Member, IBM

Andre TostAndre Tost works as a Senior Technical Staff Member in the Software Group's Enterprise Integration Solutions organization, where he helps IBM's customers establishing Service Oriented Architectures. His special focus is on Web services technology. Before his current assignment, he spent ten years in various partner enablement, development and architecture roles in IBM software development, most recently for the WebSphere Business Development group. Originally from Germany, he now lives and works in Rochester, Minnesota. In his spare time, he likes to spend time with his family and play and watch soccer whenever possible.



06 April 2005

Also available in Chinese Russian

Introduction

Now that we have gone through the basics of the messaging resources support in IBM WebSphere Application Server V6 (in Part 1), described the business scenario (the Posts-R-Us company) that we will use for this article series and seen how to create an instance of a message bus (in Part 2), it is finally time to do some real work!

In Part 3, we will show you how to create a simple, point-to-point, JMS-based messaging application. The application will consist of a sender part, running within a J2EE™ client application, and a receiver, represented by a message-driven bean (MDB). In creating this application, we will see the setup that is needed to send a JMS message through the message bus in the application server.


JMS and the bus

Following our business scenario, we will assume that whenever a package has been delivered to a customer, a message must be sent to the main system at Posts-R-Us to confirm the delivery. This confirmation message is sent asynchronously, that is, no response is required and the message is simply queued to the main system for processing.

Now you may think that sending a message to a JMS queue and receiving it from there in an MDB is hardly exciting or new. You are right. What makes it interesting here, however, is the fact that the message is actually sent to a destination on the message bus. Doing this enables us to use a mediation to apply optional messaging processing, such as filtering the message content or routing to a different destination, just to name a few. In other words, the bus takes control of the message before it is delivered to the consumer, namely the MDB, providing a level of control that is not available in a traditional JMS scenario.


Creating JMS resources in WebSphere Application Server V6

As a first step, we will create a number of artifacts in the application server: the JMS connection factory, the JMS queue, an activation specification for the MDB, and, of course, the bus destination. We will start with the bus destination and then configure the JMS resources:

  1. Open the WebSphere Application Server admin console (the server must be running).
  2. In the navigation pane on the left, select Service Integration => Buses.
  3. Select TheBus, and in the following window, select Destinations.
  4. A list of the bus destinations that are currently defined is displayed. Select New.
  5. Notice that there are several types of destinations you can create. In our example, we will use a Queue destination. Select Next.
  6. Enter PackageReceivedDestination as the identifier, then select Next.
  7. Accept the bus member by clicking Next again, and then Finish.
  8. After you save your changes, you can see the new destination in the list, as shown in Figure 1.
    Figure 1. Bus destinations
    Figure 1. Bus destinations
  9. Now you are ready to create the JMS artifacts. In the navigation pane of the admin console, select Resources => JMS Providers => Default Messaging. We want the scope to be Node, the default. The dialog in Figure 2 appears.
    Figure 2. Default messaging provider configuration
    Figure 2. Default messaging provider configuration
  10. To create the connection factory, select the JMS Connection Factory link, then New. In the create dialog, enter the following values (Figure 3):
    • Name: TheConnectionFactory
    • JNDI name: jms/TheConncectionFactory
    • Bus name: TheBus

    Leave all other default values, then click OK and save your changes.

    Figure 3. JMS connection factory
    Figure 3. JMS connection factory
  11. Next, select the JMS Queue link in the Default messaging provider window (Figure 2) and click New.
  12. Enter the following values (Figure 4):
    • Name: PackageReceivedQueue
    • JNDI name: jms/PackageReceivedQueue
    • Bus name: TheBus
    • Queue name: PackageReceivedDestination

    Leave all other default values, select OK, and save your changes.

    Figure 4. JMS queue
    Figure 4. JMS queue
  13. The last thing we need is the activation specification, which is new for J2EE 1.4 and binds the MDB to the queue. In the MDB's deployment descriptor, you define the JNDI of an activation spec. In the activation spec itself, you identify the queue that the MDB should listen to. Return to the Default Messaging Provider window in the admin console (Figure 2), and select JMS activation specification, then New.
  14. Enter or select the following values (Figure 5):
    • Name: PackageReceivedActivationSpec
    • JNDI name: eis/PackageReceivedActivationSpec
    • Destination type: queue
    • Destination JNDI name: jms/PackageReceivedQueue
    • Bus name: TheBus

    Leave all other default values, select OK, and save your changes.

    Figure 5. JMS activation specification
    Figure 5. JMS activation specification

These are all the artifacts that we need to send a message to the bus and, from there, to the message-driven bean. Next we will look at the actual Java code.


The Java code

We won't spend a lot of time describing the code that we will use for this example, since it's really no different from any regular JMS code (see Resources for a JMS tutorial), and you can download the code that we use, including the required J2EE deployment descriptors, in the Download section.

Basically, the sender will send a text message containing the number of the package that was delivered. Since this sender code is running in a J2EE client application, we do not hardcode the names of the JMS resources that are used. We use the java:comp/env namespace instead. Both names, one for the connection factory and one for the actual queue, are bound using resource references in the client application deployment descriptor.

Here is an extract of the client code:

Listing 1.
public class Main {
    private final static String JMSCF_JNDI_NAME = "java:comp/env/jms/TheConnectionFactory";
    private final static String JMSQ_JNDI_NAME = "java:comp/env/jms/PackageReceivedQueue";
    private final static String messageText = "Package Received - 24595023";
	
	public static void main(String[] args) throws Exception {
		InitialContext initCtx = new InitialContext();
		
        // Finding the WAS QueueConnectionFactory
        javax.jms.ConnectionFactory qcf = (javax.jms.ConnectionFactory) initCtx.lookup(JMSCF_JNDI_NAME);

        // Finding the Queue Destination
        Destination q = (Destination) initCtx.lookup(JMSQ_JNDI_NAME);

        // Create JMS Connection
        Connection connection = qcf.createConnection();

        // Create JMS Session
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

        // Create MessageProducer and TextMessage
        MessageProducer queueSender = session.createProducer(q);
        TextMessage outMessage = session.createTextMessage();
        outMessage.setText(messageText);

        // Set type and destination and send
        outMessage.setJMSType("package_received");
        outMessage.setJMSDestination(q);
        queueSender.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
        queueSender.send(outMessage);
        
        connection.close();    
        System.out.println("Send completed");
	}
}

For the MDB, things are even simpler. Each MDB has a method, called onMessage(), that is invoked as soon as a message arrives on the queue that the MDB listens to. Here is what it looks like in our example:

Listing 2.
public void onMessage(javax.jms.Message msg) {
	if (!(msg instanceof TextMessage)) {
		System.out.println("Received message is not a text message!");
		throw new RuntimeException();
	}
	TextMessage textMsg = (TextMessage)msg;
	try {
		System.out.println("Received message : "+textMsg.getText());
		// forward the received message to business logic for processing...
	} catch (JMSException x) {
		throw new RuntimeException(x);
	}
}

Both the client application and the MDB have deployment descriptors. We will take a quick look at each one here.

The client deployment descriptor, in a file called application-client.xml, contains references to the JNDI names of the JMS connection factory and queue that are used in the above code. If you open the client deployment descriptor in the Application Server Toolkit, it will look similar to Figure 6.

Figure 6. Client deployment descriptor
Figure 6. Client deployment descriptor

In the code, the Name value is used, combined with the java:comp/env namespace. It is used in the code as a variable called JMSCF_JNDI_NAME. The entry under WebSphere Bindings shows the actual name of the resource as it is deployed in the application server (and remember that earlier we created a JMS connection factory called jms/TheConnectionFactory).

The deployment descriptor for the MDB contains a reference to the JMS activation spec (which in turn is associated with the JMS queue we created earlier), as shown in Figure 7.

Figure 7. MDB deployment descriptor
Figure 7. MDB deployment descriptor

We define a message selector called package_received for this MDB, which enables further filtering of incoming messages. The message selector is set in the client code on the JMS message:

outMessage.setJMSType("package_received");

We package the client and MDB modules into separate EAR files, named PackageReceivedClient.ear and PackageReceived.ear. Before we can run the client, we have to install and deploy the MDB into the application server, which we will do next.


Install and run the Java code

To install and deploy the MDB:

  1. In the admin console, select Applications => Enterprise Applications in the navigation pane on the left.
  2. Select Install.
  3. Select Local file system, enter the name and directory of the EAR file that contains the MDB, then select Next.
  4. Make sure that the Generate Default Bindings is checked, then Next.
  5. In the next window, check Deploy enterprise beans, then select Next.
  6. Select Next on the next two dialogs without making any changes.
  7. Notice that in the following window, you have the ability to overwrite the settings for the activation spec, including the JMS queue that is being used (Figure 8).
    Figure 8. Ability to overwrite the activation spec
    Figure 8. Ability to overwrite the activation spec

    We will not change anything here, but this shows how the application deployer can adjust settings that were made in the EAR file and deployment descriptors.

  8. Select Next, then Finish. When the deployment step is completed, save your changes.
  9. Your console browser window should now look like Figure 9.
    Figure 9. Admin console after installing application
    Figure 9. Admin console after installing application

    Note that the new application has been installed, but it is not started. To start it, select the checkbox next to the application, then Start. The MDB is now ready to receive messages from the bus.

  10. To run the application client to send a message to the bus, open a command prompt window, and change to the \bin directory for the application server profile that you are using. For example, if your profile is named MyShippingCo and you installed WebSphere Application Server in the c:\WebSphere\AppServer6 directory, this will be the directory you want: c:\WebSphere\AppServer6\profiles\MyShippingCo\bin.
  11. Set up the proper environment by calling the setupcmdline utility.
  12. Now, launch the client application by calling the launchclient utilty, passing the client EAR file as the parameter, as shown in Figure 10.
    Figure 10. Launch launchclient utility
    Figure 10. Launch launchclient utility
  13. Check the SystemOut.log file in the \logs\server1 directory. This is where the output for the MDB will go, and it should show the printed message in Figure 11.
    Figure 11. SystemOut.log file
    Figure 11. SystemOut.log file

    The output log will also contain useful information in case a problem occurred, so it's always a good idea to check on it.


Conclusion

In this article, we described a common scenario that we use for building an Enterprise Service Bus with WebSphere Application Server V6 Messaging Resources. We built a client that sends a confirmation message to the bus whenever a package is delivered, using JMS as the protocol to communicate with the bus. The receiver of this message is a message-driven bean, also using JMS as its protocol.

In an upcoming article, we will show you how you can manipulate a message as it flows through the bus using mediations. So stay tuned.


Download

DescriptionNameSize
Code samplePackageReceived.ZIP  ( HTTP | FTP )8 KB

Resources

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into WebSphere on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=57290
ArticleTitle=IBM WebSphere Developer Technical Journal: Building an Enterprise Service Bus with WebSphere Application Server V6 -- Part 3
publish-date=04062005