Your first JMS application with Spring Boot

User Rating: 5 / 5

Star ActiveStar ActiveStar ActiveStar ActiveStar Active
 

Today I'm testing how to run a sender and receive Hello World application with Spring Boot. Let's see how complex is it compared to a Java EE approach.

Create a basic Maven project, and add a couple of Java classes to it. The first one will be the Spring Boot bootstrap class that also works as JMS Sender:

package com.mastertheboss.springboot;


import javax.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;
 
@SpringBootApplication
@EnableJms
public class App  {

    @Bean
    public JmsListenerContainerFactory<?> myFactory(ConnectionFactory connectionFactory,
                                                    DefaultJmsListenerContainerFactoryConfigurer configurer) {
        DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();
        configurer.configure(factory, connectionFactory);
        return factory;
    }


    
    public static void main(String[] args) {
        // Launch the application
        ConfigurableApplicationContext context = SpringApplication.run(App.class, args);

        JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class);

        System.out.println("Sending a JMS message.");
        jmsTemplate.convertAndSend("sampleQueue", "Hello world!");
    }

}

Within the App class, besides the standard SpringBoot annotation, we have included the @EnableJms annotation which allows the discovery of methods annotated with @JmsListener, creating the POJO message listener container under the hoods. We have also provided a method for creating a default ConnectionFactory which can be optionally overriden, for example if you are going to use a non default Connection Factory, as could be ArtemisMQ or HornetQ Connection Factory.

Next, we will code our Message Receiver POJO. Within it, the JmsListener annotation defines the name of the Destination that this method should listen. It can optionally include a reference to the JmsListenerContainerFactory to use to create the underlying message listener container

package com.mastertheboss.springboot;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;

@Component
public class ReceiveMessage {
 
    @JmsListener(destination = "sampleQueue")
    public void receiveMessage(String msg) {
        System.out.println("Received :" + msg);
    }
 
}

In terms of configuration, all you need is providing a JMS Broker: If Spring Boot detects that ActiveMQ is available on the classpath, an embedded broker is started and configured automatically (as long as no broker URL is specified through configuration). So just a couple of dependencies will do the work:

<?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.mastertheboss.springboot</groupId>
	<artifactId>SpringBootJMS</artifactId>
	<version>1.0-SNAPSHOT</version>
	<packaging>war</packaging>

	<name>Spring Example Project</name>

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

	<properties>
		<java.version>1.8</java.version>
		<source>1.8</source>
		<target>1.8</target>
		<spring.version>4.3.0.RELEASE</spring.version>
	</properties>


	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-activemq</artifactId>
		</dependency>
		<dependency>
			<groupId>org.apache.activemq</groupId>
			<artifactId>activemq-broker</artifactId>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

Now simple package and run your application with:

$ mvn clean install spring-boot:run

Here's the expected output:

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.4.0.RELEASE)

2017-01-23 19:31:33.520  INFO 21585 --- [           main] com.mastertheboss.springboot.App         : Starting App on localhost.localdomain with PID 21585 (/home/francesco/git/mastertheboss-master/spring/SpringBootJMS/target/classes started by francesco in /home/francesco/git/mastertheboss-master/spring/SpringBootJMS)
2017-01-23 19:31:33.523  INFO 21585 --- [           main] com.mastertheboss.springboot.App         : No active profile set, falling back to default profiles: default
2017-01-23 19:31:33.612  INFO 21585 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@6583bb95: startup date [Mon Jan 23 19:31:33 CET 2017]; root of context hierarchy
2017-01-23 19:31:34.764  INFO 21585 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2017-01-23 19:31:34.769  INFO 21585 --- [           main] o.s.c.support.DefaultLifecycleProcessor  : Starting beans in phase 2147483647
2017-01-23 19:31:34.864  INFO 21585 --- [           main] o.apache.activemq.broker.BrokerService   : Using Persistence Adapter: MemoryPersistenceAdapter
2017-01-23 19:31:34.939  INFO 21585 --- [  JMX connector] o.a.a.broker.jmx.ManagementContext       : JMX consoles can connect to service:jmx:rmi:///jndi/rmi://localhost:1099/jmxrmi
2017-01-23 19:31:35.067  INFO 21585 --- [           main] o.apache.activemq.broker.BrokerService   : Apache ActiveMQ 5.13.4 (localhost, ID:localhost.localdomain-44429-1485196294936-0:1) is starting
2017-01-23 19:31:35.074  INFO 21585 --- [           main] o.apache.activemq.broker.BrokerService   : Apache ActiveMQ 5.13.4 (localhost, ID:localhost.localdomain-44429-1485196294936-0:1) started
2017-01-23 19:31:35.074  INFO 21585 --- [           main] o.apache.activemq.broker.BrokerService   : For help or more information please see: http://activemq.apache.org
2017-01-23 19:31:35.114  INFO 21585 --- [           main] o.a.activemq.broker.TransportConnector   : Connector vm://localhost started
2017-01-23 19:31:35.195  INFO 21585 --- [           main] com.mastertheboss.springboot.App         : Started App in 1.996 seconds (JVM running for 7.054)

Sending a JMS message.
Received :Hello world!

Pretty cool isn't it ?

Follow us on Twitter