简体   繁体   中英

Unable to persist messages on JMS Topics and retreive them later

My end objective is to develop an application that on startup retrieves the last message published on a topic; and that, whether the message was published a second ago, or a month ago, or even earlier...

My feeling is that I have to use persistent topic . For test purpose, I tried to develop a sample that would do what I want:

public void myTest() throws JMSException, InterruptedException {
    latch = new CountDownLatch(1);

    ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory();
    factory.setBrokerURL("tcp://150.151.179.31:61616");

    Connection connection1 = factory.createConnection();
    Session session1 = connection1.createSession(false /* no transaction */, Session.CLIENT_ACKNOWLEDGE);
    connection1.start();

    Topic topic1 = session1.createTopic("test.persistence");
    MessageConsumer consumer1 = session1.createConsumer(topic1, null /* no filter */, true /* prevent receiving message published by current session */);
    consumer1.setMessageListener(this);

    //////////////////////////////////////////////////
    // if I do not close the session, my sample works,
    // if I close it, it doesn't
    //
    // session1.close();
    // connection1.close();
    //////////////////////////////////////////////////

    Connection connection2 = factory.createConnection();
    Session session2 = connection2.createSession(false, Session.AUTO_ACKNOWLEDGE);
    connection2.start();

    Topic topic2 = session2.createTopic("test.persistence");
    MessageProducer producer2 = session2.createProducer(topic2);
    MapMessage mapMessage2 = session2.createMapMessage();
    mapMessage2.setStringProperty("key", "value");
    producer2.send(mapMessage2, PERSISTENT, DEFAULT_PRIORITY, DEFAULT_TIME_TO_LIVE);

    Assert.assertTrue(latch.await(5, TimeUnit.SECONDS));
}

@Override
public void onMessage(Message message) {
    latch.countDown();
}

This sample uses ActiveMQ, but I also have the same issue with EMS.

I created two sessions:

  • one is publishing on the PERSISTENT topic
  • the other is trying to receive message on the same topic

The behavior is:

  • If I keep the first session opened my sample works but it does not test the persistence .
  • If I close the first session after the publication of the message and the subscription of the second session, no message is received: it seems that the persistence is not working.

Please help me to understand my issue.

What you're seeing is the expected behavior. JMS topic semantics dictate that messages are discarded when sent in the absence of any subscriptions. This is exactly what happens when you close the subscriber and then send the message.

If you want the subscription to remain after the subscriber is closed then you need to use a durable subscription .

However, you should keep in mind that any messages sent before the durable subscription is created will still be discarded. You'd have to use the " retroactive consumer " feature from ActiveMQ "Classic" to get any messages sent before the subscription was created. Of course that won't work on any other JMS provider aside from ActiveMQ.

Lastly, JMS destinations (ie queues & topics) are themselves not persistent or non-persistent. That is a quality of JMS messages .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM