Skip to main content

IBM WebSphere Developer Technical Journal: Developing and Testing Message-driven Bean Applications with the MQ Simulator for Java Developers in WebSphere Studio V5.0

Preparing the environment

Sheldon Wosnick (swosnick@ca.ibm.com), Software Developer, IBM WebSphere Studio Application Developer, IBM Toronto Lab
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.

Summary:  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.

Date:  15 Jan 2003
Level:  Intermediate
Activity:  1115 views

Introduction

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.

Background

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:

  1. Create and configure the EJB project for the MDB
  2. Create the MDB tester project and two session beans to invoke sending and publishing
  3. Create and implement methods in the session beans to send and publish messages
  4. Implement the onMessage() method in the MDB
  5. Generate Deploy RMIC code for the session bean testers
  6. Create and configure a unit test environment server instance and configuration
  7. Add EJB resource references for the MDB
  8. Add resource references for the two session beans
  9. Run and test the EJB beans
  10. 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
Screen capture of the completed J2EE environment

1. Create and configure the EJB project for the MDB

  1. Create a new EJB 2.0 project called SimpleMDB in an enterprise application project called DefaultEAR.
  2. 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
    ADD ALT TEXT.
  3. Specify the transaction type as Container and the destination type as Queue.
  4. Specify a listener port called SimpleListenerPort.
  5. Click Finish (see Figure 3).
    Figure 3. Specifying the transaction type, destination type, and listener port
    Specifying the transaction type, destination type, and listener port.
  6. 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
    Screen capture of EJB Deployment Descriptor for the SimpleMessage bean.

2. Create the MDB tester project and two session beans to invoke sending and publishing

  1. 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
    Screen capture 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.
  2. 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
    Screen capture creating the SimpleSender stateless                    session bean in the MDBTester project.
  3. 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.
  4. Accept the defaults and click Add in the CMP attributes section (see Figure 7).
    Figure 7. Selecting Session type, Transaction type, and other details
    Screen capture selecting Session type, Transaction type, and other details.

3. Create and implement methods in the session beans to send and publish messages

  1. 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/env rather 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> 
     
    

  2. 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
    Screen capture promoting the sendMessage() method to the local interface.
  3. 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

  1. 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> 
    

  2. 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
Screen capture for generating Deploy and RMIC code.

6. Create and configure a unit test environment server instance and configuration

  1. 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
    Screen capture for creating a new server and server configuration.
  2. 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
    Screen capture for adding the DefaultEAR and the MDBTesterEAR to the server configuration.
  3. 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.

  4. 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
    Screen capture for adding a new WASQueConnectionFactory with these specified values.
  5. 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
    Screen capture for adding a new WASQueue with these speicified values.
  6. 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
    Screen capture for setting the Initial State for the JMS server to START.
  7. Add a queue name called SimpleQ to the JMS Server (see Figure 15).
    Figure 15. Adding a Queue Name to the JMS Server
    Screen capture for adding a Queue Name to the JMS Server.
  8. 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
    Screen capture for adding a new WASTopic Connection Factory.
  9. Add a new WASTopic with these values and accept the defaults (see Figure 17), otherwise:
    Figure 17. Adding a new WASTopic
    Screen capture for adding a new WASTopic.
  10. 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
    Queue, topic connections, and destinations as listed.
  11. 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
    Screen capture for adding a new Listener Port.
  12. 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
    Screen capture for adding the DefaultEAR and MDBTester EAR modules to the server configuration.
  13. 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
    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.

  1. 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
    Screen capture for adding a resource environment reference.
  2. 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
    Screen capture of how entries look once resource environment reference is added.
  3. 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
    Screen capture of 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
    Screen capture 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.

  1. Add the EJB resource references for both the SimplePublisher and the SimpleSender

    Figure 26. Adding EJB resource references for both the SimplePublisher and SimpleSender
    Screen capture for adding EJB resource references for both the SimplePublisher and SimpleSender.
  2. 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
    Set this set of values for the SimpleSender.

    Figure 28. Set this set of values for the SimpleSender
    Set this set of values for the SimpleSender.

    Figure 29. Set this set of values for the SimplePublisher
    Set this set of values for the SimplePublisher.

    Figure 30. Set this set of values for the SimplePublisher
    Set this set of values for the SimplePublisher.

9. Run and test the EJB beans

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.

  1. 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.
  2. 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.
  3. Drill down in the the Local EJB beans until you reach the JNDI name of ejb/com/yourcomp/test and 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.
  4. 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
    Screen shot for creating instances of SimpleSender and SimplePublisher.
  5. 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
    Screen capture for 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> 
    

  6. 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
    Screen capture for 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> 
    

  7. 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.

  1. Select File=>Import=>EAR file; then click Next.
  2. Browse to the path to DefaultEAR.ear and set as the EAR module to import.
  3. Enter DefaultEAR as the project name. Accept the default project location (see Figure 34).
    Figure 34. Importing EAR files
    Screen capture for importing EAR files.
  4. Click Finish.
  5. Repeat steps 1-4 for the MDBTesterEAR using an enterprise application project called MDBTesterEAR.
    Figure 35. Importing EAR files for MDBTesterEAR
    Screen capture for importing EAR files for MDBTesterEAR.
  6. You need not regenerate deploy code for the SimpleSender and SimplePublisher EJBs in the MDBTesterProject because the download contains it.
  7. Select File=>Import=>Server Configuration; then click Next.
  8. Enter a configuration name of MyTestServer.
  9. Set the folder to My Server Project, which will be dynamically created for you.
  10. Choose a server configuration type of WebSphere version 5.0 Server Configuration.
  11. Browse to the location where you unzipped the downloaded files, to the MyTestServer.wsc directory.
  12. Click Finish and answer "Yes" to the dialog asking to create the My Server Project. See Figure 36.
    Figure 36. Importing a server configuration
    Importing a Server Configuration.
  13. Select File=>New=>Other=>Server to create a new server instance. Click Next.
  14. Set the server name to MyTestServer, using the My Server Project folder. Choose a server type of WebSphere version 5.0 Test Environment. Click Finish.
  15. Open the Sever Perspective by selecting Window=>Open Perspective=>Other=>Server.
  16. 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
    Creating a new server.
  17. 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.

Conclusion

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.



Download

NameSizeDownload method
SimpleMDB.zip0.6 MBFTP|HTTP

Information about download methods


About the author

Sheldon Wosnick

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.

Comments (Undergoing maintenance)



Trademarks  |  My developerWorks terms and conditions

Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=WebSphere
ArticleID=99600
ArticleTitle=IBM WebSphere Developer Technical Journal: Developing and Testing Message-driven Bean Applications with the MQ Simulator for Java Developers in WebSphere Studio V5.0
publish-date=01152003
author1-email=swosnick@ca.ibm.com
author1-email-cc=

My developerWorks community

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Rate a product. Write a review.

Special offers