This article is a walk through the Camel JMS Component. We will show how to use this component to produce and consume messages. In this article we will show two different options: a Spring Boot Application and a Camel Standalone application.
The JMS Component allows to send/consume messages from/to a JMS Queue or Topic. Behind the hoods, it uses Spring’s JMS support for declarative transactions, including Spring’s JmsTemplate for sending and a MessageListenerContainer for consuming.
We will show here two example applications, the first one is a Spring Boot application, the second one is a standalone Camel application. To run both examples, you need an active instance of Artemis MQ Broker. The following article will guide you through the installation and set up of it: Getting started with Artemis MQ
Camel JMS Component with Spring Boot
Spring Boot greatly simplify the configuration of Camel components. Firstly, register the JmsComponent as @Bean and include the Connection Factory settings:
import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory; import org.apache.camel.component.jms.JmsComponent; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class AppConfig { @Bean public JmsComponent jmsComponent() throws Exception { // Create the connectionfactory which will be used to connect to Artemis ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory(); cf.setBrokerURL("tcp://localhost:61616"); cf.setUser("admin"); cf.setPassword("admin"); // Create the Camel JMS component and wire it to our Artemis connectionfactory JmsComponent jms = new JmsComponent(); jms.setConnectionFactory(cf); return jms; } }
In the above example, we assume that Artemis MQ Server is running at the URL “tcp://localhost:61616” with the user admin/admin.
Next, configure the Camel Route as Spring Component:
@Component public class CamelArtemisRouteBuilder extends RouteBuilder { public void configure() throws Exception { from("timer:mytimer?period=5000").routeId("generate-route") .transform(constant("HELLO from Camel!")) .to("jms:queue:QueueIN"); from("jms:queue:QueueIN").routeId("receive-route") .log("Received a message - ${body} - sending to outbound queue") .to("jms:queue:QueueOUT?exchangePattern=InOnly"); } }
In our example routes, there’s a “generate-route” which pushes messages in the Queue “QueueIN”. The messages are then moved into the “QueueOUT” from the route “receive-route”.
The application class completes our example:
@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
Building the application
Since our application uses Spring Boot runtime, we need to use Spring Boot starters to build it. Then, we will also add the artemis-jms-client to bootstrap ArtemisMQ Connection Factory:
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <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.sample</groupId> <artifactId>jms-example-spring</artifactId> <version>1.0-SNAPSHOT</version> <name>SpringBootJMS</name> <description>Spring Boot example with JMS</description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <surefire.plugin.version>3.0.0-M4</surefire.plugin.version> <spring.boot-version>2.7.0</spring.boot-version> </properties> <dependencyManagement> <dependencies> <!-- Spring Boot BOM --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring.boot-version}</version> <type>pom</type> <scope>import</scope> </dependency> <!-- Camel BOM --> <dependency> <groupId>org.apache.camel.springboot</groupId> <artifactId>camel-spring-boot-dependencies</artifactId> <version>3.9.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.apache.camel.springboot</groupId> <artifactId>camel-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.apache.camel.springboot</groupId> <artifactId>camel-jms-starter</artifactId> </dependency> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>artemis-jms-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-undertow</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${spring.boot-version}</version> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>${surefire.plugin.version}</version> </plugin> </plugins> </build> </project>
When running the application, you will be able to see on the console the messages which are received from the log component:
20:18:14.537 [Camel (camel-1) thread #0 - JmsConsumer[QueueIN]] INFO receive-route - Received a message - HELLO from Camel! - sending to outbound queue 20:18:19.546 [Camel (camel-1) thread #0 - JmsConsumer[QueueIN]] INFO receive-route - Received a message - HELLO from Camel! - sending to outbound queue 20:18:24.550 [Camel (camel-1) thread #0 - JmsConsumer[QueueIN]] INFO receive-route - Received a message - HELLO from Camel! - sending to outbound queue
Besides, if you connect to Artemis MQ Console, you should be able to browse messages which are sent to the outbound Queue:

Source code for this example: https://github.com/fmarchioni/masterspringboot/tree/master/jms/camel-jms-springboot
Camel JMS Component standalone
For the sake of completeness, we will also show how to create a simple example of Camel JMS Component using a standalone application.
The following main application contains both the JmsComponent configuration and the RouteBuilder class:
import org.apache.camel.CamelContext; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.impl.DefaultCamelContext; import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory; import org.apache.camel.component.jms.JmsComponent; public class MainApp { public static void main(String... args) throws Exception { // use Camels Main class CamelContext ctx = new DefaultCamelContext(); ActiveMQConnectionFactory cf = new ActiveMQConnectionFactory(); cf.setBrokerURL("tcp://localhost:61616"); cf.setUser("admin"); cf.setPassword("admin"); ctx.addComponent("jms", JmsComponent.jmsComponentAutoAcknowledge(cf)); ctx.addRoutes( new RouteBuilder() { public void configure() { from("timer:mytimer?period=5000").routeId("generate-route") .transform(constant("HELLO from Camel!")) .to("jms:queue:QueueIN"); from("jms:queue:QueueIN").routeId("receive-route") .log("Received a message - ${body} - sending to outbound queue") .to("jms:queue:QueueOUT?exchangePattern=InOnly"); } }); ctx.start(); Thread.sleep(10000); ctx.stop(); } }
Finally, we will use standalone Camel dependencies to build the application. We also need to add logging libraries as we don’t get them out of the box – as the Spring Boot application does:
<dependencyManagement> <dependencies> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-parent</artifactId> <version>3.9.0</version> <scope>import</scope> <type>pom</type> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-core</artifactId> </dependency> <dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-jms</artifactId> </dependency> <dependency> <groupId>org.apache.activemq</groupId> <artifactId>artemis-jms-client</artifactId> <version>2.19.1</version> </dependency> <!-- logging --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <scope>runtime</scope> </dependency> </dependencies>
Source code for this example: https://github.com/fmarchioni/masterspringboot/tree/master/jms/camel-jms-standalone
Using a Selector in Camel JMS
Selectors are Properties which are set in the Header of the JMS Message so that you can filter only the messages which are compliant with the filter. You can set the selector using the selector attribute which is an SQL 92 predicate that is used to filter messages within the broker. You may have to encode special characters like ‘='
as %3D
.
Here is an example of two routes:
import java.io.IOException; import javax.jms.ConnectionFactory; import javax.management.MBeanServerConnection; import javax.management.remote.JMXConnector; import javax.management.remote.JMXConnectorFactory; import javax.management.remote.JMXServiceURL; import org.apache.activemq.ActiveMQConnectionFactory; import org.apache.camel.CamelContext; import org.apache.camel.LoggingLevel; import org.apache.camel.builder.RouteBuilder; import org.apache.camel.component.jms.JmsComponent; import org.apache.camel.impl.DefaultCamelContext; public class App { public static void main(String args[]) throws Exception { CamelContext context = new DefaultCamelContext(); ConnectionFactory connectionFactory = new ActiveMQConnectionFactory( "tcp://0.0.0.0:61616"); context.addComponent("jms", JmsComponent.jmsComponentAutoAcknowledge(connectionFactory)); context.addRoutes(new RouteBuilder() { public void configure() { from("timer:foo?period=1s").setBody(simple("Message at ${date:now:yyyy-MM-dd HH:mm:ss}")).to( "activemq:queue:somequeue"); from("activemq:queue:somequeue?selector=clientid %3D 'someid'").to("activemq:queue:otherqueue"); } }); context.start(); try { System.in.read(); } catch (IOException e) { e.printStackTrace(); } context.stop(); } }
Only messages which contain the header “clientid = ‘someid'” are allowed to transit from “somequeue” to “otherqueue”.