This tutorial provides a simple demonstration of both Point to Point (P2P) and Publish and Subscribe (Pub/Sub) messaging involving a message-driven bean (MDB) by walking you through the construction of a fairly simple but thorough test case involving a single MDB and two separate stateless session bean clients. One stateless session bean client sends messages using the P2P method and the other publishes messages using the Pub/Sub method. Both methods are supported by the MQ Simulator for JavaTM Developers (MQ Simulator) in WebSphere® Studio Application Developer (hereafter called Application Developer) Version 5.0. You can download all source code in the ready-to-run deployed modules.
J2EE 1.3 introduced the requirement for an application server to ship with a native Java Messaging Service (JMS) provider. In compliance with these requirements, the WebSphere Application Server V5 now ships with a native JMS provider that is built from WebSphere MQ technology and supports P2P and Pub/Sub with persistent and nonpersistent messages, with the option for the application to connect using both interprocess and network-based connectivity. WebSphere Studio V5 provides an embedded version of the native JMS provider for use with the integrated test environment called MQ Simulator.
MQ Simulator is a new feature in Application Developer Version 5.0. It is pure Java, a low-footprint native JMS provider for use with the integrated test environment that allows rapid turnaround for the developer because it provides the ability to unit test JMS applications without having to additionally install WebSphere MQ or WebSphere Application Server on the development machine. By offering a fully integrated test environment and MQ Simulator, Application Developer provides a configurable self-contained testing environment. Of course, developed applications can be deployed to and tested against enterprise infrastructure unchanged, but with MQ Simulator, it means you can develop and test much faster than with the real thing, decreasing the development cycle.
To keep it light, it does not support persistence or interprocess communication. Features that require these (for example, XA and durable subs) are simulated for the duration of the JVM. It does not, for example, support clients that run outside the appserver JVM process, which always involves some kind of interprocess communication. It does, however, for the same reason, support EJB, servlet or JSP clients -- actually, any client that can run in the same JVM process the MQ Simulator runs in, and any kind of JMS-based application that stays within this restriction. And since it does not support persistence, all JMS resources created and used at run time do not continue to exist after the appserver is shut down.
Though this may sound restrictive, because the messages are all kept in memory within the same process space, it works well because of those reasons and is well suited to unit testing. It is important to note that there is no MQ-specific code your applications must implement or bootstrap and your application should run on any JMS-compliant system without change, whether that is WebSphere MQ or some other messaging system. Furthermore, there is no need for anything else (such as a "real" WebSphere MQ system) but Application Developer itself, since everything is self-contained and ready to run.
Important: MQ Simulator is only available for WebSphere Application Server V5 testing server instances and is not available or supported for WebSphere Application Server V4 server instances. You must therefore create a WebSphere Application Server V5 server instance and configuration as will be demonstrated. In addition, you need the GA version of Application Developer Version 5.0 since MQ Simulator was not available in the beta. The MQ Simulator was designed specifically for use in the Application Developer unit test environment and will not function properly if enabled on a native WebSphere Application Server. While the restrictions on running in process without persistence is fully tolerable for a test environment, it would be unthinkable for a production system.
Development steps you will accomplish
You will perform the following steps:
- Create and configure the EJB project for the MDB
- Create the MDB tester project and two session beans to invoke sending and publishing
- Create and implement methods in the session beans to send and publish messages
- Implement the onMessage() method in the MDB
- Generate Deploy RMIC code
for the session bean testers
- Create and configure a unit test environment server instance and configuration
- Add EJB resource references for the MDB
- Add resource references for the two session beans
- Run and test the EJB beans
- Import EAR files and server configuration (optional)
Your completed J2EE environment as viewed from the J2EE Hierarchy in the J2EE perspective should look like Figure 1 below:
Figure 1. Completed J2EE environment

