Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Re-Connecting to JMS server initially and after already gaining a previous connection

I am having an issue with a JMS re-connect strategy. I'm not sure if I am doing it correctly (Most likely I am not). Anyways, I am using WebLogic, and this is a consumer client. Here's how I gain a connection, and try to add the automatic re-connect. The problem is that it doesn't reconnect, and there are no exceptions logging what-so-ever. I re-create the situation by starting weblogic, starting consumer client which gains initial connection, I close weblogic abrubtly, then I re-start weblogic at which point any messages in the queue which this consumer is listening to remain on the queue without being acknowledged since they are not being received.

public void setReceiver(MessageListener listener) {
        try {
            Properties parm = new Properties();
            parm.setProperty("java.naming.factory.initial",
                    "weblogic.jndi.WLInitialContextFactory");
            parm.setProperty("java.naming.provider.url", URL);
            parm.setProperty("java.naming.security.principal", username);
            parm.setProperty("java.naming.security.credentials", password);
            ctx = new InitialContext(parm);
            final QueueConnectionFactory connectionFactory = (QueueConnectionFactory) ctx
                    .lookup(conFactoryName);
            connection = connectionFactory.createQueueConnection();
            // TODO: 8/6/2012 Work on reconnection strategies for Consumer.
            ((WLConnection) connection)
                    .setReconnectPolicy(JMSConstants.RECONNECT_POLICY_ALL);
            ((WLConnection) connection).setReconnectBlockingMillis(30000L);
            ((WLConnection) connection).setTotalReconnectPeriodMillis(-1L);
            session = connection.createQueueSession(false,
                    Session.AUTO_ACKNOWLEDGE);

            queue = (Queue) ctx.lookup(queueName);
            // receiver = session.createReceiver(queue);
            // receiver.setMessageListener(listener);
            consumer = session.createConsumer(queue);
            consumer.setMessageListener(listener);

            connection.setExceptionListener(new ExceptionListener() {

                @Override
                public void onException(JMSException arg0) {
                    // Assume Disconnected.
                    FileHandler fh = null;
                    try {
                        fh = new FileHandler("./logs/ExceptionListener", true);
                    } catch (SecurityException e) {
                        e.printStackTrace();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    SimpleFormatter formatter = new SimpleFormatter();
                    fh.setFormatter(formatter);
                    Logger log2 = Logger.getLogger("ExceptionListener");
                    log2.addHandler(fh);
                    boolean connected = false;
                    do {
                        if (connection != null) {
                            try {
                                connection.close();
                            } catch (JMSException e) {
                                log.warning(e.toString());
                            }
                            try {
                                connection = connectionFactory.createQueueConnection();
                                connection.setExceptionListener(this);
                                connection.start();
                                connected = true;
                            } catch (JMSException e) {
                                log.severe(e.toString());
                            }
                        }
                    } while (!connected);

                }
            });
            connection.start();

        } catch (JMSException je) {
            log.severe(je.getMessage());
        } catch (Exception e) {
            log.severe(e.getMessage());
        }
    }
like image 383
Reid Mac Avatar asked Aug 06 '12 18:08

Reid Mac


1 Answers

So I finally figured out the issue. The main problem with the exception listener not being called was due to having competing jars in my build path. I had wlfullclient.jar and wljmsclient.jar and wlsasclient.jar in my build path After removing wljmsclient.jar and wlsasclient.jar, I started to receive error messages which allowed me to debug further. Here's my final solution which will try to connect every 30 seconds on the initial connection, and then it will try to re-connect every 30 seconds if it has gained a connection, but then has lost it:

public boolean setReceiver(MessageListener listener) {
        try {
            Properties parm = new Properties();
            parm.setProperty("java.naming.factory.initial",
                    "weblogic.jndi.WLInitialContextFactory");
            parm.setProperty("java.naming.provider.url", URL);
            parm.setProperty("java.naming.security.principal", username);
            parm.setProperty("java.naming.security.credentials", password);
            ctx = new InitialContext(parm);
            final QueueConnectionFactory connectionFactory = (QueueConnectionFactory) ctx
                    .lookup(conFactoryName);
            connection = connectionFactory.createQueueConnection();
            ((WLConnection) connection)
                    .setReconnectPolicy(JMSConstants.RECONNECT_POLICY_ALL);
            ((WLConnection) connection).setReconnectBlockingMillis(30000L);
            ((WLConnection) connection).setTotalReconnectPeriodMillis(-1L);
            session = connection.createQueueSession(false,
                    Session.AUTO_ACKNOWLEDGE);
            queue = (Queue) ctx.lookup(queueName);
            consumer = session.createConsumer(queue);
            consumer.setMessageListener(listener);

            connection.setExceptionListener(new ExceptionListener() {
                @Override
                public void onException(JMSException arg0) {
                    // Assume Disconnected.
                    Logger log2 = new MyLogger().getLogger("BPEL Client");
                    if (arg0 instanceof LostServerException) {
                        log2.severe("Connection to the Server has been lost, will retry in 30 seconds. "
                                + arg0.toString());
                    } else {
                        log2.severe(arg0.toString());
                    }

                }
            });
            connection.start();
            log.info("Successfully connected to " + URL);
            return true;
        } catch (JMSException je) {
            log.severe("Could not connect to the WebLogic Server, will retry in 30 seconds. "
                    + je.getMessage());
            try {
                Thread.sleep(30000L);
            } catch (InterruptedException e) {
                log.warning(e.toString());
            }
            return setReceiver(listener);
        } catch (Exception e) {
            log.severe("Could not connect to the WebLogic Server, will retry in 30 seconds. "
                    + e.toString());
            try {
                Thread.sleep(30000L);
            } catch (InterruptedException ie) {
                log.warning(ie.toString());
            }
            return setReceiver(listener);

        }
    }
like image 170
Reid Mac Avatar answered Sep 30 '22 21:09

Reid Mac