1 of 1 people found this helpful
That's to be expected. In JMS changing the selector causes the old subscription to be deleted and a new one to be created.
See JMS javadoc:
"A client can change an existing durable subscription by creating a durable
TopicSubscriberwith the same name and a new topic and/or message selector. Changing a durable subscriber is equivalent to unsubscribing (deleting) the old one and creating a new one."
I read portion of the documentation that describes changing the selector. My question was that I didn't change the call to createDurableSubscriber at all because I didn't intend to change the messageSelector. The change occurred because I had noLocal set (both times), and the connection ID changed. I don't control the connection ID, so I can't make it stay the same. What I am trying to accomplish is a subscriber with a filter someAttribute="someValue" and connection=NOT_THIS_ONE. It seems that the unsubscribe happens because the noLocal setting is rolled into the messageSelector. Is this implementation specific, or do all JMS providers work this way?
As far as I know all JMS providers work this way.
When ou change the connectionID, you are creating a different subscriber. If you want to recover your previous subscription, you must use the same ConnectionID.
You could have a higher control on the publish/subscriber if you are not using JMS. Like you could have an Address, and a Queue associated with that address, and have your consumer always using the same queue.
Those things are automated under the covers with the JMS layer for you, but you could use the core-api directly if you needed more specicialized behaviour.
in our environment we have the same problem and we could have situations in which subscribers lost their connection (due to server restart) and when they reconnect,
they need to re-use the same connectionID in order to avoid that old subscription will be deleted and a new one will be created.
How can we set the same ConnectionID every time the subscriber starts?
Thanks in advance.
Actually I think the story doesn't end here though.
Yes, I think it is correct in JMS terms that if the message selector changes, the subscription is effectively changed so messages from the 'old' version will be lost. But I also think Sue and Stefano are correct because NO, I don't think HornetQ's implementation of JMS should add the __HQ_CID<>... into the selector string because this makes durable subscriptions as specified in the JMS spec. impossible using HQ JMS (and assuming you DON'T want to use core - as in my case where we have dozens of JMS processes and don't want to go around re-developing them to use HQ core API).
As has been mentioned, the JMS API does not provide a call to set the connection ID (and it doesn't make sense for it to else how can the server manage dups?). I think the HQ implementation of JMS is partly broken because it does not properly support durable subscriptions - in other words, a durable subscriber cannot disconnect then reconnect with (what it thinks) is the identical details (clientID, selector, name) and pick up messages published while it was down or disconnected - in other words, it's only durable if HQ goes down otherwise it might as well not be durable.
I'm using HQ2.2.14_FINAL in stand-alone, non-clustered mode under JDK1.6 on solaris 10 and have the same issue as the other two. Fortunately, I can get around it by setting noLocal = false because my subscriber does not also publish - hence these posts were very useful, thankyou! I used jConsole to list the subscribers as JSON and noticed the __HQ_CID added and my tiny braincell sparked and I searched for 'noLocal and HornetQ durable subscriber' and found this thread.
I still think this should be fixed though.
We close processes down weekly or overnight and are in the process of upgrading from JBOSSMQ under JBAS4 to JBAS5 and a stand-alone HQ JVM. JBOSSMQ did not add this connection ID to the selector and neither does IBM WAS as far as I can tell because we have IBM WAS topics here also and you can connect / disconect the client with noLocal set to true and it still picks up messages published while the client was down.