JMS is a standard Java API that allows a Java application to send messages to another application. It is highly scalable and allows us to loosely couple applications using asynchronous messaging. Using JMS we can read, send and read messages.
Here are some implementations of JMS is as follows:
- Amazon SQS
- Apache ActiveMQ
- JBoss Messaging
- RabbitMQ
JMS Message
A JMS message can be divided into three parts that are as follows:
- Header: It contains the metadata about the message.
- Properties: It can further be subdivided into three sections –
- Application: The java application sending message.
- Provider: It is used by the JMS provider and is implementation-specific.
- Standard Properties: These are defined by the JMS API.
- Payload: This field is the message itself.
Implementation: Here we will be building a sample greeting (Maven-based)application to demonstrate how to integrate and use JMS. For simplicity, we will be using an embedded server instead of creating another application.
The project Structure is as follows:
Step 1: Create a spring project using spring initializer. Create the folders and files as depicted in the below image as follows:

Project structure
Step 2: Add the below dependencies to pom.xml file.
XML
< dependency >
< groupId >org.apache.activemq</ groupId >
< artifactId >artemis-server</ artifactId >
</ dependency >
< dependency >
< groupId >org.apache.activemq</ groupId >
< artifactId >artemis-jms-server</ artifactId >
</ dependency >
< dependency >
< groupId >org.springframework.boot</ groupId >
< artifactId >spring-boot-starter-artemis</ artifactId >
</ dependency >
< dependency >
< groupId >org.springframework.boot</ groupId >
< artifactId >spring-boot-starter-web</ artifactId >
</ dependency >
< dependency >
< groupId >org.springframework.boot</ groupId >
< artifactId >spring-boot-devtools</ artifactId >
< scope >runtime</ scope >
< optional >true</ optional >
</ dependency >
< dependency >
< groupId >org.projectlombok</ groupId >
< artifactId >lombok</ artifactId >
< optional >true</ optional >
</ dependency >
< dependency >
< groupId >org.springframework.boot</ groupId >
< artifactId >spring-boot-starter-test</ artifactId >
< scope >test</ scope >
</ dependency >
|
Model Layer
Step 3: Create a simple POJO (Plain old java class) which will act as our model for sending and receiving messages. Here we have used Lombok to reduce boilerplate code. Annotations used are as follows:
- @Data: This annotation generates getters, setters for all the fields, toString method, and equals & hashCode method.
- @Builder: This annotation uses a builder pattern to automatically build complex builder APIs.
- @NoArgsConstructor: This annotation generates a constructor with no arguments.
- @AllArgsConstructor: This annotation generates a constructor with all arguments.
Example:
Java
package com.anuanu.springjms.model;
import java.io.Serializable;
import java.util.UUID;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class GreetingMessage implements Serializable {
static final long serialVersionUID
= -7462433555964441775L;
private UUID id;
private String message;
}
|
Required Configurations is as follows:
A. Embedded Server Configuration
As discussed earlier, we will be creating an embedded server for the demonstration of JMS messaging. We will be using ActiveMQServers to create our embedded server. Here is the method signature to newActiveMQServer:
Modifier and Type |
Methods and Description |
static ActiveMQServer |
newActiveMQServer(Configuration config) |
Note: Configuration can be changed as per the requirement.
The embedded server also starts when our spring boot application starts. (as we have called start() method on the server).
Example:
Java
package com.anuanu.springjms;
import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
import org.apache.activemq.artemis.core.server.ActiveMQServer;
import org.apache.activemq.artemis.core.server.ActiveMQServers;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringJmsApplication {
public static void main(String[] args) throws Exception
{
ActiveMQServer activeMQServer
= ActiveMQServers.newActiveMQServer(
new ConfigurationImpl()
.setPersistenceEnabled( false )
.setJournalDirectory(
"target/data/journal" )
.setSecurityEnabled( false )
.addAcceptorConfiguration( "invm" ,
activeMQServer.start();
SpringApplication.run(SpringJmsApplication. class ,
args);
}
}
|
C. Task Configuration
The taskConfig class will help us execute tasks asynchronously. The task here is sending messages at fixed intervals of time. For sending messages at fixed intervals we have enabled the scheduler using @EnableScheduling annotation. Annotations used are as follows:
- @EnableScheduling: This annotation enables the scheduler for our application.
- @EnableAsync: This annotation enables spring to run @Async methods in a background thread pool.
- @Configuration: This annotation indicates that the specified class has @Bean definition methods.
- @Bean: It is a method-level annotation and is used to explicitly declare a bean.
Example:
Java
package com.anuanu.springjms.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
@EnableScheduling
@EnableAsync
@Configuration
public class TaskConfig {
@Bean TaskExecutor taskExecutor()
{
return new SimpleAsyncTaskExecutor();
}
}
|
D. Message Converter Configuration
The jmsConfig class provides a common stream for producers and consumers for producing and consuming messages respectively. It also provides a bean for converting Java objects and JMS messages. Annotations used are as follows:
- @Configuration: This annotation indicates that the specified class has @Bean definition methods.
- @Bean: It is a method-level annotation and is used to explicitly declare a bean.
Note : Message converter uses Jackson 2.x to convert messages to and from JSON. It maps an object to a BytesMessage, or to a TextMessage if the targetType is set to MessageType.TEXT. It converts from a TextMessage or BytesMessage to an object.
Example:
Java
package com.anuanu.springjms.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jms.support.converter.MappingJackson2MessageConverter;
import org.springframework.jms.support.converter.MessageConverter;
import org.springframework.jms.support.converter.MessageType;
@Configuration
public class JmsConfig {
public static final String QUEUE = "greet" ;
@Bean
public MessageConverter messageConverter()
{
MappingJackson2MessageConverter converter
= new MappingJackson2MessageConverter();
converter.setTargetType(MessageType.TEXT);
converter.setTypeIdPropertyName( "_type" );
return converter;
}
}
|
Sending JMS Messages
The MessageSender class (described below) is mainly used to create and produce/send messages to the common stream from where the consumer can consume messages. We have used JmsTemplate which is a helper class that makes it easier for us to receive and send messages through JMS. We have also annotated the class with @Scheduled with a value of 2000 ms which tells the scheduler to send the messages at an interval of every 2 seconds. Annotations used are as follows:
- @RequiredArgsConstructor : This annotation generates a constructor with required arguments i,e. arguments with final fields or fields with other constraints.
- @Component: This annotation marks our class as the component which allows spring to detect any custom-defined beans.
- @Scheduled: This annotation marks a method to be scheduled. It must have any one of these cron(), fixedDelay() or fixedRate() attributes.
Example:
Java
package com.anuanu.springjms.sender;
import com.anuanu.springjms.config.JmsConfig;
import com.anuanu.springjms.model.GreetingMessage;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
@RequiredArgsConstructor
@Component
public class MessageSender {
private final JmsTemplate jmsTemplate;
private static Integer ID = 1 ;
@Scheduled (fixedRate = 2000 )
public void sendMessage()
{
System.out.println( "Greetings user" );
GreetingMessage message
= GreetingMessage.builder()
.id(UUID.randomUUID())
.message( "Greetings user " + ID++)
.build();
jmsTemplate.convertAndSend(JmsConfig.QUEUE,
message);
System.out.println( "Message sent!!!" );
}
}
|

Sending messages
Receiving JMS Messages
The MessageListener class (described below) acts as a consumer i.e. it consumes/receives messages that reside in the common stream and is not already consumed. The location of the common stream “JmsConfig.QUEUE” is passed to the destination method in @JmsListener. Annotations used are as follows:
- @JmsListener: This annotation marks a method to be the target of a JMS message listener on the specified destination().
- @Component: This annotation marks our class as component which allows spring to detect any custom-defined beans.
- @Payload: This annotation marks that the payload of the message is to be extracted is annotated parameter.
- @Headers: This annotation extracts all the headers inside a Map<String, Object>. It is used here with MessageHeaders class which implements Map<String, Object> and is used for message headers.
Example:
Java
package com.anuanu.springjms.listener;
import com.anuanu.springjms.config.JmsConfig;
import com.anuanu.springjms.model.GreetingMessage;
import javax.jms.Message;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;
@Component
public class MessageListener {
@JmsListener (destination = JmsConfig.QUEUE)
public void
listen( @Payload GreetingMessage greetingMessage,
@Headers MessageHeaders messageHeaders,
Message message)
{
System.out.println( "Greeting Received!!!" );
System.out.println(greetingMessage);
}
}
|

Receiving messages
Output:
The message is sent and received every 2 seconds. A unique user name and id is passed for every new message.

Output – 1
Inspecting the messageListener class:

The below image shows us the jms message that is received at the messageListener class. There is a variety of properties that can be customized in the header field. Notice the one key-value pair we added in the header.
'_type' -> 'com.anuanu.springjms.model.GreetingMessage'

Whether you're preparing for your first job interview or aiming to upskill in this ever-evolving tech landscape,
GeeksforGeeks Courses are your key to success. We provide top-quality content at affordable prices, all geared towards accelerating your growth in a time-bound manner. Join the millions we've already empowered, and we're here to do the same for you. Don't miss out -
check it out now!
Last Updated :
16 Nov, 2022
Like Article
Save Article