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.
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:
- Open the WebSphere Application Server admin console (the server must be running).
- In the navigation pane on the left, select Service Integration => Buses.
- Select TheBus, and in the following window, select Destinations.
- A list of the bus destinations that are currently defined is displayed. Select New.
- Notice that there are several types of destinations you can create. In our example, we will use a Queue destination. Select Next.
- Enter
PackageReceivedDestinationas the identifier, then select Next. - Accept the bus member by clicking Next again, and then Finish.
- After you save your changes, you can see the new destination in the list, as shown in Figure 1.
Figure 1. Bus destinations
- 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
- 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
- Name:
- Next, select the JMS Queue link in the Default messaging provider window (Figure 2) and click New.
- 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
- Name:
- 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.
- 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
- Name:
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.
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
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
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.
To install and deploy the MDB:
- In the admin console, select Applications => Enterprise Applications in the navigation pane on the left.
- Select Install.
- Select Local file system, enter the name and directory of the EAR file that contains the MDB, then select Next.
- Make sure that the Generate Default Bindings is checked, then Next.
- In the next window, check Deploy enterprise beans, then select Next.
- Select Next on the next two dialogs without making any changes.
- 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
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.
- Select Next, then Finish. When the deployment step is completed, save your changes.
- Your console browser window should now look like Figure 9.
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.
- 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.
- Set up the proper environment by calling the setupcmdline utility.
- 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
- 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
The output log will also contain useful information in case a problem occurred, so it's always a good idea to check on it.
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.
| Name | Size | Download method |
|---|---|---|
| PackageReceived.ZIP | 8 KB | FTP |
Information about download methods
- Building an Enterprise Service Bus with WebSphere Application Server V6: Part 1. Introduction to WebSphere V6 Messaging Resources
- Building an Enterprise Service Bus with WebSphere Application Server V6: Part 2. Business requirements and the bus
- JMS Tutorial from Sun
- JMS Tutorial on developerWorks
- Introduction to the JMS 1.1 API
- IBM Web site for Enterprise Service Bus
- IBM Web site for SOA and Web Services
- Reference collection for Service Data Objects
- Redbook: Patterns: Service-Oriented Architecture and Web Services
- Redbook: Patterns: Implementing an SOA using an Enterprise Service Bus
- Redpaper: Patterns: Using Business Service Choreography In Conjunction With An Enterprise Service Bus
- Resource: The WebSphere Application Server Version 6.0 Information Center
- Redpaper: WebSphere Application Server V6 Technical Overview
- Get involved in the developerWorks community by participating in
developerWorks blogs.
- Browse for books on these and other technical topics.

Rachel Reinitz is a Senior Consulting IT Specialist with IBM Software Services for WebSphere focusing on Web services. Rachel consults with customers and ISVs on how service oriented architecture and Web services can be used to achieve their business and technical objectives. She developed IBM's Advanced Web Services Training course and is a frequent conference presenter. Rachel is also an IBM Academy Member, and an experienced eXtreme Programming coach who has used XP practices for 4 years. She lives in the Bay Area in California, and enjoys hiking, socializing, and international travel.

Andre 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.
Comments (Undergoing maintenance)





