Camel JMS Component example

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

That’s all! enjoy Camel with JMS!

Leave a Reply