The Java EE 5 Tutorial

Writing the Client Programs for the Synchronous Receive Example

    The sending program, producer/src/java/Producer.java, performs the following steps:

  1. Injects resources for a connection factory, queue, and topic:

    @Resource(mappedName="jms/ConnectionFactory")
    private static ConnectionFactory connectionFactory;
    @Resource(mappedName="jms/Queue")private static Queue queue;
    @Resource(mappedName="jms/Topic")private static Topic topic;
  2. Retrieves and verifies command-line arguments that specify the destination type and the number of arguments:

    final int NUM_MSGS;
    String destType = args[0];
    System.out.println("Destination type is " + destType);
    if ( ! ( destType.equals("queue") || destType.equals("topic") ) ) { 
        System.err.println("Argument must be \”queue\” or " + "\”topic\”");
        System.exit(1);
    }
    if (args.length == 2){ 
        NUM_MSGS = (new Integer(args[1])).intValue();
    } 
    else { 
        NUM_MSGS = 1;
    }
  3. Assigns either the queue or topic to a destination object, based on the specified destination type:

    Destination dest = null;
    try { 
        if (destType.equals("queue")) { 
            dest = (Destination) queue; 
        } else { 
            dest = (Destination) topic; 
        }
    } 
    catch (Exception e) {
        System.err.println("Error setting destination: " + e.toString()); 
        e.printStackTrace(); 
        System.exit(1);
    }
  4. Creates a Connection and a Session:

    Connection connection = connectionFactory.createConnection(); 
    Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
  5. Creates a MessageProducer and a TextMessage:

    MessageProducer producer = session.createProducer(dest);
    TextMessage message = session.createTextMessage();
  6. Sends one or more messages to the destination:

    for (int i = 0; i < NUM_MSGS; i++) { 
        message.setText("This is message " + (i + 1)); 
        System.out.println("Sending message: " + message.getText()); 
        producer.send(message);
    }
  7. Sends an empty control message to indicate the end of the message stream:

    producer.send(session.createMessage());

    Sending an empty message of no specified type is a convenient way to indicate to the consumer that the final message has arrived.

  8. Closes the connection in a finally block, automatically closing the session and MessageProducer:

    } finally { 
        if (connection != null) { 
            try { connection.close(); } 
            catch (JMSException e) { } 
        }
    }

    The receiving program, synchconsumer/src/java/SynchConsumer.java, performs the following steps:

  1. Injects resources for a connection factory, queue, and topic.

  2. Assigns either the queue or topic to a destination object, based on the specified destination type.

  3. Creates a Connection and a Session.

  4. Creates a MessageConsumer:

    consumer = session.createConsumer(dest);
  5. Starts the connection, causing message delivery to begin:

    connection.start();
  6. Receives the messages sent to the destination until the end-of-message-stream control message is received:

    while (true) {
        Message m = consumer.receive(1); 
        if (m != null) { 
            if (m instanceof TextMessage) { 
                message = (TextMessage) m; 
                System.out.println("Reading message: " + message.getText()); 
            } else { 
                break; 
            } 
        }
    }

    Because the control message is not a TextMessage, the receiving program terminates the while loop and stops receiving messages after the control message arrives.

  7. Closes the connection in a finally block, automatically closing the session and MessageConsumer.

The receive method can be used in several ways to perform a synchronous receive. If you specify no arguments or an argument of 0, the method blocks indefinitely until a message arrives:

Message m = consumer.receive();
Message m = consumer.receive(0);

For a simple client program, this may not matter. But if you do not want your program to consume system resources unnecessarily, use a timed synchronous receive. Do one of the following:

The SynchConsumer program uses an indefinite while loop to receive messages, calling receive with a timeout argument. Calling receiveNoWait would have the same effect.