1. Create and configure the EJB project for the MDB
- Create a new EJB 2.0 project called SimpleMDB in an enterprise application project called DefaultEAR.
- Create a new Message-driven bean called SimpleMessage by
selecting Message-driven bean and entering the following
properties (see Figure 2 below):
- Bean name: SimpleMessage
- Source folder: ejbModule
- Default package: com.yourcomp
Figure 2. Creating a Message-driven bean
- Specify the transaction type as Container and the destination type as Queue.
- Specify a listener port called SimpleListenerPort.
- Click Finish (see Figure 3).
Figure 3. Specifying the transaction type, destination type, and listener port
- Open the EJB Deployment Descriptor for the SimpleMessage bean
to see the values you specified in the wizard. This tutorial demonstrates
both P2P and Pub/Sub but the MDB itself is identical for both
and you can use the same listener port (see Figure 4 below).
Figure 4. EJB Deployment Descriptor for the SimpleMessage bean
2. Create the MDB tester project and two session beans to invoke sending and publishing
- Create a new, separate EJB Project called MDBTester
in a new enterprise application project. This project
contains two ordinary stateless session beans that you create:
a SimpleSender and a SimplePublisher (see Figure
5 below).
Figure 5. Creating the MDBTester EJB project
There is no MQ Simulator limitation or restriction to implement our testing scenario this way -- we could have just created all the EJBs in a single EAR or EJB module or used servlets or JSPs. However, it adds a bit of interest in that the session beans posting messages to the queue are in an entirely different module than the MDB that picks those messages off the queue. In this way, you can keep your business logic isolated from the test beans as well as reuse your test code for other MDBs. - Now, to create a stateless session bean called SimpleSender
in the MDBTester project, select Session bean
and enter these properties: (see Figure 6 below).
- Bean name: SimpleSender
- Source folder: ejbModule
- Default package: com.yourcomp.test
Figure 6. Creating the SimpleSender stateless session bean in the MDBTester project
- Accept the defaults of stateless and container to improve performance and cut back on network overhead when not required, as here, specify Local client view only. For CMP 2.0 beans, the EJB specification states that the default interface is the local interface ("Local client view"), introduced with CMP 2.0, which helps to reduce the network traffic and other overhead from calls between EJBs in the same container. Before local interfaces, the only choice was remote interfaces, increasing this overhead even when the calls were between beans in a single container.
- Accept the defaults and click Add in the CMP attributes
section (see Figure 7).
Figure 7. Selecting Session type, Transaction type, and other details
3. Create and implement methods in the session beans to send and publish messages
- Create a new method called sendMessage() in the SimpleSenderBean
that contains the following code. Notice that the queue name
and the connection factory names use the J2EE convention of the
java:comp/envrather than specifying the JNDI name directly. See the Best Practice: Use Java:comp to Locate EJBs and Increase Application Portability for a good discussion of why you should use Java:comp/env in your J2EE applications for EJBs or any JNDI resources for that matter.<samp>Listing 1</samp> <tt>package com.yourcomp.test; import javax.jms.*; import javax.naming.*; Import javax.naming.directory.*; Import javax.rmi.PortableRemoteObject; public class SimpleSenderBean implements javax.ejb.SessionBean { QueueConnectionFactory queueConnectionFactory = null; QueueConnection queueConnection = null; Queue queue = null; QueueSender queueSender = null; QueueSession queueSession = null; String connectionFactoryName = "Java:comp/env/Simple/jms/SimpleQCF"; String queueName = "Java:comp/env/Simple/jms/SimpleQ"; String message = "My Very Simple Message"; int numMessages = 5; ... public void sendMessage() { try { System.out.println("Getting an Intial Context ..."); Context ctx = new InitialContext(); System.out.println("Getting an QueueConnectionFactory ..."); queueConnectionFactory = (QueueConnectionFactory) PortableRemoteObject.narrow( ctx.lookup(connectionFactoryName), QueueConnectionFactory.class); System.out.println( "Got the QueueConnectionFactory: " + queueConnectionFactory); System.out.println("Getting a QueueConnection ..."); queueConnection = queueConnectionFactory.createQueueConnection(); System.out.println("Got the QueueConnection: " + queueConnection); System.out.println("Getting a QueueSession ..."); boolean transacted = false; queueSession = queueConnection.createQueueSession( transacted, QueueSession.AUTO_ACKNOWLEDGE); System.out.println("Got the QueueSession: " + queueSession); System.out.println("Getting a Queue ..."); queue = (Queue) PortableRemoteObject.narrow( ctx.lookup(queueName), Queue.class); System.out.println("Got the Queue: " + queue); System.out.println("Getting a QueueSender ..."); queueSender = queueSession.createSender(queue); System.out.println("Got the QueueSender: " + queueSender); System.out.println("*** Sending the messages now ***"); for (int i = 1; i < numMessages + 1; i++) { Message theMessage = null; System.out.println("Sending text message #" + i); theMessage = queueSession.createTextMessage(message + " #" + i); queueSender.send(theMessage); } } catch (Throwable t) { t.printStackTrace(); } finally { if (queueConnection != null) { try { System.out.println( "Closing the QueueSession and the QueueConnection now."); queueSession.close(); queueConnection.close(); } catch (Throwable t) { t.printStackTrace(); } } } } }</tt>
- Promote the sendMessage() method to the local interface.
You can use local interfaces, a new addition to EJB 2.0, instead
of remote interfaces, to reduce network traffic within a single
EJB container thereby increasing throughput and performance of
the EJB to EJB calls (see Figure 8).
Figure 8. Promoting the sendMessage() method to the local interface
- Similarly for the SimplePublisher, use appropriate Pub/Sub JMS implementation
for establishing topic sessions and connections.
<tt>Listing 2 package com.yourcomp.test; import javax.jms.*; Import javax.naming.*; Import javax.naming.directory.*; Import javax.rmi.PortableRemoteObject; public class SimplePublisherBean implements javax.ejb.SessionBean { TopicConnectionFactory topicConnectionFactory = null; Topic topic = null; TopicPublisher topicPublisher = null; TopicSession topicSession = null; TopicConnection topicConnection = null; String connectionFactoryName = "Java:comp/env/Simple/jms/SimpleTCF"; String topicName = "Java:comp/env/Simple/jms/SimpleT"; String outString = "Simple Topic Message"; private javax.ejb.SessionContext mySessionCtx; ... public void publishMessage() { try { System.out.println("Getting an Intial Context ..."); Context ctx = new InitialContext(); System.out.println("Getting an TopicConnectionFactory ..."); topicConnectionFactory = (TopicConnectionFactory) ctx.lookup(connectionFactoryName); topic = (Topic) ctx.lookup(topicName); System.out.println( "Got the TopicConnectionFactory: " + topicConnectionFactory); System.out.println("Getting a TopicConnection ..."); topicConnection = topicConnectionFactory.createTopicConnection(); System.out.println("Got the TopicConnection: " + topicConnection); System.out.println("Starting the TopicConnection ..."); topicConnection.start(); System.out.println("Getting a TopicSession ..."); Boolean transacted = false; topicSession = topicConnection.createTopicSession(transacted, Session.AUTO_ACKNOWLEDGE); System.out.println("Got the TopicSession: " + topicSession); System.out.println("Getting a TopicPublisher ..."); topicPublisher = topicSession.createPublisher(topic); System.out.println("Got the TopicPublisher: " + topicPublisher); System.out.println("Creating a TextMessage ..."); TextMessage outMessage = topicSession.createTextMessage(outString); System.out.println( "Publish the message to: " + topic.getTopicName()); topicPublisher.publish(outMessage); try { topicPublisher.close(); } catch (JMSException e) { System.out.println("Whoops! Threw a JMSException: " + e); } } catch (Throwable t) { t.printStackTrace(); } finally { if (topicConnection != null) { try { System.out.println( "Closing the TopicSession and the TopicConnection now."); topicSession.close(); topicConnection.close(); } catch (Throwable t) { t.printStackTrace(); } } } } } </tt>4. Promote the publishMessage() method to the local interface.
4. Implement the onMessage() method in the MDB
- Implement the onMessage() method of the SimpleMDB
with something like the following (admittedly not that real-worldly,
but it hopefully demonstrates the main points):
<samp>Listing 3</samp> <tt>package com.yourcomp; import javax.jms.*; Import javax.naming.*; Import javax.naming.directory.*; Import javax.rmi.PortableRemoteObject; public class SimpleMessageBean implements javax.ejb.MessageDrivenBean, javax.jms.MessageListener { </tt><tt> ... public void onMessage(javax.jms.Message msg) { try { System.out.println("Invoking MDB onMessage() now."); System.out.println("Message Object is: " + MSG); System.out.println("Text message is: " + ((TextMessage)MSG).getText()); System.out.println(); } catch (JMSException e) { System.out.println("Whoops! A JMSException occurred: " + e); e.printStackTrace(); } }</tt>
- Since an MDB does not require special deploy code, there is nothing further you need to do to create and use an MDB for useful work. All you really need to do at a minimum is to implement the onMessage() method in the bean.
5. Generate deploy and RMIC code for the session beans
Generate deploy and RMIC code and code for both the SimpleSender and the SimplePublisher beans. As mentioned, there is no need to generate deploy code because the Message-driven bean is ready to use by virtue of having an onMessage() method and the appropriate deployment descriptor. Clients don't access message-driven beans through interfaces and a message-driven bean has only a bean class (see Figure 9).
Figure 9. Generating deploy and RMIC code

6. Create and configure a unit test environment server instance and configuration
- Create a new WebSphere Application Server V5 Test Environment
server and configurationcalled MyTestServer in a
folder (that is, a server project) called, simple enough, Server
Project (see Figure 10).
Figure 10. Creating a new server and server configuration
- Add the DefaultEAR and the MDBTesterEAR to the
MyTestServer server configuration (see Figure 11).
Figure 11. Adding the DefaultEAR and the MDBTesterEAR to the server configuration
- Add a new WASQueueConnectionFactory and WASQueue.
It is always best to configure at the individual server level
providing application isolation, rather than the cell or node
level. Therefore, add the following JMS resources expanding the
server section on the JMS tab of the server configuration editor
for the MyTestServer server. Edit the WebSphere JMS Provider
Options page.
- Click Add and then add a new WASQueConnectionFactory
by entering these values and accepting the defaults (see Figure
12), otherwise:
Figure 12. Adding a new WASQueConnectionFactory with these specified values
- Add a new WASQueue with these valuesand accept
the defaults (see Figure 13), otherwise:
Figure 13. Screen capture for adding a new WASQueue with these specified values
- On this same JMS page, make sure to set the initial state for
the JMS server to START because it will be set to STOP
by default when you create the server configuration. Set the intial
state of the JMS server to START (see Figure 14).
Figure 14. Setting the Initial State for the JMS server to START
- Add a queue name called SimpleQ to the JMS Server (see
Figure 15).
Figure 15. Adding a Queue Name to the JMS Server
- Add a new WAS Topic Connection Factory and WAS Topic. For the
Pub/Sub test, you need to add a TopicConnectionFactory and a Topic.
Locate the WASTopicConnectionFactory section, click Add, then enter these valuesand accept the defaults (see Figure 16), otherwise:
Figure 16. Adding a new WASTopic Connection Factory
- Add a new WASTopic with these values and accept the defaults
(see Figure 17), otherwise:
Figure 17. Adding a new WASTopic
- Once completed, your queue and topic connections and destinations
appear in the list (see Figure 18).
Figure 18. Queue, topic connections, and destinations as listed
- Add a new listener port. On the EJB tab of the Server Configuration
Editor, in the Listener Ports section, add a new listener port
whose name matches the name specified for the listener port in
the MDB earlier. This ability to configure a Listener Port here
did not exist for the the Early Availability release of Application
Developer, so you need the GM version to use this feature.
Since we used a name of SimpleListenerPort, you need to specify that name here as well. Click the Add button, specify the following values, and accept the defaults; otherwise, click OK and save your server configuration (see Figure 19).
Figure 19. Adding a new Listener Port
- Add the DefaultEAR and the MDBTester EAR modules
to the server configuration (see Figure 20).
Figure 20. Adding the DefaultEAR and MDBTester EAR modules to the server configuration
- Make sure both the application modules (DefaultEAR and
MDBTesterEAR) are added to the same server configuration (see Figure 21).
Figure 21. Adding both application modules to the same server configuration
7. Add EJB resource references for the MDB
Resource references are needed so that different modules may
access common resources. In this case, the resources are connection
factories, topics and queues that are bound to specific JNDI names
that WebSphere Application Server uses at run time. Open the EJB
Deployment Descriptor Editor for the SimpleMessage bean. Click on
the ejb-jar.xml file to open it.
- Add a resource environment reference you will name ResourceEnvRef
for the Queue type and JNDI name of jms/simpleQ (see Figure
22).
Figure 22. Adding a resource environment reference
- When the reference is added, the entries should look like the following (see Figure 23):
Figure 23. Example of how entries look once resource environment reference is added
- Now add an EJB resource reference to an external resource to the Queue
Connection Factory.
Figure 24. Adding an EJB resource reference to an external resource
When the reference is added, the entries should look now like Figure 25 below:
Figure 25. Example of entries with reference added
8. Add resource references for the two session beans
Now, you need to add the same type of resource references to the MDBTester beans, the SimpleSender and the SimplePublisher.
- Add the EJB resource references for both the SimplePublisher
and the SimpleSender
Figure 26. Adding EJB resource references for both the SimplePublisher and SimpleSender
- The following four figures graphically demonstrate the four
sets of values. You should ensure that they are set properly,
first two for the SimpleSender and then the last two for
the SimplePublisher. The important points are to be consistent
in the JNDI names you use to ensure all the references refer to
the same resource by the same JNDI name and that the correct type
of resource is specified -- each of the four main JMS resource
types including: Queue, QueueConnectionFactory, Topic and TopicConnectionFactory.
Figure 27. Set this set of values for the SimpleSender
Figure 28. Set this set of values for the SimpleSender
Figure 29. Set this set of values for the SimplePublisher
Figure 30. Set this set of values for the SimplePublisher
Now that you have created the EJBs and configured the server environment, it is time to test the MDB that it executes. You might be interested in starting the server in debug mode and stepping through the publishMessage or sendMessage() methods as well.
- Start the WebSphere Application Server V5 server instance by
clicking on the running person in the Servers view in the Servers
perspective.
Alternatively, you may do a run on server on an EJB or on the project. This article describes how to to launch the server manually. - Start the IBM ® Universal Test Client by right clicking on the server in the Server view. Select run universal test client, then open the JNDI Explorer from the Test Client's home page.
- Drill down in the the Local EJB beans until you reach the JNDI
name of
ejb/com/yourcomp/testand click on the SimpleSenderLocalHome that takes you to the EJB page. Once there, use the Home interface to create or retrieve an instance of the SimpleSender. - Go back to the JNDI Explorer and perform the same steps for
the SimplePublisher. You can then work first with the "sender"
then subsequently with the "publisher" because you will have instances
of both (if that is what you want to do). See Figure 31.
Figure 31. Creating instances of SimpleSender and SimplePublisher
- Once you have a home, create an instance of SimpleSenderLocal
by running the SimpleSenderLocal.create() method. The server console
window should be open but if it is not make sure to open it because
all your printlns will go there. If the steps have been followed
properly, you will notice console output that came from the println
statements in the session bean and the MDB (see Figure 32).
Figure 32. Creating an instance of SimpleSenderLocal
The expected console output (your time and date stamps will of course be different) for P2P should be something like the following:
<tt>... [11/17/02 9:58:05:609 EDT] 30d1bea0 SystemOut O Getting an Intial Context ... [11/17/02 9:58:05:609 EDT] 30d1bea0 SystemOut O Getting an QueueConnectionFactory ... [11/17/02 9:58:05:641 EDT] 30d1bea0 SystemOut O Got the QueueConnectionFactory: com.ibm.ejs.jms.JMSQueueConnectionFactoryHandle@4afbbea3 managed connection factory = com.ibm.ejs.jms.WSJMSManagedQueueConnectionFactory@185ebebd connection manager = com.ibm.ejs.j2c.ConnectionManager@5557ebc restricted methods enabled = false [11/17/02 9:58:05:641 EDT] 30d1bea0 SystemOut O Getting a QueueConnection ... [11/17/02 9:58:05:656 EDT] 30d1bea0 SystemOut O Got the QueueConnection: com.ibm.ejs.jms.JMSQueueConnectionHandle@4e897ea3 managed connection = com.ibm.ejs.jms.JMSManagedQueueConnection@4b2cfea3 physical connection = com.ibm.mq.jms.MQXAQueueConnection@4b11fea3 closed = false invalid = false restricted methods enabled = false open session handles = [] temporary queues = [] [11/17/02 9:58:05:656 EDT] 30d1bea0 SystemOut O Getting a QueueSession ... [11/17/02 9:58:05:703 EDT] 30d1bea0 SystemOut O Got the QueueSession: com.ibm.ejs.jms.JMSQueueSessionHandle@51be7ea2 managed session = com.ibm.ejs.jms.JMSManagedQueueSession@bdbbea3 state = ACTIVE restricted methods enabled = false open children = [] [11/17/02 9:58:05:703 EDT] 30d1bea0 SystemOut O Getting a Queue ... [11/17/02 9:58:05:703 EDT] 30d1bea0 SystemOut O Got the Queue: queue:///WQ_SimpleQ [11/17/02 9:58:05:703 EDT] 30d1bea0 SystemOut O Getting a QueueSender ... [11/17/02 9:58:05:734 EDT] 30d1bea0 SystemOut O Got the QueueSender: com.ibm.ejs.jms.JMSQueueSenderHandle@2e3ea2 session handle = com.ibm.ejs.jms.JMSQueueSessionHandle@51be7ea2 message ID disabled = null message timestamp disabled = null delivery mode = null priority = null time to live = null closed = false queue = queue:///WQ_SimpleQ physical queue sender = com.ibm.mq.jms.MQQueueSender@7eb3bea2 [11/17/02 9:58:05:734 EDT] 30d1bea0 SystemOut O *** Sending the messages now *** [11/17/02 9:58:05:734 EDT] 30d1bea0 SystemOut O Sending text message #1 [11/17/02 9:58:05:766 EDT] 30d1bea0 SystemOut O Sending text message #2 [11/17/02 9:58:05:766 EDT] 30d1bea0 SystemOut O Sending text message #3 [11/17/02 9:58:05:766 EDT] 30d1bea0 SystemOut O Sending text message #4 [11/17/02 9:58:05:766 EDT] 30d1bea0 SystemOut O Sending text message #5 [11/17/02 9:58:05:766 EDT] 30d1bea0 SystemOut O Closing the QueueSession and the QueueConnection now. [11/17/02 9:58:05:828 EDT] 2207ea2 SystemOut O Invoking MDB onMessage() now. [11/17/02 9:58:05:828 EDT] 2207ea2 SystemOut O Message Object is: JMS Message class: jms_text JMSType: null JMSDeliveryMode: 2 JMSExpiration: 0 JMSPriority: 4 JMSMessageID: ID:414d51205741535f6c6f63616c686f730000000000000005 JMSTimestamp: 1033999085766 JMSCorrelationID:null JMSDestination: queue:///WQ_SimpleQ JMSReplyTo: null JMSRedelivered: false JMS_IBM_PutDate:20021007 JMSXAppID:Application Developer JMS_IBM_Format:MQSTR JMS_IBM_PutApplType:28 JMS_IBM_MsgType:8 JMSXUserID:swosnick JMS_IBM_PutTime:13580576 JMSXDeliveryCount:1 My Very Simple Message #1 [11/17/02 9:58:05:828 EDT] 2207ea2 SystemOut O Text message is: My Very Simple Message #1 ... </tt>
- Do the same for the SenderPublish. Create a new instance and
invoke the publishMessage() method (see Figure 33). Before you
do this, go change the listener port so that the MDB listens for
the Topic instead of the Queue set up in Section 6, Step 11. Otherwise,
the MDB will still be listening on the Queue and will not produce
the output you would expect.
Figure 33. Creating a new instance for SenderPublish
Expected console output (your time and date stamps will of course be different) for Pub/Sub:
<tt>[11/17/02 9:42:47:672 EDT] 76bd3cfe SystemOut O Getting an Intial Context ... [11/17/02 9:42:47:688 EDT] 76bd3cfe SystemOut O Getting an TopicConnectionFactory ... [11/17/02 9:42:47:719 EDT] 76bd3cfe SystemOut O Got the TopicConnectionFactory: com.ibm.ejs.jms.JMSTopicConnectionFactoryHandle@55e4fce1 managed connection factory = com.ibm.ejs.jms.WSJMSManagedTopicConnectionFactory@3156bce6 connection manager = com.ibm.ejs.j2c.ConnectionManager@33937ce6 restricted methods enabled = false [11/17/02 9:42:47:719 EDT] 76bd3cfe SystemOut O Getting a TopicConnection ... [11/17/02 9:42:47:766 EDT] 76bd3cfe SystemOut O Got the TopicConnection: com.ibm.ejs.jms.JMSTopicConnectionHandle@35977ce0 managed connection = com.ibm.ejs.jms.JMSManagedTopicConnection@4a8bfce0 physical connection = com.ibm.mq.jms.MQXATopicConnection@4af9bce0 closed = false invalid = false restricted methods enabled = false open session handles = [] temporary topics = [] [11/17/02 9:42:47:766 EDT] 76bd3cfe SystemOut O Starting the TopicConnection ... [11/17/02 9:42:47:766 EDT] 76bd3cfe SystemOut O Getting a TopicSession ... [11/17/02 9:42:47:828 EDT] 76bd3cfe SystemOut O Got the TopicSession: com.ibm.ejs.jms.JMSTopicSessionHandle@118bce0 managed session = com.ibm.ejs.jms.JMSManagedTopicSession@400bbce0 state = ACTIVE restricted methods enabled = false open children = [] [11/17/02 9:42:47:828 EDT] 76bd3cfe SystemOut O Getting a TopicPublisher ... [11/17/02 9:42:47:859 EDT] 76bd3cfe SystemOut O Got the TopicPublisher: com.ibm.ejs.jms.JMSTopicPublisherHandle@74867ce7 session handle = com.ibm.ejs.jms.JMSTopicSessionHandle@118bce0 message ID disabled = null message timestamp disabled = null delivery mode = null priority = null time to live = null closed = false topic = topic://SimpleTopic?brokerVersion=1 physical topic publisher = com.ibm.mq.jms.MQTopicPublisher@5157fce7 [11/17/02 9:42:47:859 EDT] 76bd3cfe SystemOut O Creating a TextMessage ... [11/17/02 9:42:47:859 EDT] 76bd3cfe SystemOut O Publish the message to: topic://SimpleTopic?brokerVersion=1 [11/17/02 9:42:47:891 EDT] 76bd3cfe SystemOut O Closing the TopicSession and the TopicConnection now. [11/17/02 9:42:47:969 EDT] 6e2e7ce7 SystemOut O Invoking MDB onMessage() now. [11/17/02 9:42:47:984 EDT] 6e2e7ce7 SystemOut O Message Object is: JMS Message class: jms_text JMSType: null JMSDeliveryMode: 2 JMSExpiration: 0 JMSPriority: 4 JMSMessageID: ID:414d51205741535f6c6f63616c686f73000000000000000d JMSTimestamp: 1033998167891 JMSCorrelationID:ID:414d51205741535f6c6f63616c686f730000000000000008 JMSDestination: topic://SimpleTopic?brokerVersion=1 JMSReplyTo: null JMSRedelivered: false JMS_IBM_PutDate: JMSXAppID:WAS_localhost_server1 JMS_IBM_Format:MQSTR JMS_IBM_PutApplType:26 JMS_IBM_MsgType:8 JMSXUserID:swosnick JMS_IBM_PutTime: JMSXDeliveryCount:1 Simple Topic Message [11/17/02 9:42:47:984 EDT] 6e2e7ce7 SystemOut O Text message is: Simple Topic Message </tt>
- To debug your MDB, which is presumably what you want to most test in this scenario, set breakpoints in the onMessage() method and make sure to start the server in debug mode.
10. Import EAR files and server configuration (optional)
Some people might prefer (optionally) to run the application right away to see how it works rather than coding it all from scratch. That's fine, and that is why the download provided contains all you need to to do just that. Follow the instructions below to import the EAR files and server configuration, then create a server for that configuration. All the JMS resources and JNDI names have been preset for you and you should be able to run the application with a few simple steps. Remember, this article does not teach you how to design and create Message-driven beans but rather introduce you to the MQ testing tools available in Application Developer.
- Select File=>Import=>EAR file; then click Next.
- Browse to the path to
DefaultEAR.earand set as the EAR module to import. - Enter DefaultEAR as the project name. Accept the default project
location (see Figure 34).
Figure 34. Importing EAR files
- Click Finish.
- Repeat steps 1-4 for the MDBTesterEAR using an enterprise
application project called MDBTesterEAR.
Figure 35. Importing EAR files for MDBTesterEAR
- You need not regenerate deploy code for the SimpleSender and SimplePublisher EJBs in the MDBTesterProject because the download contains it.
- Select File=>Import=>Server Configuration; then click Next.
- Enter a configuration name of
MyTestServer. - Set the folder to
My Server Project, which will be dynamically created for you. - Choose a server configuration type of
WebSphere version 5.0 Server Configuration. - Browse to the location where you unzipped the downloaded files, to the
MyTestServer.wscdirectory. - Click Finish and answer "Yes" to the dialog asking to
create the My Server Project. See Figure 36.
Figure 36. Importing a server configuration
- Select File=>New=>Other=>Server to create a new server instance. Click Next.
- Set the server name to
MyTestServer, using theMy Server Projectfolder. Choose a server type ofWebSphere version 5.0 Test Environment. Click Finish. - Open the Sever Perspective by selecting Window=>Open Perspective=>Other=>Server.
- In the Server Configuration View, select MyTestServer;
then right click and Switch Configuration from no configuration
to MyTestServer. See Figure 37.
Figure 37. Creating a new server
- Run server and test as above. If you want to debug your code, run the server in debug mode after setting breakpoints within interesting parts of the code.
New to Application Developer Version 5.0 is a very productive and lightweight environment that enables quick testing and debugging of MDBs and other JMS applications in a unit test environment. This tutorial has walked you through one way to use the MQ Simulator, within the in-process restriction, by creating EJBs that run in the same process as the application server running the MDB. Although the MQ Simulator is not designed or supported for production systems, it is invaluable in the unit test environment where no tool-specific or vendor-specific code is required. For those who feel limited by the requirements for in-process clients, it is always possible to configure Application Developer to work with other messaging systems through the admin client if need be. Once the JMS-based application has been tested with MQ Simulator, it can be deployed without change to the production application server that will be set up to use the full WebSphere MQ system or some other messaging system.
| Name | Size | Download method |
|---|---|---|
| SimpleMDB.zip | 0.6 MB | FTP |
Information about download methods

Sheldon Wosnick is a software developer on the IBM WebSphere Studio Application Developer, Server Tools team at the IBM Toronto Lab. With his teammates, he is currently responsible for the entire server run time and unit test environment for Application Developer. Previously, he was a member of the VisualAge® for Java WebSphere Tools team. Sometimes fondly known as the "run time guy," he designed and integrated the WebSphere Test Environment and the Apache Tomcat Test Environment for VisualAge for Java, two very popular features in VisualAge for Java. You can reach Sheldon at swosnick@ca.ibm.com.




