The Java EE 5 Tutorial

Creating Durable Subscriptions

To ensure that a pub/sub application receives all published messages, use PERSISTENT delivery mode for the publishers. In addition, use durable subscriptions for the subscribers.

The Session.createConsumer method creates a nondurable subscriber if a topic is specified as the destination. A nondurable subscriber can receive only messages that are published while it is active.

At the cost of higher overhead, you can use the Session.createDurableSubscriber method to create a durable subscriber. A durable subscription can have only one active subscriber at a time.

A durable subscriber registers a durable subscription by specifying a unique identity that is retained by the JMS provider. Subsequent subscriber objects that have the same identity resume the subscription in the state in which it was left by the preceding subscriber. If a durable subscription has no active subscriber, the JMS provider retains the subscription’s messages until they are received by the subscription or until they expire.

You establish the unique identity of a durable subscriber by setting the following:

You set the client ID administratively for a client-specific connection factory using the Admin Console.

After using this connection factory to create the connection and the session, you call the createDurableSubscriber method with two arguments: the topic and a string that specifies the name of the subscription:

String subName = "MySub";
MessageConsumer topicSubscriber =
     session.createDurableSubscriber(myTopic, subName);

The subscriber becomes active after you start the Connection or TopicConnection. Later, you might close the subscriber:

topicSubscriber.close();

The JMS provider stores the messages sent or published to the topic, as it would store messages sent to a queue. If the program or another application calls createDurableSubscriber using the same connection factory and its client ID, the same topic, and the same subscription name, the subscription is reactivated, and the JMS provider delivers the messages that were published while the subscriber was inactive.

To delete a durable subscription, first close the subscriber, and then use the unsubscribe method, with the subscription name as the argument:

topicSubscriber.close();
session.unsubscribe("MySub");

The unsubscribe method deletes the state that the provider maintains for the subscriber.

Figure 31–7 and Figure 31–8 show the difference between a nondurable and a durable subscriber. With an ordinary, nondurable subscriber, the subscriber and the subscription begin and end at the same point and are, in effect, identical. When a subscriber is closed, the subscription also ends. Here, create stands for a call to Session.createConsumer with a Topic argument, and close stands for a call to MessageConsumer.close. Any messages published to the topic between the time of the first close and the time of the second create are not consumed by the subscriber. In Figure 31–7, the subscriber consumes messages M1, M2, M5, and M6, but messages M3 and M4 are lost.

Figure 31–7 Nondurable Subscribers and Subscriptions

Diagram showing messages being lost when nondurable subscriptions
are used

With a durable subscriber, the subscriber can be closed and re-created, but the subscription continues to exist and to hold messages until the application calls the unsubscribe method. In Figure 31–8, create stands for a call to Session.createDurableSubscriber, close stands for a call to MessageConsumer.close, and unsubscribe stands for a call to Session.unsubscribe. Messages published while the subscriber is closed are received when the subscriber is created again. So even though messages M2, M4, and M5 arrive while the subscriber is closed, they are not lost.

Figure 31–8 A Durable Subscriber and Subscription

Diagram showing messages being preserved when durable
subscriptions are used

See A Java EE Application That Uses the JMS API with a Session Bean for an example of a Java EE application that uses durable subscriptions. See A Message Acknowledgment Example and the next section for examples of client applications that use durable subscriptions.

A Durable Subscription Example

The DurableSubscriberExample.java program shows how durable subscriptions work. It demonstrates that a durable subscription is active even when the subscriber is not active. The program contains a DurableSubscriber class, a MultiplePublisher class, a main method, and a method that instantiates the classes and calls their methods in sequence.

The program is in the following directory:

tut-install/javaeetutorial5/examples/jms/advanced/durablesubscriberexample/src/java/

The program begins in the same way as any publish/subscribe program: The subscriber starts, the publisher publishes some messages, and the subscriber receives them. At this point, the subscriber closes itself. The publisher then publishes some messages while the subscriber is not active. The subscriber then restarts and receives the messages.

    Before you run this program, compile and package the source file and create a connection factory that has a client ID. Perform the following steps:

  1. To compile and package the program using NetBeans IDE, follow these steps:

    1. In NetBeans IDE, choose Open Project from the File menu.

    2. In the Open Project dialog, navigate to tut-install/javaeetutorial5/examples/jms/advanced/.

    3. Select the durablesubscriberexample folder.

    4. Select the Open as Main Project check box.

    5. Click Open Project.

    6. Right-click the project and choose Build.

    To compile and package the program using Ant, follow these steps:

    1. Go to the following directory:

      tut-install/javaeetutorial5/examples/jms/advanced/durablesubscriberexample/
      
    2. Type the following command:


      ant
      
  2. If you did not do so for A Message Acknowledgment Example, create a connection factory named jms/DurableConnectionFactory:


    ant create-durable-cf
    

To run the program using NetBeans IDE, right-click the durablesubscriberexample project and choose Run.

    To run the program from the command line, follow these steps:

  1. Go to the dist directory:


    cd dist
    
  2. Type the following command:


    appclient -client durablesubscriberexample.jar
    

The output looks something like this:


Connection factory without client ID is jms/ConnectionFactory
Connection factory with client ID is jms/DurableConnectionFactory
Topic name is jms/Topic
Starting subscriber
PUBLISHER: Publishing message: Here is a message 1
SUBSCRIBER: Reading message: Here is a message 1
PUBLISHER: Publishing message: Here is a message 2
SUBSCRIBER: Reading message: Here is a message 2
PUBLISHER: Publishing message: Here is a message 3
SUBSCRIBER: Reading message: Here is a message 3
Closing subscriber
PUBLISHER: Publishing message: Here is a message 4
PUBLISHER: Publishing message: Here is a message 5
PUBLISHER: Publishing message: Here is a message 6
Starting subscriber
SUBSCRIBER: Reading message: Here is a message 4
SUBSCRIBER: Reading message: Here is a message 5
SUBSCRIBER: Reading message: Here is a message 6
Closing subscriber
Unsubscribing from durable subscription

After you run the program, you can delete the connection factory jms/DurableConnectionFactory. Go to the directory tut-install/javaeetutorial5/examples/jms/advanced/durablesubscriberexample/ and type the following command:


ant delete-durable-cf

To delete the class and JAR files for the program using NetBeans IDE, right-click the project and choose Clean.

To delete the class and JAR files for the program using Ant, type the following:


ant clean