无法在持久订阅上创建订阅者

Cannot create a subscriber on the durable subscription

我正在为一个系统集成主题的小项目工作,我正在使用 JMS (JBOSS)。我们必须使用持久主题,这部分很容易。问题是,假设我使用以下代码:

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

这个 try-with-resources 很有用,因为它会在块结束时破坏连接。但是假设我在 JMSConsumer 等待消息时中断了程序。当我重新启动程序时,它会抛出:

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

有没有办法在程序中断时关闭connection/unsubscribe/something?

如果你需要做一些清理但不吞下异常,你可以捕获异常,做一些清理,然后重新抛出原来的异常:

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

(我假设它是一个 InterruptedException,因为你说 "say I interrupt the program" - 但也许它是其他类型:同样的想法适用)

基本上,我使用了以下代码:

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

我想我试图使用 jmsContext.stop() 关闭连接。无论如何,它没有用,现在可以了。耶我。