# JMS Failover Without Transactions Example

This example demonstrates two servers coupled as a live-backup pair for high availability (HA), and a client connection failing over from live to backup when the live server is crashed.

Failover behavior differs wether the JMS session is transacted or not.

When a non-transacted JMS session is used, once and only once delivery is not guaranteed and it is possible some messages will be lost or delivered twice, depending when the failover to the backup server occurs.

It is up to the client to deal with such cases. To ensure once and only once delivery, the client must use transacted JMS sessions (as shown in the example for failover with transactions).

For more information on HornetQ failover and HA, and clustering in general, please see the clustering section of the user manual.

## Example step-by-step

To run the example, simply type `./build.sh` (or `build.bat` on windows) from this directory

In this example, the live server is server 1, and the backup server is server 0

The connection will initially be created to server1, server 1 will crash, and the client will carry on seamlessly on server 0, the backup server.

1. Get an initial context for looking up JNDI from server #1.

               initialContext = getContext(1);

2. Look up the JMS resources from JNDI on server #1.

               Queue queue = (Queue)initialContext.lookup("/queue/exampleQueue");
               ConnectionFactory connectionFactory = (ConnectionFactory)initialContext.lookup("/ConnectionFactory");

3. Create a JMS Connection

               connection = connectionFactory.createConnection();

4. Create a JMS non-transacted Session with client acknowledgement

               Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);

5. Start the connection to ensure delivery occurs

               connection.start();

6. Create a JMS MessageProducer and MessageConsumer

               MessageProducer producer = session.createProducer(queue);
               MessageConsumer consumer = session.createConsumer(queue);

7. Send some messages to server #1

               for (int i = 0; i < numMessages; i++)
               {
                  TextMessage message = session.createTextMessage("This is text message " + i);
                  producer.send(message);
                  System.out.println("Sent message: " + message.getText());
               }

8. Receive and acknowledge half of the sent messages

               TextMessage message0 = null;
               for (int i = 0; i < numMessages / 2; i++)
               {
                  message0 = (TextMessage)consumer.receive(5000);
                  System.out.println("Got message: " + message0.getText());
               }
               message0.acknowledge();

9. Receive the second half of the sent messages but do not acknowledge them yet

               for (int i = numMessages / 2; i < numMessages; i++)
               {
                  message0 = (TextMessage)consumer.receive(5000);
                  System.out.println("Got message: " + message0.getText());
               }

10. Crash server #1, the live server, and wait a little while to make sure it has really crashed.

               killServer(1);
               Thread.sleep(2000);

11. Acknowledging the second half of the sent messages will fail as failover to the backup server has occured

               try
               {
                  message0.acknowledge();
               }
               catch (JMSException e)
               {
                  System.err.println("Got exception while acknowledging message: " + e.getMessage());
               }

12. Consume again the second half of the messages againg. Note that they are not considered as redelivered

               for (int i = numMessages / 2; i < numMessages; i++)
               {
                  message0 = (TextMessage)consumer.receive(5000);
                  System.out.printf("Got message: %s (redelivered?: %s)\n", message0.getText(), message0.getJMSRedelivered());
               }
               message0.acknowledge();

13. And finally, always remember to close your resources after use, in a `finally` block. Closing a JMS connection will automatically close all of its sessions, consumers, producer and browser objects

               finally
               {
                  if (connection != null)
                  {
                     connection.close();
                  }

                  if (initialContext != null)
                  {
                     initialContext.close();
                  }
               }