1
votes

I'm working on a small project for a Systems Integration subject, and I'm using JMS (JBOSS). We have to use durable topics, and that part is quite easy. The thing is, let's say I use the following code:

TopicConnectionFactory topicConnectionFactory = InitialContext.doLookup("jms/RemoteConnectionFactory");
try(JMSContext jmsContext = topicConnectionFactory.createContext(<username>,<password>)) {
    Topic topic = InitialContext.doLookup(<topic>);
    JMSConsumer jmsConsumer = jmsContext.createDurableConsumer(topic, <client-id>);
    Message message = jmsConsumer.receive();
    if(message != null) {
        result = message.getBody(ArrayList.class);
    }
}

This try-with-resources is useful, since it destroys the connection when the block ends. But let's say I interrupt the program while the JMSConsumer waits for the message. When I restart the program, it will throw:

javax.jms.IllegalStateRuntimeException: Cannot create a subscriber on the durable subscription since it already has subscriber(s)

Is there a way to close the connection/unsubscribe/something when the program is interrupted?

2
Can you catch the interruptedexception, do some cleanup, then rethrow it? - Andy Turner
I tried adding a ShutdownHook, but it doesn't work. I'll check the docs again, I might be trying to close the connection the wrong way, I don't know. - Budgerous

2 Answers

1
votes

If you need to do some cleanup but not swallow the exception, you can catch the exception, do some cleanup, then rethrow the original exception:

try(JMSContext jmsContext = topicConnectionFactory.createContext(<username>,<password>)) {
  // ...
} catch (InterruptedException e) {
  // Do some cleanup.
  throw e;
}

(I'm assuming that it's an InterruptedException, because you said "say I interrupt the program" - but maybe it is some other type: same idea applies)

0
votes

Basically, I used the following code:

TopicConnectionFactory topicConnectionFactory = InitialContext.doLookup("jms/RemoteConnectionFactory");
try(JMSContext jmsContext = topicConnectionFactory.createContext(<username>,<password>)) {
    Topic topic = InitialContext.doLookup(<topic>);
    JMSConsumer jmsConsumer = jmsContext.createDurableConsumer(topic, <client-id>);
    Runtime.getRuntime().addShutdownHook(new Thread() {
        public void run() {
            jmsConsumer.close();
            this.interrupt();
        }
    });
    Message message = jmsConsumer.receive();
    if(message != null) {
        result = message.getBody(ArrayList.class);
    }
}

I was trying to close the connection using jmsContext.stop(), I think. Anyhow, it wasn't working, now it is. Yay me.