Friends of OpenJDK Today

Durable Subscription with JMS and Spring Boot

December 28, 2023

Author(s)

  • Simon Martinelli

    Simon Martinelli is a Java Champion, a Vaadin Champion, and an Oracle ACE Pro. He regularly shares his knowledge in articles, speaks at international conferences, and writes his blog: https://martinelli.ch. ... Learn more

When using the publish-subscribe domain with JMS, we often want to use durable subscriptions. But how can this be done with Spring Boot?

What is JMS?

The Java Message Service (JMS) API is a standard for creating, sending, receiving, and reading messages. It enables distributed communication that is loosely coupled, reliable, and asynchronous.

JMS supports two message delivery modes: Point-to-Point and Publish/Subscribe

In the point-to-point domain, a producer can send a message to one consumer through a destination called "queue". A given queue may have multiple receivers, but only one receiver may consume each message.

In the publish-subscribe domain, a producer can send a message to many consumers through a destination called "topic". Consumers can subscribe to a topic and receive a copy of each message.

Durable Subscription

Durable subscriptions allow messages to remain on a topic while the message consumer is not active. A durable subscriber registers a durable subscription by specifying a unique identity that is retained by the JMS provider. You establish the unique identity of a durable subscriber by setting the following:

  • A client ID for the connection
  • A topic and a subscription name for the subscriber

Configuration with Spring Boot and JMS

The first thing to configure is that we want to use the publish-subscribe domain in the application.properties:

spring.jms.pub-sub-domain=true

Next we must configure durable subscription. Unfortunately this cannot be done using a simple property. We have to configure the ConnectionFactory manually:

@Bean
public JmsListenerContainerFactory<?> artemisConnectionFactory(
                                         CachingConnectionFactory connectionFactory,
                                         DefaultJmsListenerContainerFactoryConfigurer configurer) {
    // When using durable subscription the ClientId must be set for reconnect
    // Note that client IDs need to be unique among all active Connections of the underlying JMS provider
    connectionFactory.setClientId(clientId);

    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    configurer.configure(factory, connectionFactory);
    factory.setPubSubDomain(pubSubDomain);
    factory.setSubscriptionDurable(true);

    return factory;
}

The crucial lines in the configuration are line 6, where we set a client ID, which has to be unique among all active connections, and line 11, where we activate the durable subscription mode.

Finally, we must configure the Listener to use this connection factory by setting the containerFactory attribute of the JmsListener annotation. We also set the subscription. If this attribute is not set, Spring JMS will generate a subscription name based on the class and method name.

@JmsListener(destination = "${chat.topic}",
             selector = "user <> '${chat.user}'",
             containerFactory = "artemisConnectionFactory",
             subscription = "chat")
public void onMessage(Message message) {
    ...
}

Example Code and References

You can find the source code on GitHub: https://github.com/simasch/spring-boot-jms-pubsub-durable

The two pictures are taken from the Java EE 5 tutorial

Related Articles

View All
  • A Simple Service with Spring Boot

    I will demonstrate how to create a simple Web Service using Spring Boot.  This framework makes it almost effortless to develop web services, so long as the appropriate dependencies are in place.

    In this example, I will create a Web Service that will read the current temperature from a file and make it available to clients via a RESTful endpoint.

    Read More
    Avatar photo
    September 22, 2020
  • Annotation-free Spring

    Some, if not most, of our judgments regarding technology stacks come either from third-party opinions or previous experiences. Yet, we seem to be adamant about them!

    Read More
    Avatar photo
    September 17, 2021
  • Better Error Handling for Your Spring Boot REST APIs

    One of the things that distinguishes a decent API from one that is a pleasure to work with is robust error handling. Nothing is more frustrating than using some API and getting back cryptic errors where you can only guess why the server is not accepting your request.

    Spring Boot lets you customize the error handling for your application, but there is quite a lot of low-level coding involved if you want to do this correctly.

    Read More
    August 21, 2021

Author(s)

  • Simon Martinelli

    Simon Martinelli is a Java Champion, a Vaadin Champion, and an Oracle ACE Pro. He regularly shares his knowledge in articles, speaks at international conferences, and writes his blog: https://martinelli.ch. ... Learn more

Comments (1)

Your email address will not be published. Required fields are marked *

Highlight your code snippets using [code lang="language name"] shortcode. Just insert your code between opening and closing tag: [code lang="java"] code [/code]. Or specify another language.

Save my name, email, and website in this browser for the next time I comment.

Java Annotated Monthly – February 2024 | The IntelliJ IDEA Blog - https://ukrainepost.dreamhosters.com

[…] Durable Subscription with JMS and Spring Boot – When using the publish-subscribe domain with JMS, we often want to use durable subscriptions. But how can this be done with Spring Boot? Simon Martinelli answers this question in his article.  […]

Subscribe to foojay updates:

https://foojay.io/feed/
Copied to the clipboard