1
votes

The ActiveMQ setting, server, properties are all in the jndi.properties file.

Example:

java.naming.provider.url=failover:(tcp://localhost:61616?keepAlive=true)
java.naming.factory.initial = org.apache.activemq.jndi.ActiveMQInitialContextFactory
queue.MyQueue = testUpdate

While my program look like this:

public class MQReader{

public final String JNDI_FACTORY = "ConnectionFactory";
public final String QUEUE = "MyQueue";

private QueueConnectionFactory queueConnectionFactory;
private QueueConnection queueConnection;
private QueueSession queueSession;
private QueueReceiver queueReceiver;
private Queue queue;

public static void main(String[] args) throws Exception {

    // create a new intial context, which loads from jndi.properties file
    javax.naming.Context ctx = new javax.naming.InitialContext();
    MQReader reader = new MQReader();
    reader.init(ctx);

    try {
        reader.wait();
    } catch (InterruptedException ie) {
        ie.printStackTrace();
    }
    reader.close();
}

public void init(Context context) throws NamingException, JMSException {
    queueConnectionFactory = (QueueConnectionFactory) context.lookup(JNDI_FACTORY);
    queueConnection = queueConnectionFactory.createQueueConnection();
    queueSession = queueConnection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
    queue = (Queue) context.lookup(QUEUE);
    queueReceiver = queueSession.createReceiver(queue);
    queueReceiver.setMessageListener(
        message ->{
            try {
                if(message != null) {
                    //do stuff like print message for testing.
                }
            } catch (JMSException jmse) {
                    System.err.println("An exception occurred: " + jmse.getMessage());
            }
        }
    );
    queueConnection.start();
}

public void close() throws JMSException {
    queueReceiver.close();
    queueSession.close();
    queueConnection.close();
}

}

I thought the failover item in the jndi should take care of my reconnecting but it does not. I ran the broker and ran the program and it worked perfectly but once I stopped the broker, my consumer program just exit with exit code of 1. "Process finished with exit code 1"

I am not sure what I did wrong here. I have added print out statement a lot of places and found out that it exited at reader.wait() without triggering any exception.

1

1 Answers

1
votes

I figure it out. Since my main thread exited after I started the listener thread and the listener thread is running(non-daemon thread) perfectly, it keeps the JVM running. Once the listener loses it connection, the program exits because there are no non-daemon thread running left. The failover protocol code is running as a daemon thread so therefore the JVM exit the program without letting the failover protocol code to reconnect.

So what I did is to add this piece of code, not the best way to do it but it works for what I am trying to do.

 Scanner in = new Scanner(System.in);
    while(true){
        System.out.println("Please enter \"stop\" to stop the program.");
        String command = in.nextLine();
        if("stop".equalsIgnoreCase(command)){
            reader.close();
            System.exit(0);
        }
    }

instead of

try {
    reader.wait();
} catch (InterruptedException ie) {
    ie.printStackTrace();
}
reader.close();

The wait method was crashing and was not keeping the main thread alive. This is also a way to keep my program running without sending messages to queue to stop it.