This is a cache of https://developer.ibm.com/tutorials/spring-boot-java-applications-for-cics-part-5-jms/. It is a snapshot of the page as it appeared on 2025-11-15T03:30:46.124+0000.
Spring Boot Java applications for CICS, Part 5: JMS - IBM Developer
The fifth and final tutorial in the Spring Boot Java applications for CICS series demonstrates how to use Spring Boot's JMS capabilities integrated into a CICS Liberty server and with IBM MQ as the JMS provider. You'll learn how to develop the application, build it with Gradle or Maven, and then deploy and test it in CICS.
Spring Boot offers a number of options for integrating with messaging systems and the JMS API. These options range from the simple convenience of the JmsTemplate to a message-driven POJO (MDP), which handles incoming asynchronous messages through use of the @JmsListener annotation.
The sample is a web application and all requests can be driven from a browser. The application uses the Spring Boot web interface to process HTTP RESTful GET requests. The web application then uses a JMS connection factory to write a message to an MQ queue, which then triggers a Spring Boot MDP that receives the message and writes the contents to a CICS temporary storage queue (TSQ). In a real-world implementation, other types of REST interfaces, such as POST, would be more appropriate. GET requests are used here for simplicity (see Figure 1).
Once your newly generated project has been imported into your IDE, you should have the Application.java and ServletInitializer.java classes which provide the basic framework of a Spring Boot web application.
For Gradle, your build file will need three additional dependencies over and above those required for the Part 1 tutorial:
javax.transaction-api
javax.jms-api
spring-integration-jms
The Java EE JTA and JMS dependencies should be marked as compileOnly because the Liberty runtime provides its own implementations. You want to compile against those dependencies, but not package them into the build as would be done if the implementation directive was chosen.
In this section, you’ll learn how to send a simple JMS message to an MQ queue using Spring’s JmsTemplate and a JMS connection factory.
The first task is to update your Spring Application class. You will need to add the @EnableJms and @EnableTransactionManagement Spring annotations in addition to the standard @SpringBootApplication. These annotations are necessary to enable the Spring Boot components that are required for your transactional JMS application. You also need to create a Spring Bean that returns a JMS connection factory defined in the Liberty server configuration. You will use the JNDI name jms/cf for your connection factory.
Note: See the README file for details on how to configure the JMS connection factory in the Liberty server.xml.
The JmsTemplate interface is the central class in Spring’s JMS core package. It simplifies JMS operations leaving application code to provide the input and extract results. You inject the JmsTemplate using the @Autowired annotation.
The root() method defines a mapping to the root URL / using the @GetMapping("/") annotation, and returns usage information for the sample.
The send() method is annotated with the @RequestMapping("/send/{jmsq}") and takes as input the name of the JMS queue as a URI path parameter, and an input query string to be written to the queue. This means the URL format for your endpoint should be /send/{queue}?data={input string} where queue is the name of the MQ queue. You use the convertAndSend() method on the JmsTemplate to write the input string to the JMS queue. This method converts the input string to a JMS message. You can modify the conversion behaviour if required by implementing the MessageConverter interface and providing your own implementation of the methods fromMessage() and toMessage().
3. Receive a JMS message using an MDP
Although JmsTemplate can be used to send and receive messages, it can't easily be used to initiate work from incoming messages. Instead, Spring provides an asynchronous message-driven POJO (MDP) to provide a message-based application entry point, similar to Java EE message-driven beans.
You will now create a new class called JMSMessageReceiver to act as your MDP.
JMSMessageReceiver is annotated with @Component so that it is found during classpath scanning and registered as a Spring Bean. This bean uses the receiveMessage() method to receive the input string from the JMS queue.
The @JmsListener annotation on the receiveMessage() method defines the name of the destination queue
to listen to, while containerFactory tells Spring which factory it should use to create the underlying message listener.
The JMS listener containerFactory myFactoryBean must be created as a Spring Bean in the Application class and takes as input the connection factory. Add the following code to the Application class to define myFactoryBean:
Note: In order to take advantage of CICS integration and to call the JCICS API, the container factory should set its task executor to be the DefaultManagedTaskExecutor. Although this is a Liberty executor, it has been primed to supply CICS-enabled threads -- thus Spring itself will be supplied CICS-enabled threads. The sample code uses the TSQ class to write to a CICS temporary storage queue, "SPRINGQ," and so you use setTaskExecutor(taskExecutor()) to achieve the necessary JCICS integration.
Without performing this action, the JmsListenerContainerFactory won't run on a CICS-enabled thread. If a request tries to use the JCICS API, you will get an error like this:
org.springframework.jms.listener.adapter.ListenerExecutionFailedException: Listener method 'public void com.ibm.cicsdev.springboot.jms.smokeTest.JMSMessageReceiver.receiveMessage(java.lang.String) throws com.ibm.cics.server.CicsException' threw exception; nested exception is com.ibm.cics.server.CicsRuntimeException: DTCTSQ\_WRITE: No JCICS context is associated with the current thread.
Copy codeCopied!
To create a suitable task executor bean, add the following taskExecutor() method to the Application class:
The final step to support use of the task executor is to add the concurrent-1.0 Liberty feature to the Liberty feature manager list in server.xml. Once you’ve done this, the MDP should be able to receive messages from MQ written to the SPRING.QUEUE and then write to the CICS temporary storage queue SPRINGQ using the JCICS API.
4. Add transaction management
In order to make the JMSMessageReceiver class fully transactional, you need to ensure that reading messages from the JMS queue is coordinated with writing to the CICS TSQ. When using the JMS resource adapter in client mode, sends and receives do not operate under the control of the CICS unit-of-work, so to coordinate these two actions you need to use a global transaction and the Java Transaction API. PlatformTransactionManager is the central interface in Spring's transaction infrastructure and Spring offers several implementations of the platform transaction manager interface for handling transactions across JDBC, JPA, Hibernate, JMS, and so on.
Spring makes available the JmsTransactionManager, which implements a local transaction using the PlatformTransactionManager or Spring's JtaTransactionManager which provides global transaction
support based on JTA. In our scenario, to integrate recoverable operations across the JMSListener and the CICS TSQ resource, you need to use the Spring JtaTransactionManager. For more information, see Spring Boot Java applications for CICS, Part 3: Transactions.
Based on the this knowledge, you can amend your Spring Application class by adding a new Spring Bean for a JTA-enabled PlatformTransactionManager as follows:
Lastly, add the @Transactional (rollbackFor=Exception.class) annotation to the receiveMessage() method in the JMSMessageReceiver class to denote this as a Spring Boot container-managed transaction. The rollbackFor=Exception.class setting ensures that the method rolls back for any exceptions, not just unchecked exceptions.
In addition, you need to add a test on the input message string data, and if the data equals "rollback," then you throw an exception causing a rollback of the JTA (global) transaction. Equally, if the JCICS TSQ.writeString() method fails with a checked CICSConditionException, this will also cause a rollback.
Your JMSMessageReceiver should now look like this:
After the above configuration, your MDP will be able to receive messages and update the CICS TSQ under a single global transaction, meaning both operations always commit or both rollback if an exception is thrown.
Note: If application security is enabled in the target Liberty server, you need to enable an authentication method and authorisation roles. To do this, create a Java EE web.xml file and place it in the src/main/webapp/WEB-INF folder.
A sample web.xml file that supports basic authentication is provided in the associated Git repository. For further details on enabling security, refer to the previous tutorial, Spring Boot Java applications for CICS, Part 2: Security.
5. Deploy and run the sample
To deploy the sample into a CICS Liberty JVM server, you need to build the application as a WAR. Gradle build.gradle and Maven pom.xml files are provided in the sample repository to simplify this task. Once you've done this, there are a couple of ways to deploy the application:
Add an <application> element to the Liberty server.xml that points directly to the WAR.
Add the WAR to a CICS bundle project, exporting the project to zFS, and install it using a CICS BUNDLE resource definition.
In addition, you need to:
Create an MQ queue called SPRING.QUEUE.
Add a CICS TSMODEL definition for the temporary storage queue SPRINGQ, defined as recoverable.
Add the MQ resource adapter and a connection factory definition in Liberty server.xml.
Add the following Liberty features to your server.xml:
servlet-3.1 or servlet-4.0
wmqJmsClient-2.0
concurrent-1.0
For further details on configuring Liberty and deploying the sample to CICS, see the README in the Git repository.
To invoke the application, simply find the base URL for the application in the Liberty messages.log. For example:
CWWKT0016I: Web application available (default_host): http://myzos.mycompany.com:32000/cics-java-liberty-springboot-jms-0.1.0/
Paste the base URL along with the REST service suffix send/SPRING.QUEUE?data=I LOVE CICS into the browser. For example:
http://myzos.mycompany.com:httpPort/cics-java-liberty-springboot-jms-0.1.0/send/SPRING.QUEUE?data=I LOVE CICS
The browser will prompt for basic authentication.
Next, write the string "rollback" to the same queue using the REST service suffix /send/SPRING.QUEUE?data=rollback.
Check if the specified TSQ has the information you expected by executing the CICS command CEBR SPRINGQ. For this example, you should just see the words "I LOVE CICS" in TSQ SPRINGQ as the second update should have rolled back.
Summary
Using JMS to access messaging systems is made easy in Spring using the JmsTemplate. This is the final tutorial in this series. Be sure to review the full set of samples on other Spring Boot applications for CICS Liberty such as Link to Liberty, Java Persistence API (JPA) and asynchronous threading from the CICS Java development team.
About cookies on this siteOur websites require some cookies to function properly (required). In addition, other cookies may be used with your consent to analyze site usage, improve the user experience and for advertising.For more information, please review your cookie preferences options. By visiting our website, you agree to our processing of information as described in IBM’sprivacy statement. To provide a smooth navigation, your cookie preferences will be shared across the IBM web domains listed here.