Embedded ActiveMQ and Spring JMS Integration

This tutorial will show you how you can build Spring based application with Apache ActiveMQ for point-to-point messaging domain. In point to point messaging domain you have only one message producer and only one message consumer. For more information on point-to-point messaging system please read tutorial https://roytuts.com/configure-jms-client-using-glassfish-3/

As the ActiveMQ will be started in embedded mode, so you won’t be able to see the message in the ActiveMQ admin console.

Now you will look into the following steps in order to implement point-to-point messaging system using Spring and embedded ActiveMQ.

Prerequisites

Java at least 8, Spring Boot 2.4.3, Maven 3.6.3

Project Setup

You can create maven based project in your favorite IDE or tool. The name of the project is spring-jms-embedded-apache-activemq.

The pom.xml file with required dependency is given below:

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.roytuts</groupId>
	<artifactId>spring-jms-embedded-apache-activemq</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<maven.compiler.source>12</maven.compiler.source>
		<maven.compiler.target>12</maven.compiler.target>
	</properties>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.4.3</version>
	</parent>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-activemq</artifactId>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

Message Producer

In point to point messaging domain you need message produces that will produce message.

package com.roytuts.spring.jms.apache.activemq;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Component;

@Component
public class MessageProducer {

	@Autowired
	private JmsTemplate jmsTemplate;

	public void sendMessageToDestination(final String message) {
		jmsTemplate.convertAndSend(message);
	}

}

Message Consumer

There is one message consumer that consumes messages produced by the message producer.

package com.roytuts.spring.jms.apache.activemq;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

import org.springframework.stereotype.Component;

@Component
public class MessageConsumer implements MessageListener {

	@Override
	public void onMessage(Message message) {
		if (message instanceof TextMessage) {
			try {
				String msg = ((TextMessage) message).getText();

				System.out.println("Message has been consumed : " + msg);
			} catch (JMSException ex) {
				throw new RuntimeException(ex);
			}
		} else {
			throw new IllegalArgumentException("Message must be of type TextMessage");
		}
	}

}

App Configuration

Create a file application.properties under src/main/resources folder with the following key/value pairs. Here I have specified message broker URL and destination queue name. The queue is used in the point-to-point messaging domain whereas topic is used in the publish/subscribe domain.

jms.broker.url=tcp://localhost:61616
jms.queue.name=IN_QUEUE

You need to configure various Spring beans for connectionfactory, jms template, destination, etc. I am showing you embedded ActiveMQ, so I am creating the BrokerService bean for this.

package com.roytuts.spring.jms.apache.activemq;

import javax.jms.ConnectionFactory;
import javax.jms.Destination;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.broker.BrokerService;
import org.apache.activemq.command.ActiveMQQueue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.jms.connection.CachingConnectionFactory;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.listener.DefaultMessageListenerContainer;
import org.springframework.jms.listener.MessageListenerContainer;

@Configuration
@PropertySource("classpath:application.properties")
public class JmsConfig {

	@Value("${jms.broker.url}")
	private String brokerUrl;

	@Value("${jms.queue.name}")
	private String queueName;

	@Autowired
	private MessageConsumer messageConsumer;

	@Bean
	public BrokerService broker() throws Exception {
		BrokerService broker = new BrokerService();
		broker.addConnector(brokerUrl);
		broker.setPersistent(false);
		return broker;
	}

	@Bean
	public ConnectionFactory connectionFactory() {
		return new CachingConnectionFactory(new ActiveMQConnectionFactory(brokerUrl));
	}

	@Bean
	public Destination destination() {
		return new ActiveMQQueue(queueName);
	}

	@Bean
	public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory, Destination destination) {
		JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
		jmsTemplate.setDefaultDestination(destination);

		return jmsTemplate;
	}

	@Bean
	public MessageListenerContainer defaultMessageListenerContainer(ConnectionFactory connectionFactory,
			Destination destination) {
		DefaultMessageListenerContainer defaultMessageListenerContainer = new DefaultMessageListenerContainer();
		defaultMessageListenerContainer.setConnectionFactory(connectionFactory);
		defaultMessageListenerContainer.setDestination(destination);
		defaultMessageListenerContainer.setMessageListener(messageConsumer);

		return defaultMessageListenerContainer;
	}

}

Main Class

A class is having @SpringBootApplication and main method enough to deploy the application using Spring Boot framework.

package com.roytuts.spring.jms.apache.activemq;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringJmsApacheActiveMqApp implements CommandLineRunner {

	@Autowired
	private MessageProducer messageProducer;

	public static void main(String[] args) {
		SpringApplication.run(SpringJmsApacheActiveMqApp.class, args);
	}

	@Override
	public void run(String... args) throws Exception {
		messageProducer.sendMessageToDestination("Send this message to destination");
	}

}

Testing the Application

Now you can start your Spring boot application by running the main class. You will see the following output on the console:

Message has been consumed : Send this message to destination

You won’t be able to check the ActiveMQ console as the Apache ActiveMQ is running in embedded mode. In the console you will see that the connector started Connector tcp://127.0.0.1:61616 started.

That’s all about how to work with Spring and embedded Apache ActiveMQ for JMS.

Source Code

Download

Author: Soumitra

Hi, I am, Soumitra, the owner of roytuts.com and it is my passion for sharing my knowledge and I have been writing blogs on various technologies since 2014. If you like my tutorials, you may also want to like my Facebook Page, follow me on Twitter, Github.

2 thoughts on “Embedded ActiveMQ and Spring JMS Integration

  1. Having trouble getting this set up correctly … can you be specific/explicit regarding names and locations for each of the four xml files shown?

Leave a Reply

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