Apache Camel Exception Handling Example | CodeUsingJava

Apache Camel Exception Handling Example

In this tutorial we will be having look at how to handle exception in apache camel

Overview

When executing the routes an exception may occur. Using Apache Camel we can implement Exception Handling using -
  • Do Try Catch Block
  • OnException Block

Table Of Contents :


Technology Stack

We will be making use of-
  • Java 1.8
  • Apache Camel 3.0.0-M2
  • Maven
  • Camel-Spring 3.0.0-RC2

Let us get started

In this section, we will introduce Apache Camel's Exception Handling.

In either the spring configuration file or the Java DSL class, we can write the exception handling code. In this article, we will use Java DSL to implement exception handling. The project that we are going to create is as follows-

camel exception project

The dependencies of pom.xml are as follows-


<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.codeusingjava</groupId>
  <artifactId>camel-exception-handling</artifactId>
  <version>0.0.1-SNAPSHOT</version>

	<dependencies>
		<dependency>
			<groupId>org.apache.camel</groupId>
			<artifactId>camel-core</artifactId>
			<version>3.0.0-RC2</version>
		</dependency>

		<dependency>
			<groupId>org.apache.camel</groupId>
			<artifactId>camel-spring</artifactId>
			<version>3.0.0-RC2</version>
		</dependency>

		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>1.7.5</version>
		</dependency>

		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>1.7.5</version>
		</dependency>
	</dependencies>
</project>

Apache camel's exception handling can be implemented in 2 ways.
  • Using Do Try block
  • Using OnException block

Defines the following custom exception So our MyCamelCustomException.java will be as follows-

package com.codeusingjava.customexception;


public class MyCamelCustomException extends RuntimeException {

	private static final long serialVersionUID = 7607128449240157466L;
	public MyCamelCustomException(String message){
		super(message);
	}
}

First, we once throw this custom exception from the MyCustomCamelExceptionProcessor.java call from our Java DSL path.

package com.codeusingjava.processor;

import org.apache.camel.Exchange;
import org.apache.camel.Processor;

import com.codeusingjava.customexception.MyCamelCustomException;

public class MyCustomCamelExceptionProcessor implements Processor{

	public void process(Exchange exchange) throws Exception {
		System.out.println("Exception occured");
		throw new MyCamelCustomException("Exception occured");
	}

}

Our SimpleRouteBuilder code is the following at the moment. There's no written code management exception. The message will therefore continue to be retried as the exception is not handled

package com.codeusingjava.route;

import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;

import com.codeusingjava.customexception.MyCamelCustomException;
import com.codeusingjava.processor.MyCustomCamelExceptionProcessor;

public class MyRouteBuilder extends RouteBuilder{

    @Override
    public void configure() throws Exception {
        from("file:C:/inputFolder?noop=true").process(new MyCustomCamelExceptionProcessor()).to("file:C:/outputFolder");
    }
}

Our main class will be as follows:

package com.codeusingjava.main;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyMainApp {

	public static void main(String[] args) {
		AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        ctx.start();
        System.out.println("Application context started");
        try {
            Thread.sleep(5 * 60 * 1000);
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
        ctx.stop();
        ctx.close();
	}

}


Our application context will be as folows:

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel="http://camel.apache.org/schema/spring"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
		http://www.springframework.org/schema/beans/spring-beans.xsd          
		http://camel.apache.org/schema/spring 
		http://camel.apache.org/schema/spring/camel-spring.xsd">

	<bean id="routeBuilder" class="com.codeusingjava.route.MyRouteBuilder" />

	<camelContext xmlns="http://camel.apache.org/schema/spring">
		<routeBuilder ref="routeBuilder" />
		 <redeliveryPolicyProfile id="test"
            retryAttemptedLogLevel="WARN" maximumRedeliveries="5"
            redeliveryDelay="5" />
	</camelContext>
	
</beans>


camel exception occurs
Let's now look at the exception handling code
  • By using Do Try block
Similar to the Java try catch block, this approach. So the thrown exception will be caught immediately and the message will not go on trying again.

package com.codeusingjava.route;

import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;

import com.codeusingjava.customexception.MyCamelCustomException;
import com.codeusingjava.processor.MyCustomCamelExceptionProcessor;

public class MyRouteBuilder extends RouteBuilder{

    @Override
    public void configure() throws Exception {
         from("file:C:/inputFolder?noop=true").doTry().process(new MyCustomCamelExceptionProcessor()).to("file:C:/outputFolder")
            .doCatch(MyCamelCustomException.class).process(new Processor() {

                public void process(Exchange exchange) throws Exception {
                    System.out.println("Handling exception");
                }
            }).log("Received body ");

}


camel exception handling

This approach's drawback is that it only applies to the single route. Suppose we have one more seperate route Then if an exception happens in that route the current doTry block will not handle it.


package com.codeusingjava.route;

import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;

import com.codeusingjava.customexception.MyCamelCustomException;
import com.codeusingjava.processor.MyCustomCamelExceptionProcessor;

public class MyRouteBuilder extends RouteBuilder{

	@Override
    public void configure() throws Exception {
        from("file:C:/inputFolder?noop=true").doTry().process(new MyCustomCamelExceptionProcessor()).to("file:C:/outputFolder")
            .doCatch(MyCamelCustomException.class).process(new Processor() {

                public void process(Exchange exchange) throws Exception {
                    System.out.println("handling ex");
                }
            }).log("Received body ");

        from("file:C:/inbox?noop=true").process(new MyCustomCamelExceptionProcessor()).to("file:C:/outbox");
    }

}



camel exception multiple handling
The exception from("file:C:/inbox?noop=true") the path is thrown will not be dealt with

Let's now look at the exception handling code
  • By using OnException block
The block OnException is written separately from the routes
All routes are covered by this. Below is the start of both routes
from("file:C:/inputFolder?noop=true") and from("file:C:/inbox?noop=true") the exception handling will be applied.

package com.codeusingjava.route;

import org.apache.camel.Exchange;
import org.apache.camel.Processor;
import org.apache.camel.builder.RouteBuilder;

import com.codeusingjava.customexception.MyCamelCustomException;
import com.codeusingjava.processor.MyCustomCamelExceptionProcessor;

public class MyRouteBuilder extends RouteBuilder{

	@Override
	public void configure() throws Exception {

		onException(MyCamelCustomException.class).process(new Processor() {

			public void process(Exchange exchange) throws Exception {
				System.out.println("handling ex");
			}
		}).log("Received body ").handled(true);

		from("file:C:/inputFolder?noop=true").process(new MyCustomCamelExceptionProcessor()).to("file:C:/outputFolder");

		from("file:C:/inbox?noop=true").process(new MyCustomCamelExceptionProcessor()).to("file:C:/outputFolder");
	}
}


The output is as follows.

camel exception handling example
Thus the onException Block handles the exception thrown from both routes

Download the code of origin-

Download Camel Exception Handling Code-
Apache Camel Quartz Example