【问题标题】:Cannot create a subscriber on the durable subscription无法在持久订阅上创建订阅者
【发布时间】:2015-10-16 07:11:39
【问题描述】:

我正在为系统集成主题开发一个小项目,并且我正在使用 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)

有没有办法在程序中断时关闭连接/取消订阅/某些东西?

【问题讨论】:

  • 你能捕捉到中断的异常,做一些清理,然后重新抛出它吗?
  • 我尝试添加一个 ShutdownHook,但它不起作用。我会再次检查文档,我可能试图以错误的方式关闭连接,我不知道。

标签: java jboss jms


【解决方案1】:

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

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

(我假设它是InterruptedException,因为你说“说我中断程序” - 但也许是其他类型:同样的想法适用)

【讨论】:

  • 我实际上的意思是键盘中断,或者通过 IDE 停止进程。老实说,我不知道这是否会引发 InterruptedException...
  • 为什么不尝试——暂时——捕捉Exception,看看如果你“中断”进程会抛出什么? (只是不要将其保留为catch Exception long term)
  • 谢谢,原来我只是以错误的方式关闭连接。我会发布答案。
  • 对了,我试过抓Exception,没有
【解决方案2】:

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

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() 关闭连接。无论如何,它不起作用,现在它起作用了。哎呀我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-12
    • 1970-01-01
    • 2017-01-24
    • 2017-11-08
    • 1970-01-01
    • 2015-09-01
    • 1970-01-01
    • 2015-08-24
    相关资源
    最近更新 更多