# The Java EE 7 Tutorial

# 46.4 Writing High Performance and Scalable JMS Applications

This section describes how to use the JMS API to write applications that can handle high volumes of messages robustly. These examples use both nondurable and durable shared consumers.

## 46.4.1 Using Shared Nondurable Subscriptions

This section describes the receiving clients in an example that shows how to use a shared consumer to distribute messages sent to a topic among different consumers. This section then explains how to compile and run the clients using GlassFish Server.

You may wish to compare this example to the results of Running Multiple Consumers on the Same Destination using an unshared consumer. In that example, messages are distributed among the consumers on a queue, but each consumer on the topic receives all the messages because each consumer on the topic is using a separate topic subscription.

In this example, however, messages are distributed among multiple consumers on a topic, because all the consumers are sharing the same subscription. Each message added to the topic subscription is received by only one consumer, similarly to the way in which each message added to a queue is received by only one consumer.

A topic may have multiple subscriptions. Each message sent to the topic will be added to each topic subscription. However, if there are multiple consumers on a particular subscription, each message added to that subscription will be delivered to only one of those consumers.

### 46.4.1.1 Writing the Clients for the Shared Consumer Example

The sending client is `Producer.java`, the same client used in previous examples.

The receiving client is `SharedConsumer.java`. It is very similar to `AsynchConsumer.java`, except that it always uses a topic. It performs the following steps.

1. Injects resources for a connection factory and topic.

2. In a `try`-with-resources block, creates a `JMSContext`.

3. Creates a consumer on a shared nondurable subscription, specifying a subscription name:

       consumer = context.createSharedConsumer(topic, "SubName");

4. Creates an instance of the `TextListener` class and registers it as the message listener for the shared consumer.

5. Listens for the messages published to the destination, stopping when the user types the character `q` or `Q`.

6. Catches and handles any exceptions. The end of the `try`-with-resources block automatically causes the `JMSContext` to be closed.

The `TextListener.java` class is identical to the one for the `asynchconsumer` example.

For this example, you will use the default connection factory and the topic you created in To Create Resources for the Simple Examples.

### 46.4.1.2 To Run the SharedConsumer and Producer Clients

1. Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).

2. Open three command windows. In the first, go to the `simple/producer/` directory:

       cd tut-install/examples/jms/simple/producer/

3. In the second and third command windows, go to the `shared/sharedconsumer/` directory:

       cd tut-install/examples/jms/shared/sharedconsumer/

4. In one of the `sharedconsumer` windows, build the example:

       mvn install

5. In each of the two `sharedconsumer` windows, start running the client. You do not need to specify a `topic` argument:

       appclient -client target/sharedconsumer.jar

   Wait until you see the following output in both windows:

       Waiting for messages on topic
       To end program, enter Q or q, then <return>

6. In the `producer` window, run the client, specifying the topic and a number of messages:

       appclient -client target/producer.jar topic 20

   Each consumer client receives some of the messages. Only one of the clients receives the non-text message that signals the end of the message stream.

7. Enter `Q` or `q` and press Return to stop each client and see a report of the number of text messages received.

## 46.4.2 Using Shared Durable Subscriptions

The `shareddurableconsumer` client shows how to use shared durable subscriptions. It shows how shared durable subscriptions combine the advantages of durable subscriptions (the subscription remains active when the client is not) with those of shared consumers (the message load can be divided among multiple clients).

The example is much more similar to the `sharedconsumer` example than to the `DurableConsumer.java` client. It uses two classes, `SharedDurableConsumer.java` and `TextListener.java`, which can be found under the tut-install`/examples/jms/shared/shareddurableconsumer/` directory.

The client uses `java:comp/DefaultJMSConnectionFactory`, the connection factory that does not have a client identifier, as is recommended for shared durable subscriptions. It uses the `createSharedDurableConsumer` method with a subscription name to establish the subscription:

    consumer = context.createSharedDurableConsumer(topic, "MakeItLast");

You run the example in combination with the `Producer.java` client.

### 46.4.2.1 To Run the SharedDurableConsumer and Producer Clients

1. In a terminal window, go to the following directory:

       tut-install/examples/jms/shared/shareddurableconsumer

2. To compile and package the client, enter the following command:

       mvn install

3. Run the client first to establish the durable subscription:

       appclient -client target/shareddurableconsumer.jar

4. The client displays the following and pauses:

       Waiting for messages on topic
       To end program, enter Q or q, then <return>

5. In the `shareddurableconsumer` window, enter `q` or `Q` to exit the program. The subscription remains active, although the client is not running.

6. Open another terminal window and go to the `producer` example directory:

       cd tut-install/examples/jms/simple/producer

7. Run the `producer` example, sending a number of messages to the topic:

       appclient -client target/producer.jar topic 6

8. After the producer has sent the messages, open a third terminal window and go to the `shareddurableconsumer` directory.

9. Run the client in both the first and third terminal windows. Whichever client starts first will receive all the messages that were sent when there was no active subscriber:

       appclient -client target/shareddurableconsumer.jar

10. With both `shareddurableconsumer` clients still running, go to the `producer` window and send a larger number of messages to the topic:

        appclient -client target/producer.jar topic 25

    Now the messages will be shared by the two consumer clients. If you continue sending groups of messages to the topic, each client receives some of the messages. If you exit one of the clients and send more messages, the other client will receive all the messages.