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());
}
}
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: