Apache ActiveMQ Artemis is a combined feature-set of ActiveMQ/HornetQ/Apollo. It provides a non blocking architecture for an outstanding performance. So in the tutorial, JavaSampleApproach will guide how to
create JMS producer/consumer by SpringBoot Artemis applications.
Related posts:
- Spring JMS with ActiveMQ – JMS Consumer and JMS Producer | Spring Boot
- Spring Apache Kafka Application with SpringBoot Auto-Configuration
- Spring RabbitMQ Producer/Consumer applications with SpringBoot
I. Technologies
– Java 8
– Maven 3.6.1
– Spring Tool Suite: Version 3.8.4.RELEASE
– Spring Boot: 1.5.4.RELEASE
– Apache Artemis 2.1.0
II. SpringBoot Artemis
1. SpringBoot Auto-configure
When having artemis-jms-client
Artemis on the classpath, Spring Boot can auto-configure a ConnectionFactory.
We use spring.artemis.*
to control Artemis configuration:
spring.artemis.mode=native
spring.artemis.host=localhost
spring.artemis.port=61616
spring.artemis.user=jsa
spring.artemis.password=12345
spring.artemis.mode
has 2 mode: {NATIVE, EMBEDDED}:
- NATIVE: Connect to a broker using the native Artemis protocol.
-
EMBEDDED: Embed the broker in the application.
2. Sending/Receiving messages
For sending message, we use:JmsTemplate jmsTemplate
@Component
public class ArtemisProducer {
@Autowired
JmsTemplate jmsTemplate;
@Value("${jms.queue.destination}")
String destinationQueue;
public void send(String msg){
jmsTemplate.convertAndSend(destinationQueue, msg);
}
}
For recieved messages, we use: @JmsListener
:
@Component
public class ArtemisConsumer {
@JmsListener(destination = "${jms.queue.destination}")
public void receive(String msg){
System.out.println("Recieved Message: " + msg);
}
}
3. SpringBoot Artemis applications
In the tutorial, we create 2 SpringBoot Artemis projects for producer/consumer:
III. Practice
We create 2 SpringBoot projects {SpringBootArtemisProducer, SpringBootArtemisConsumer}:
Step to do:
- Create SpringBoot projects
- Implement Artemis Producer/Consumer
- Deploy Artemis
- Run and check results
1. Create SpringBoot projects
Using SpringToolSuite, we create 2 SpringBoot projects: {SpringBootArtemisProducer, SpringBootArtemisConsumer}.
For SpringBootArtemisProducer, add dependencies:
<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>
For SpringBootArtemisConsumer, add dependencies:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-jms-client</artifactId>
<version>2.1.0</version>
</dependency>
Why we don't use artemis-jms-client 2.1.0
for SpringBootArtemisProducer?
-> At the time we do the tutorial, artemis-jms-client 2.1.0
has a bug for jmsTemplate.convertAndSend
with exception:
java.lang.NoSuchMethodError: org.apache.activemq.artemis.api.core.client.ClientMessage.setUserID(Ljava/lang/Object;)Lorg/apache/activemq/artemis/api/core/Message;
at org.apache.activemq.artemis.jms.client.ActiveMQMessageProducer.doSendx(ActiveMQMessageProducer.java:469) ~[artemis-jms-client-2.1.0.jar:2.1.0]
at org.apache.activemq.artemis.jms.client.ActiveMQMessageProducer.send(ActiveMQMessageProducer.java:191) ~[artemis-jms-client-2.1.0.jar:2.1.0]
at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:626) ~[spring-jms-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:597) ~[spring-jms-4.3.10.RELEASE.jar:4.3.10.RELEASE]
at org.springframework.jms.core.JmsTemplate$4.doInJms(JmsTemplate.java:574) ~[spring-jms-4.3.10.RELEASE.jar:4.3.10.RELEASE]
Why we don't use spring-boot-starter-artemis - version 1.5.6
(that includes artemis-jms-client 1.5.5
) for Artemis consumer @JmsListener
?
-> Because we got an bug:
Setup of JMS message listener invoker failed for destination 'JSA-QUEUE' - trying to recover. Cause: AMQ119019: Queue already exists JSA-QUEUE
Note:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-artemis</artifactId>
<version>1.5.6.RELEASE</version>
</dependency>
</pre>
<strong>EQUAL TO</strong>:
<pre class="lang:xhtml">
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>4.3.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.activemq</groupId>
<artifactId>artemis-jms-client</artifactId>
<version>1.5.5</version>
</dependency>
2. Implement Artemis Producer/Consumer
For above projects, open application.properties files, add Artemis configuration:
spring.artemis.mode=native
spring.artemis.host=localhost
spring.artemis.port=61616
spring.artemis.user=jsa
spring.artemis.password=12345
jms.queue.destination=JSA-QUEUE
2.1 Implement Artemis Producer
Using JmsTemplate
to implement ArtemisProducer
:
package com.javasampleapproach.artemis.jms;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jms.core.JmsTemplate;
import org.springframework.stereotype.Component;
@Component
public class ArtemisProducer {
@Autowired
JmsTemplate jmsTemplate;
@Value("${jms.queue.destination}")
String destinationQueue;
public void send(String msg){
jmsTemplate.convertAndSend(destinationQueue, msg);
}
}
- Create a simple RestApi for sending messages:
package com.javasampleapproach.artemis.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.javasampleapproach.artemis.jms.ArtemisProducer;
@RestController
public class RestApiController {
@Autowired
ArtemisProducer producer;
@RequestMapping(value="/produce")
public String produce(@RequestParam("msg")String msg){
producer.send(msg);
return "Done";
}
}
2.2 Implement Artemis Consumer
Using @JmsListener
to implement ArtemisConsumer:
package com.javasampleapproach.artemis.jms;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
@Component
public class ArtemisConsumer {
@JmsListener(destination = "${jms.queue.destination}")
public void receive(String msg){
System.out.println("Recieved Message: " + msg);
}
}
3. Deploy Artemis
Go to Artemis download page. Download Artemis 2.1.0:
Extract apache-artemis-2.1.0-bin.zip, we have:
Create an Artemis broker jsa-springboot-broker by commandline:
C:\apache-artemis-2.1.0\bin>artemis create "C:\dev\jsa-springboot-broker"
:
Run the Artemis broker by commnandline: "C:\dev\jsa-springboot-broker\bin\artemis" run
4. Run and check results
Build and Run above SpringBoot projects with commandlines: {mvn clean install
, mvn spring-boot:run
}
- Make a sending request:
http://localhost:8080/produce?msg=JSA - SpringBoot Artemis, Hello World!
. Results:
-> Use jconsole.exe, monitor message added in Artemis queue:
-> Artemis Consumer's Logs:
Recieved Message: JSA - SpringBoot Artemis, Hello World!
Top comments (0)