JMS is a Java Enterprise technology that has been implemented to decouple the logic from event producer from event consumers by means of messages. In this two parts tutorial, we will learn how to send and receive JMS Messages from a Spring Boot application using Apache Artemis MQ .
This tutorial is split in two parts:
- Part 1: In the first part, we will show how to send JMS Messages using an embedded Artemis MQ Server
- Part 2: In the next part, we will connect to a remote Artemis MQ Broker. The second part is available here: JMS Messaging with Spring Boot and Remote Artemis MQ
Creating the Project
Firstly, we will need a project which uses artemis dependencies, therefore from the CLI we will execute:
$ spring init -d=artemis artemis -x
Additionally, as we will start ArtemisMQ in embedded mode, we will also need to add as extra dependency “artemis-jms-server”:
<dependency> <groupId>org.apache.activemq</groupId> <artifactId>artemis-jms-server</artifactId> </dependency>
Here is the full list of dependencies you need to run this example project:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-artemis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>artemis-jms-server</artifactId> </dependency> </dependencies>
The configuration of the server will be contained in the file application.properties:
spring.artemis.mode=embedded spring.artemis.embedded.enabled=true spring.artemis.embedded.queues=springbootQueue myqueue=springbootQueue
As you can see, we have declared the server mode, that is embedded . Also, we have configured the list of destinations that we will use in our example.
Coding the JMS Producer and Consumer
Next, let’s add a JMS Producer to our main Application class:
package com.example.artemis; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import org.springframework.jms.core.JmsTemplate; @SpringBootApplication public class DemoApplication { private static final Logger log = LoggerFactory.getLogger(DemoApplication.class); public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @Value("${myqueue}") String queue; @Bean CommandLineRunner start(JmsTemplate template) { return args -> { log.info("Sending> ..."); template.convertAndSend(queue, "Hello World from Spring Boot!"); }; } }
As you can see, it’s declaring a @Bean CommandLineRunner method to allow the execution after the Spring Boot finishes its pre-configuration. Also, this method has the JmsTemplate instance, which we use to convertAndSend an Hello World message.
JmsTemplate is a core class within the Spring Framework that provides a convenient abstraction layer over the Java Message Service (JMS) API. Its primary purpose is to simplify interactions with JMS by handling resource management (connections, sessions, producers, consumers) and providing higher-level methods for sending and receiving messages.
Finally, to consume messages, we will be adding a Message Consumer:
package com.example.artemis; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Consumer implements MessageListener { private Logger log = LoggerFactory.getLogger(Consumer.class); @Override public void onMessage(Message message) { try { log.info("Received message: " + message.getBody(Object.class)); } catch (JMSException ex) { ex.printStackTrace(); } } }
Within this class, we need:
• Implement MessageListener
• Code the method onMessage to receive messages asynchronously.
Finally, you need to do some extra configuration involving how to connect to the ArtemisMQ server:
package com.example.artemis; 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.jms.listener.DefaultMessageListenerContainer; import javax.jms.ConnectionFactory; @Configuration public class MessagingConfig { @Autowired private ConnectionFactory connectionFactory; @Value("${myqueue}") private String queue; @Bean public DefaultMessageListenerContainer messageListener() { DefaultMessageListenerContainer container = new DefaultMessageListenerContainer(); container.setConnectionFactory(this.connectionFactory); container.setDestinationName(queue); container.setMessageListener(new Consumer()); return container; } }
The @Configuration annotation tells Spring to configure any declared methods annotated with the @Bean annotations.
We have @Autowired a ConnectionFactory for creating a connection with the default user identity to the broker. In this case it will create the connection to the ArtemisMQ server with the default credentials.
Lastly, the @Bean messageListener defines a bean that will return a DefaultMessageListenerContainer instance. The DefaultMessageListenerContainer will be responsible for connecting to the queue and listening through the consumer’s MessageListener interface implementation.
Running the Application
Finally, you can run the application with:
$ ./mvnw spring-boot:run
After running the application you should have the logs from the consumer and producer, something similar to this:
Congratulations! You have successfully connected an embedded ArtemisMQ server with a Spring Boot consumer/producer!
Continue reading here if you want to learn how to connect to a remote ArtemisMQ server: JMS Messaging with Spring Boot and Remote Artemis MQ
The source code for this tutorial (kindly provided by mastertheboss.com is available here)
Found the article helpful? if so please follow us on Socials