My Grails 2.2.1 application has for a while needed to connect to JMS queues. Configuration for that is fairly straightforward and its covered well in the documentation of relevant plugins (I use the Grails JMS Plugin). Recently it became necessary to add a few durable subscriptions to a topic (three to be exact, each with a different selector). Now in the interest of not polluting my configuration files, I wanted these three listeners to share a connection description and JMS container.
First hurdle was to have the three listeners connect my ActiveMQ instances. After not having much success I found that what was missing was a client id – which you only need to set for durable subscriptions. The client id needs to be setup on the connection factory in resources.groovy (not in the adapter or container settings). Below are examples of the the resources.groovy settings and Config.groovy settings respectively.
With these settings I was able to get my three listeners connected but the durable subscription was not functional. The default behavior when you use a service listener is that it uses the name of the service as the subscription name. That would be fine except that the the service listener passed to Spring JMS is a proxy of the Service bean. This results in the subscription name having the proxy part included – “com.enterprise.service.RegistrationListenerServicesdf43ghu”. Since the last part is randomly generated at every server startup the durable subscription that was setup was worthless. One way to override it would be to define a separate container/adapter for every listener and then hard code the subscription name in the configuration. That is not a scalable solution and is a lot of clutter just to override the default subscription name. The cleaner solution I found was to have my service listeners implement SubscriptionNameProvider.
With this configuration in place I finally had my topic listeners setup and truly durable!