Oracle Backend for Microservices and AI
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Oracle Spring Boot Starter for AQ/JMS

This starter provides support for Oracle Transactional Event Queues (TxEventQ) and Oracle Advanced Queuing (AQ) as Java Message Service (JMS) providers. It depends on the Universal Connection Pool (UCP) starter.

Note: By default, the data Source and JMS Connection Factory that the starter injects into your application share the same database transaction. This means that you can start a transaction, read from a queue, perform an update operation, and then commit or rollback that whole unit of work, including the message consumption.

To add this starter to your project, add this Maven dependency:

<dependency>
    <groupId>com.oracle.database.spring</groupId>
    <artifactId>oracle-spring-boot-starter-aqjms</artifactId>
    <version>23.4.0</version>
</dependency>

For Gradle projects, add this dependency:

implementation 'com.oracle.database.spring:oracle-spring-boot-starter-aqjms:23.4.0'

To configure your application to use Oracle Transactional Event Queues or Oracle Advanced Queuing, you must annotate you application with the @EnableJms annotation, and create the two following beans:

  • A JmsListenerContainerFactory<?> bean, which can be created as shown in the following example. Note that you can override settings if you need to. Also, note that the name of the method defines the name of the factory, which you will use when creating JMS listeners.
  • A MessageConverter bean to map objects of your class representing the payload into a text based format (like JSON) that can be used in the actual messages.

Note: Any queues or topics that you want to use must be pre-created in the database. See Sample Code for examples.

package com.example.aqjms;

import jakarta.jms.ConnectionFactory;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jms.DefaultJmsListenerContainerFactoryConfigurer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.jms.annotation.EnableJms;
import org.springframework.jms.config.DefaultJmsListenerContainerFactory;
import org.springframework.jms.config.JmsListenerContainerFactory;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.support.converter.MappingJackson2MessageConverter;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jms.support.converter.MessageType;

@SpringBootApplication
@EnableJms
public class JmsSampleApplication {

 @Bean
 public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory,
       DefaultJmsListenerContainerFactoryConfigurer configurer) {
   DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
   // This provides all Boot's defaults to this factory, including the message converter
   configurer.configure(factory, connectionFactory);
   // You could override some of Boot's defaults here if necessary
   return factory;
 }
  
 @Bean
 public MessageConverter jacksonJmsMessageConverter() {
   MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
   converter.setTargetType(MessageType.TEXT);
   converter.setTypeIdPropertyName("_type");
   return converter;
 }
  
 public static void main(String[] args) {
   ConfigurableApplicationContext context = SpringApplication.run(JmsSampleApplication.class, args);
 }
  
}

To send a message to a JMS queue or topic, get an instance of the JmsTemplate from the Spring Application context, and call the convertAndSend() method specifying the name of the queue or topic, and providing the object to be converted and sent in the payload of the message, as shown in the following example:

JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class);
jmsTemplate.convertAndSend("mailbox", new Email(-1, "info@example.com", "Hello"));

To receive messages from a JMS queue or topic, create a method that takes your message class, for example Email, as input. Annotate the method with the @JmsListener annotation, specifying the destination, that is the name of the queue or topic, and the container factory name that you created earlier, as shown in the following example:

package com.example.aqjms;

import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;

@Component
public class Receiver {

    @JmsListener(destination = "mailbox", containerFactory = "myFactory")
    public void receiveMessage(Email email) {
      System.out.println("Received <" + email + ">");
    }

}

Note that the starter uses the configuration for spring.datasource as the connection details for the Oracle Database hosting the queues and topics. If you wish to use a different configuration, you must use a named configuration, for example spring.datasource.txeventq and use Java configuration (as shown for the UCP starter) and annotate the configuration with the standard Spring @Qualifier annotation, specifying the correct name, for example txevevntq.