JMS in Spring Boot applications

You can use JMS in Spring Boot applications to send and receive messages by using reliable, asynchronous communication by using messaging providers such as IBM MQ.

To use JMS in your Spring Boot application, add a JMS artifact to your dependencies in your Spring Boot application to make the necessary Java libraries available. For example, in Maven,
<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-jms</artifactId>
</dependency>
<dependency>
    <groupId>javax.jms</groupId> 
    <artifactId>javax.jms-api</artifactId>
    <scope>provided</scope>
</dependency>
or in Gradle,
implementation("org.springframework.integration:spring-integration-jms")
compileOnly("javax.jms:javax.jms-api")
To send and receive messages by using a JMS messaging provider, you can define a JMS connection factory in the Liberty server.xml as you would if you were using JMS in a Java EE application. This connection factory can then be used to reference a remote IBM MQ queue manager by using a JmsTemplate object and either:
  1. Performing a JNDI lookup of the connection factory in an @Bean annotated connectionFactory() method and returning the connection factory.
  2. Naming the connection factory in the spring.jms.jndi-name in the Spring application properties. Spring Boot then creates the JmsTemplate by using the connection factory that is named in the application.properties.
Note: In option 2, it is also possible to configure all the connection factory attributes necessary to connect a Spring application to the required queue manager from within the application.properties file. The attributes are all defined in Common application properties. However, this ties the application directly the queue manager and by using JNDI is a more flexible approach.

A message driven POJO (MDP) is used to handle incoming messages in Spring Boot. An @EnableJms annotation is used in the Spring Boot Configuration class to enable discovery of methods annotated @JmsListener. The @JMSListener annotation marks a method to be the target of a JMS message listener that receives incoming messages.

If you want these MDPs to be able to use the JCICS API, then you need to bind the Liberty TaskExecutor to the JmsListenerContainerFactory. This can be achieved as follows:
@Bean
public TaskExecutor taskExecutor()
{
    return new DefaultManagedTaskExecutor();
}

@Bean
public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory) 
{
    DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
    factory.setConnectionFactory(connectionFactory);
    factory.setTaskExecutor(taskExecutor());
    return factory;
}
Note: This requires the use of the jndi-1.0 and concurrent-1.0 Liberty features.

The Spring Boot @Transactional annotation can also be used on the @JMSListener annotated method to signify that the receiving of the message from the queue and the CICS UOW are to be coordinated by using the same container-managed JTA global transaction.