This is an automated email from the ASF dual-hosted git repository.

gnodet pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 552ee0cc3eb736de8b360eb910d8571df6b558b0
Author: Guillaume Nodet <gno...@gmail.com>
AuthorDate: Thu May 23 17:46:33 2019 +0200

    [CAMEL-13564] Split exception/error handling model from runtime
    
    Remaining things:
      - MulticastProcessor.createErrorHandler
      - ErrorHandlerRefReifier.createErrorHandler
      - move state from ErrorHandlerBuilderSupport and ErrorHandlerBuilderRef 
to RouteContext
---
 components/camel-blueprint/pom.xml                 |   4 +
 .../blueprint/CamelErrorHandlerFactoryBean.java    |   2 +-
 .../cdi/transaction/JtaTransactionPolicy.java      |   3 +-
 .../camel/spring/spi/SpringTransactionPolicy.java  |   3 +-
 .../spring/spi/TransactionErrorHandlerBuilder.java |   5 +
 .../spring/spi/TransactionErrorHandlerReifier.java |  89 ++++++++++++++++
 .../camel/builder/DefaultErrorHandlerBuilder.java  |   8 ++
 .../camel/builder/ErrorHandlerBuilderRef.java      |   3 +-
 .../camel/builder/ErrorHandlerBuilderSupport.java  |  62 ++++++++++-
 .../errorhandler/ErrorHandlerSupport.java          |  59 ++---------
 .../errorhandler/RedeliveryErrorHandler.java       |  30 ++----
 .../DefaultExceptionPolicyStrategy.java            |  59 +++++------
 .../processor/exceptionpolicy/ExceptionPolicy.java |  85 +++++++++++++++
 .../exceptionpolicy/ExceptionPolicyKey.java        |   8 +-
 .../exceptionpolicy/ExceptionPolicyStrategy.java   |   9 +-
 .../apache/camel/reifier/DynamicRouterReifier.java |   3 +-
 .../apache/camel/reifier/OnExceptionReifier.java   |   1 +
 .../org/apache/camel/reifier/ProcessorReifier.java |   3 +-
 .../apache/camel/reifier/RoutingSlipReifier.java   |   3 +-
 .../errorhandler/DeadLetterChannelReifier.java     |  48 +++++++++
 .../errorhandler/DefaultErrorHandlerReifier.java   |  69 ++++++++++++
 .../errorhandler/ErrorHandlerRefReifier.java       |  19 ++++
 .../{ => errorhandler}/ErrorHandlerReifier.java    | 118 +++++++++++++++++++--
 .../errorhandler/NoErrorHandlerReifier.java        |  41 +++++++
 .../ValidatorEndpointClearCachedSchemaTest.java    |   5 +
 .../errorhandler/ErrorHandlerSupportTest.java      |  13 +--
 .../CustomExceptionPolicyStrategyTest.java         |   3 +-
 .../DefaultExceptionPolicyStrategyTest.java        |  48 ++++-----
 28 files changed, 641 insertions(+), 162 deletions(-)

diff --git a/components/camel-blueprint/pom.xml 
b/components/camel-blueprint/pom.xml
index a7880bf..3179463 100644
--- a/components/camel-blueprint/pom.xml
+++ b/components/camel-blueprint/pom.xml
@@ -52,6 +52,10 @@
             <artifactId>camel-core-osgi</artifactId>
         </dependency>
         <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-core</artifactId>
+        </dependency>
+        <dependency>
             <groupId>org.osgi</groupId>
             <artifactId>osgi.core</artifactId>
             <scope>provided</scope>
diff --git 
a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelErrorHandlerFactoryBean.java
 
b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelErrorHandlerFactoryBean.java
index de4aa2f..38199df 100644
--- 
a/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelErrorHandlerFactoryBean.java
+++ 
b/components/camel-blueprint/src/main/java/org/apache/camel/blueprint/CamelErrorHandlerFactoryBean.java
@@ -31,7 +31,7 @@ import org.apache.camel.builder.ErrorHandlerBuilder;
 import org.apache.camel.core.xml.AbstractCamelFactoryBean;
 import org.apache.camel.model.RedeliveryPolicyDefinition;
 import org.apache.camel.processor.errorhandler.RedeliveryPolicy;
-import org.apache.camel.reifier.ErrorHandlerReifier;
+import org.apache.camel.reifier.errorhandler.ErrorHandlerReifier;
 import org.osgi.service.blueprint.container.BlueprintContainer;
 
 @XmlRootElement(name = "errorHandler")
diff --git 
a/components/camel-cdi/src/main/java/org/apache/camel/cdi/transaction/JtaTransactionPolicy.java
 
b/components/camel-cdi/src/main/java/org/apache/camel/cdi/transaction/JtaTransactionPolicy.java
index e674b3d..d2dd5ebe 100644
--- 
a/components/camel-cdi/src/main/java/org/apache/camel/cdi/transaction/JtaTransactionPolicy.java
+++ 
b/components/camel-cdi/src/main/java/org/apache/camel/cdi/transaction/JtaTransactionPolicy.java
@@ -26,6 +26,7 @@ import org.apache.camel.builder.ErrorHandlerBuilder;
 import org.apache.camel.builder.ErrorHandlerBuilderRef;
 import org.apache.camel.model.ProcessorDefinition;
 import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.reifier.errorhandler.ErrorHandlerReifier;
 import org.apache.camel.spi.RouteContext;
 import org.apache.camel.spi.TransactedPolicy;
 import org.slf4j.Logger;
@@ -130,7 +131,7 @@ public abstract class JtaTransactionPolicy implements 
TransactedPolicy {
             ErrorHandlerBuilder builder) {
         JtaTransactionErrorHandler answer;
         try {
-            answer = (JtaTransactionErrorHandler) 
builder.createErrorHandler(routeContext, processor);
+            answer = (JtaTransactionErrorHandler) 
ErrorHandlerReifier.reifier(builder).createErrorHandler(routeContext, 
processor);
         } catch (Exception e) {
             throw RuntimeCamelException.wrapRuntimeCamelException(e);
         }
diff --git 
a/components/camel-spring/src/main/java/org/apache/camel/spring/spi/SpringTransactionPolicy.java
 
b/components/camel-spring/src/main/java/org/apache/camel/spring/spi/SpringTransactionPolicy.java
index 362160e..a67b4f3 100644
--- 
a/components/camel-spring/src/main/java/org/apache/camel/spring/spi/SpringTransactionPolicy.java
+++ 
b/components/camel-spring/src/main/java/org/apache/camel/spring/spi/SpringTransactionPolicy.java
@@ -22,6 +22,7 @@ import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.builder.ErrorHandlerBuilder;
 import org.apache.camel.builder.ErrorHandlerBuilderRef;
 import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.reifier.errorhandler.ErrorHandlerReifier;
 import org.apache.camel.spi.RouteContext;
 import org.apache.camel.spi.TransactedPolicy;
 import org.apache.camel.spi.annotations.JdkService;
@@ -124,7 +125,7 @@ public class SpringTransactionPolicy implements 
TransactedPolicy {
     protected TransactionErrorHandler 
createTransactionErrorHandler(RouteContext routeContext, Processor processor, 
ErrorHandlerBuilder builder) {
         TransactionErrorHandler answer;
         try {
-            answer = (TransactionErrorHandler) 
builder.createErrorHandler(routeContext, processor);
+            answer = (TransactionErrorHandler) 
ErrorHandlerReifier.reifier(builder).createErrorHandler(routeContext, 
processor);
         } catch (Exception e) {
             throw RuntimeCamelException.wrapRuntimeCamelException(e);
         }
diff --git 
a/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandlerBuilder.java
 
b/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandlerBuilder.java
index 361f02c..8e2c918 100644
--- 
a/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandlerBuilder.java
+++ 
b/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandlerBuilder.java
@@ -21,6 +21,7 @@ import java.util.Map;
 import org.apache.camel.LoggingLevel;
 import org.apache.camel.Processor;
 import org.apache.camel.builder.DefaultErrorHandlerBuilder;
+import org.apache.camel.reifier.errorhandler.ErrorHandlerReifier;
 import org.apache.camel.spi.CamelLogger;
 import org.apache.camel.spi.RouteContext;
 import org.apache.camel.spi.TransactedPolicy;
@@ -35,6 +36,10 @@ import 
org.springframework.transaction.support.TransactionTemplate;
  */
 public class TransactionErrorHandlerBuilder extends DefaultErrorHandlerBuilder 
{
 
+    static {
+        
ErrorHandlerReifier.registerReifier(TransactionErrorHandlerBuilder.class, 
TransactionErrorHandlerReifier::new);
+    }
+
     private static final Logger LOG = 
LoggerFactory.getLogger(TransactionErrorHandlerBuilder.class);
     private static final String PROPAGATION_REQUIRED = "PROPAGATION_REQUIRED";
     private TransactionTemplate transactionTemplate;
diff --git 
a/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandlerReifier.java
 
b/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandlerReifier.java
new file mode 100644
index 0000000..d50c49c
--- /dev/null
+++ 
b/components/camel-spring/src/main/java/org/apache/camel/spring/spi/TransactionErrorHandlerReifier.java
@@ -0,0 +1,89 @@
+package org.apache.camel.spring.spi;
+
+import java.util.Map;
+
+import org.apache.camel.ErrorHandlerFactory;
+import org.apache.camel.Processor;
+import org.apache.camel.reifier.errorhandler.DefaultErrorHandlerReifier;
+import org.apache.camel.spi.RouteContext;
+import org.apache.camel.spi.TransactedPolicy;
+import org.apache.camel.util.ObjectHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.support.TransactionTemplate;
+
+import static org.apache.camel.model.TransactedDefinition.PROPAGATION_REQUIRED;
+
+public class TransactionErrorHandlerReifier extends 
DefaultErrorHandlerReifier<TransactionErrorHandlerBuilder> {
+
+    private static final Logger LOG = 
LoggerFactory.getLogger(TransactionErrorHandlerReifier.class);
+
+    public TransactionErrorHandlerReifier(ErrorHandlerFactory definition) {
+        super(definition);
+    }
+
+    public Processor createErrorHandler(RouteContext routeContext, Processor 
processor) throws Exception {
+        TransactionTemplate transactionTemplate = 
definition.getTransactionTemplate();
+        if (transactionTemplate == null) {
+            // lookup in context if no transaction template has been configured
+            LOG.debug("No TransactionTemplate configured on 
TransactionErrorHandlerBuilder. Will try find it in the registry.");
+
+            Map<String, TransactedPolicy> mapPolicy = 
routeContext.lookupByType(TransactedPolicy.class);
+            if (mapPolicy != null && mapPolicy.size() == 1) {
+                TransactedPolicy policy = mapPolicy.values().iterator().next();
+                if (policy instanceof SpringTransactionPolicy) {
+                    transactionTemplate = ((SpringTransactionPolicy) 
policy).getTransactionTemplate();
+                }
+            }
+
+            if (transactionTemplate == null) {
+                TransactedPolicy policy = 
routeContext.lookup(PROPAGATION_REQUIRED, TransactedPolicy.class);
+                if (policy instanceof SpringTransactionPolicy) {
+                    transactionTemplate = ((SpringTransactionPolicy) 
policy).getTransactionTemplate();
+                }
+            }
+
+            if (transactionTemplate == null) {
+                Map<String, TransactionTemplate> mapTemplate = 
routeContext.lookupByType(TransactionTemplate.class);
+                if (mapTemplate == null || mapTemplate.isEmpty()) {
+                    LOG.trace("No TransactionTemplate found in registry.");
+                } else if (mapTemplate.size() == 1) {
+                    transactionTemplate = 
mapTemplate.values().iterator().next();
+                } else {
+                    LOG.debug("Found {} TransactionTemplate in registry. 
Cannot determine which one to use. "
+                            + "Please configure a TransactionTemplate on the 
TransactionErrorHandlerBuilder", mapTemplate.size());
+                }
+            }
+
+            if (transactionTemplate == null) {
+                Map<String, PlatformTransactionManager> mapManager = 
routeContext.lookupByType(PlatformTransactionManager.class);
+                if (mapManager == null || mapManager.isEmpty()) {
+                    LOG.trace("No PlatformTransactionManager found in 
registry.");
+                } else if (mapManager.size() == 1) {
+                    transactionTemplate = new 
TransactionTemplate(mapManager.values().iterator().next());
+                } else {
+                    LOG.debug("Found {} PlatformTransactionManager in 
registry. Cannot determine which one to use for TransactionTemplate. "
+                            + "Please configure a TransactionTemplate on the 
TransactionErrorHandlerBuilder", mapManager.size());
+                }
+            }
+
+            if (transactionTemplate != null) {
+                LOG.debug("Found TransactionTemplate in registry to use: {}", 
transactionTemplate);
+            }
+        }
+
+        ObjectHelper.notNull(transactionTemplate, "transactionTemplate", this);
+
+        TransactionErrorHandler answer = new 
TransactionErrorHandler(routeContext.getCamelContext(), processor,
+                definition.getLogger(), definition.getOnRedelivery(),
+                definition.getRedeliveryPolicy(), 
definition.getExceptionPolicyStrategy(), transactionTemplate,
+                definition.getRetryWhilePolicy(routeContext.getCamelContext()),
+                getExecutorService(routeContext.getCamelContext()),
+                definition.getRollbackLoggingLevel(), 
definition.getOnExceptionOccurred());
+        // configure error handler before we can use it
+        configure(routeContext, answer);
+        return answer;
+    }
+
+}
diff --git 
a/core/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java
 
b/core/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java
index cd6b982..768f63c 100644
--- 
a/core/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java
+++ 
b/core/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java
@@ -521,6 +521,14 @@ public class DefaultErrorHandlerBuilder extends 
ErrorHandlerBuilderSupport {
         this.asyncDelayedRedelivery = asyncDelayedRedelivery;
     }
 
+    public ScheduledExecutorService getExecutorService() {
+        return executorService;
+    }
+
+    public void setExecutorService(ScheduledExecutorService executorService) {
+        this.executorService = executorService;
+    }
+
     public String getExecutorServiceRef() {
         return executorServiceRef;
     }
diff --git 
a/core/camel-core/src/main/java/org/apache/camel/builder/ErrorHandlerBuilderRef.java
 
b/core/camel-core/src/main/java/org/apache/camel/builder/ErrorHandlerBuilderRef.java
index d292f0e..27e4c42 100644
--- 
a/core/camel-core/src/main/java/org/apache/camel/builder/ErrorHandlerBuilderRef.java
+++ 
b/core/camel-core/src/main/java/org/apache/camel/builder/ErrorHandlerBuilderRef.java
@@ -26,6 +26,7 @@ import org.apache.camel.ExtendedCamelContext;
 import org.apache.camel.Processor;
 import org.apache.camel.model.OnExceptionDefinition;
 import org.apache.camel.model.RouteDefinition;
+import org.apache.camel.reifier.errorhandler.ErrorHandlerReifier;
 import org.apache.camel.spi.RouteContext;
 import org.apache.camel.util.ObjectHelper;
 
@@ -65,7 +66,7 @@ public class ErrorHandlerBuilderRef extends 
ErrorHandlerBuilderSupport {
 
     public Processor createErrorHandler(RouteContext routeContext, Processor 
processor) throws Exception {
         ErrorHandlerFactory handler = handlers.computeIfAbsent(routeContext, 
this::createErrorHandler);
-        return handler.createErrorHandler(routeContext, processor);
+        return 
ErrorHandlerReifier.reifier(handler).createErrorHandler(routeContext, 
processor);
     }
 
     public boolean supportTransacted() {
diff --git 
a/core/camel-core/src/main/java/org/apache/camel/builder/ErrorHandlerBuilderSupport.java
 
b/core/camel-core/src/main/java/org/apache/camel/builder/ErrorHandlerBuilderSupport.java
index bd951a8..217351d 100644
--- 
a/core/camel-core/src/main/java/org/apache/camel/builder/ErrorHandlerBuilderSupport.java
+++ 
b/core/camel-core/src/main/java/org/apache/camel/builder/ErrorHandlerBuilderSupport.java
@@ -21,11 +21,19 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.camel.Predicate;
+import org.apache.camel.Processor;
+import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.model.OnExceptionDefinition;
+import org.apache.camel.model.ProcessorDefinitionHelper;
+import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.processor.ErrorHandler;
 import org.apache.camel.processor.errorhandler.ErrorHandlerSupport;
 import org.apache.camel.processor.errorhandler.RedeliveryErrorHandler;
+import org.apache.camel.processor.exceptionpolicy.ExceptionPolicy;
+import org.apache.camel.processor.exceptionpolicy.ExceptionPolicyKey;
 import org.apache.camel.processor.exceptionpolicy.ExceptionPolicyStrategy;
+import org.apache.camel.spi.ClassResolver;
 import org.apache.camel.spi.RouteContext;
 import org.apache.camel.util.ObjectHelper;
 
@@ -46,8 +54,7 @@ public abstract class ErrorHandlerBuilderSupport implements 
ErrorHandlerBuilder
 
     protected void cloneBuilder(ErrorHandlerBuilderSupport other) {
         if (!onExceptions.isEmpty()) {
-            Map<RouteContext, List<OnExceptionDefinition>> copy = new 
HashMap<>(onExceptions);
-            other.onExceptions = copy;
+            other.onExceptions.putAll(onExceptions);
         }
         other.exceptionPolicyStrategy = exceptionPolicyStrategy;
     }
@@ -59,7 +66,7 @@ public abstract class ErrorHandlerBuilderSupport implements 
ErrorHandlerBuilder
             List<OnExceptionDefinition> list = onExceptions.get(routeContext);
             if (list != null) {
                 for (OnExceptionDefinition exception : list) {
-                    handlerSupport.addExceptionPolicy(routeContext, exception);
+                    addExceptionPolicy(handlerSupport, routeContext, 
exception);
                 }
             }
         }
@@ -72,6 +79,52 @@ public abstract class ErrorHandlerBuilderSupport implements 
ErrorHandlerBuilder
         }
     }
 
+    public static void addExceptionPolicy(ErrorHandlerSupport handlerSupport, 
RouteContext routeContext, OnExceptionDefinition exceptionType) {
+        if (routeContext != null) {
+            // add error handler as child service so they get lifecycle handled
+            Processor errorHandler = 
routeContext.getOnException(exceptionType.getId());
+            handlerSupport.addErrorHandler(errorHandler);
+
+            // load exception classes
+            List<Class<? extends Throwable>> list;
+            if (exceptionType.getExceptions() != null && 
!exceptionType.getExceptions().isEmpty()) {
+                list = createExceptionClasses(exceptionType, 
routeContext.getCamelContext().getClassResolver());
+                for (Class<? extends Throwable> clazz : list) {
+                    String routeId = null;
+                    // only get the route id, if the exception type is route 
scoped
+                    if (exceptionType.isRouteScoped()) {
+                        RouteDefinition route = 
ProcessorDefinitionHelper.getRoute(exceptionType);
+                        if (route != null) {
+                            routeId = route.getId();
+                        }
+                    }
+                    Predicate when = exceptionType.getOnWhen() != null ? 
exceptionType.getOnWhen().getExpression() : null;
+                    ExceptionPolicyKey key = new ExceptionPolicyKey(routeId, 
clazz, when);
+                    ExceptionPolicy policy = toExceptionPolicy(exceptionType);
+                    handlerSupport.addExceptionPolicy(key, policy);
+                }
+            }
+        }
+    }
+
+    protected static ExceptionPolicy toExceptionPolicy(OnExceptionDefinition 
exceptionType) {
+        return new ExceptionPolicy(exceptionType);
+    }
+
+    protected static List<Class<? extends Throwable>> 
createExceptionClasses(OnExceptionDefinition exceptionType, ClassResolver 
resolver) {
+        List<String> list = exceptionType.getExceptions();
+        List<Class<? extends Throwable>> answer = new ArrayList<>(list.size());
+        for (String name : list) {
+            try {
+                Class<? extends Throwable> type = 
resolver.resolveMandatoryClass(name, Throwable.class);
+                answer.add(type);
+            } catch (ClassNotFoundException e) {
+                throw RuntimeCamelException.wrapRuntimeCamelException(e);
+            }
+        }
+        return answer;
+    }
+
     public List<OnExceptionDefinition> getErrorHandlers(RouteContext 
routeContext) {
         return onExceptions.get(routeContext);
     }
@@ -112,4 +165,7 @@ public abstract class ErrorHandlerBuilderSupport implements 
ErrorHandlerBuilder
         return false;
     }
 
+    public Map<RouteContext, List<OnExceptionDefinition>> getOnExceptions() {
+        return onExceptions;
+    }
 }
diff --git 
a/core/camel-core/src/main/java/org/apache/camel/processor/errorhandler/ErrorHandlerSupport.java
 
b/core/camel-core/src/main/java/org/apache/camel/processor/errorhandler/ErrorHandlerSupport.java
index dfa1ebc..5f8a45f 100644
--- 
a/core/camel-core/src/main/java/org/apache/camel/processor/errorhandler/ErrorHandlerSupport.java
+++ 
b/core/camel-core/src/main/java/org/apache/camel/processor/errorhandler/ErrorHandlerSupport.java
@@ -16,23 +16,16 @@
  */
 package org.apache.camel.processor.errorhandler;
 
-import java.util.ArrayList;
 import java.util.LinkedHashMap;
-import java.util.List;
 import java.util.Map;
 
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
-import org.apache.camel.RuntimeCamelException;
-import org.apache.camel.model.OnExceptionDefinition;
-import org.apache.camel.model.ProcessorDefinitionHelper;
-import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.processor.ErrorHandler;
 import 
org.apache.camel.processor.exceptionpolicy.DefaultExceptionPolicyStrategy;
+import org.apache.camel.processor.exceptionpolicy.ExceptionPolicy;
 import org.apache.camel.processor.exceptionpolicy.ExceptionPolicyKey;
 import org.apache.camel.processor.exceptionpolicy.ExceptionPolicyStrategy;
-import org.apache.camel.spi.ClassResolver;
-import org.apache.camel.spi.RouteContext;
 import org.apache.camel.support.ChildServiceSupport;
 
 /**
@@ -40,59 +33,25 @@ import org.apache.camel.support.ChildServiceSupport;
  */
 public abstract class ErrorHandlerSupport extends ChildServiceSupport 
implements ErrorHandler {
 
-    protected final Map<ExceptionPolicyKey, OnExceptionDefinition> 
exceptionPolicies = new LinkedHashMap<>();
+    protected final Map<ExceptionPolicyKey, ExceptionPolicy> exceptionPolicies 
= new LinkedHashMap<>();
     protected ExceptionPolicyStrategy exceptionPolicy = 
createDefaultExceptionPolicyStrategy();
 
-    public void addExceptionPolicy(RouteContext routeContext, 
OnExceptionDefinition exceptionType) {
-        if (routeContext != null) {
-            // add error handler as child service so they get lifecycle handled
-            Processor errorHandler = 
routeContext.getOnException(exceptionType.getId());
-            if (errorHandler != null) {
-                addChildService(errorHandler);
-            }
-
-            // load exception classes
-            List<Class<? extends Throwable>> list = null;
-            if (exceptionType.getExceptions() != null && 
!exceptionType.getExceptions().isEmpty()) {
-                list = createExceptionClasses(exceptionType, 
routeContext.getCamelContext().getClassResolver());
-                for (Class<? extends Throwable> clazz : list) {
-                    String routeId = null;
-                    // only get the route id, if the exception type is route 
scoped
-                    if (exceptionType.isRouteScoped()) {
-                        RouteDefinition route = 
ProcessorDefinitionHelper.getRoute(exceptionType);
-                        if (route != null) {
-                            routeId = route.getId();
-                        }
-                    }
-                    ExceptionPolicyKey key = new ExceptionPolicyKey(routeId, 
clazz, exceptionType.getOnWhen());
-                    exceptionPolicies.put(key, exceptionType);
-                }
-            }
-        }
+    public void addErrorHandler(Processor errorHandler) {
+        addChildService(errorHandler);
     }
 
-    protected List<Class<? extends Throwable>> 
createExceptionClasses(OnExceptionDefinition exceptionType, ClassResolver 
resolver) {
-        List<String> list = exceptionType.getExceptions();
-        List<Class<? extends Throwable>> answer = new ArrayList<>(list.size());
-        for (String name : list) {
-            try {
-                Class<? extends Throwable> type = 
resolver.resolveMandatoryClass(name, Throwable.class);
-                answer.add(type);
-            } catch (ClassNotFoundException e) {
-                throw RuntimeCamelException.wrapRuntimeCamelException(e);
-            }
-        }
-        return answer;
+    public void addExceptionPolicy(ExceptionPolicyKey key, ExceptionPolicy 
policy) {
+        exceptionPolicies.put(key, policy);
     }
 
     /**
-     * Attempts to find the best suited {@link OnExceptionDefinition} to be 
used for handling the given thrown exception.
+     * Attempts to find the best suited {@link ExceptionPolicy} to be used for 
handling the given thrown exception.
      *
      * @param exchange  the exchange
      * @param exception the exception that was thrown
      * @return the best exception type to handle this exception, <tt>null</tt> 
if none found.
      */
-    protected OnExceptionDefinition getExceptionPolicy(Exchange exchange, 
Throwable exception) {
+    protected ExceptionPolicy getExceptionPolicy(Exchange exchange, Throwable 
exception) {
         if (exceptionPolicy == null) {
             throw new IllegalStateException("The exception policy has not been 
set");
         }
@@ -101,7 +60,7 @@ public abstract class ErrorHandlerSupport extends 
ChildServiceSupport implements
     }
 
     /**
-     * Sets the strategy to use for resolving the {@link 
OnExceptionDefinition} to use
+     * Sets the strategy to use for resolving the {@link ExceptionPolicy} to 
use
      * for handling thrown exceptions.
      */
     public void setExceptionPolicy(ExceptionPolicyStrategy exceptionPolicy) {
diff --git 
a/core/camel-core/src/main/java/org/apache/camel/processor/errorhandler/RedeliveryErrorHandler.java
 
b/core/camel-core/src/main/java/org/apache/camel/processor/errorhandler/RedeliveryErrorHandler.java
index 754c990..17d5423 100644
--- 
a/core/camel-core/src/main/java/org/apache/camel/processor/errorhandler/RedeliveryErrorHandler.java
+++ 
b/core/camel-core/src/main/java/org/apache/camel/processor/errorhandler/RedeliveryErrorHandler.java
@@ -36,8 +36,7 @@ import org.apache.camel.Navigate;
 import org.apache.camel.Predicate;
 import org.apache.camel.Processor;
 import org.apache.camel.RuntimeCamelException;
-import org.apache.camel.model.OnExceptionDefinition;
-import org.apache.camel.reifier.ErrorHandlerReifier;
+import org.apache.camel.processor.exceptionpolicy.ExceptionPolicy;
 import org.apache.camel.spi.AsyncProcessorAwaitManager;
 import org.apache.camel.spi.CamelLogger;
 import org.apache.camel.spi.ExchangeFormatter;
@@ -664,13 +663,13 @@ public abstract class RedeliveryErrorHandler extends 
ErrorHandlerSupport impleme
             exchange.setProperty(Exchange.EXCEPTION_CAUGHT, e);
 
             // find the error handler to use (if any)
-            OnExceptionDefinition exceptionPolicy = 
getExceptionPolicy(exchange, e);
+            ExceptionPolicy exceptionPolicy = getExceptionPolicy(exchange, e);
             if (exceptionPolicy != null) {
-                currentRedeliveryPolicy = 
ErrorHandlerReifier.createRedeliveryPolicy(exceptionPolicy, 
exchange.getContext(), currentRedeliveryPolicy);
+                currentRedeliveryPolicy = 
exceptionPolicy.createRedeliveryPolicy(exchange.getContext(), 
currentRedeliveryPolicy);
                 handledPredicate = exceptionPolicy.getHandledPolicy();
                 continuedPredicate = exceptionPolicy.getContinuedPolicy();
                 retryWhilePredicate = exceptionPolicy.getRetryWhilePolicy();
-                useOriginalInMessage = 
exceptionPolicy.getUseOriginalMessagePolicy() != null && 
exceptionPolicy.getUseOriginalMessagePolicy();
+                useOriginalInMessage = 
exceptionPolicy.getUseOriginalInMessage();
 
                 // route specific failure handler?
                 Processor processor = null;
@@ -1245,25 +1244,8 @@ public abstract class RedeliveryErrorHandler extends 
ErrorHandlerSupport impleme
         // or on the exception policies
         if (!exceptionPolicies.isEmpty()) {
             // walk them to see if any of them have a maximum redeliveries > 0 
or retry until set
-            for (OnExceptionDefinition def : exceptionPolicies.values()) {
-
-                String ref = def.getRedeliveryPolicyRef();
-                if (ref != null) {
-                    // lookup in registry if ref provided
-                    RedeliveryPolicy policy = 
CamelContextHelper.mandatoryLookup(camelContext, ref, RedeliveryPolicy.class);
-                    if (policy.getMaximumRedeliveries() != 0) {
-                        // must check for != 0 as (-1 means redeliver forever)
-                        return true;
-                    }
-                } else if (def.getRedeliveryPolicyType() != null) {
-                    Integer max = 
CamelContextHelper.parseInteger(camelContext, 
def.getRedeliveryPolicyType().getMaximumRedeliveries());
-                    if (max != null && max != 0) {
-                        // must check for != 0 as (-1 means redeliver forever)
-                        return true;
-                    }
-                }
-
-                if (def.getRetryWhilePolicy() != null || def.getRetryWhile() 
!= null) {
+            for (ExceptionPolicy def : exceptionPolicies.values()) {
+                if (def.determineIfRedeliveryIsEnabled(camelContext)) {
                     return true;
                 }
             }
diff --git 
a/core/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategy.java
 
b/core/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategy.java
index 948d05a..3c5b660 100644
--- 
a/core/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategy.java
+++ 
b/core/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategy.java
@@ -23,15 +23,12 @@ import java.util.Set;
 import java.util.TreeMap;
 
 import org.apache.camel.Exchange;
-import org.apache.camel.model.OnExceptionDefinition;
-import org.apache.camel.model.ProcessorDefinitionHelper;
-import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.util.ObjectHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * The default strategy used in Camel to resolve the {@link 
org.apache.camel.model.OnExceptionDefinition} that should
+ * The default strategy used in Camel to resolve the {@link ExceptionPolicy} 
that should
  * handle the thrown exception.
  * <p/>
  * <b>Selection strategy:</b>
@@ -41,7 +38,7 @@ import org.slf4j.LoggerFactory;
  * by is selected first, ending with the thrown exception itself. The method 
{@link #createExceptionIterator(Throwable)}
  * provides the Iterator used for the walking.</li>
  * <li>The exception type must be configured with an Exception that is an 
instance of the thrown exception, this
- * is tested using the {@link 
#filter(org.apache.camel.model.OnExceptionDefinition, Class, Throwable)} method.
+ * is tested using the {@link #filter(ExceptionPolicy, Class, Throwable)} 
method.
  * By default the filter uses <tt>instanceof</tt> test.</li>
  * <li>If the exception type has <b>exactly</b> the thrown exception then its 
selected as its an exact match</li>
  * <li>Otherwise the type that has an exception that is the closest super of 
the thrown exception is selected
@@ -49,8 +46,8 @@ import org.slf4j.LoggerFactory;
  * </ul>
  * <p/>
  * <b>Fine grained matching:</b>
- * <br/> If the {@link OnExceptionDefinition} has a when defined with an 
expression the type is also matches against
- * the current exchange using the {@link 
#matchesWhen(org.apache.camel.model.OnExceptionDefinition, 
org.apache.camel.Exchange)}
+ * <br/> If the {@link ExceptionPolicy} has a when defined with an expression 
the type is also matches against
+ * the current exchange using the {@link #matchesWhen(ExceptionPolicy, 
org.apache.camel.Exchange)}
  * method. This can be used to for more fine grained matching, so you can e.g. 
define multiple sets of
  * exception types with the same exception class(es) but have a predicate 
attached to select which to select at runtime.
  */
@@ -58,12 +55,12 @@ public class DefaultExceptionPolicyStrategy implements 
ExceptionPolicyStrategy {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(DefaultExceptionPolicyStrategy.class);
 
-    public OnExceptionDefinition getExceptionPolicy(Map<ExceptionPolicyKey, 
OnExceptionDefinition> exceptionPolicies,
-                                                    Exchange exchange, 
Throwable exception) {
+    public ExceptionPolicy getExceptionPolicy(Map<ExceptionPolicyKey, 
ExceptionPolicy> exceptionPolicies,
+                                              Exchange exchange, Throwable 
exception) {
 
-        Map<Integer, OnExceptionDefinition> candidates = new TreeMap<>();
-        Map<ExceptionPolicyKey, OnExceptionDefinition> routeScoped = new 
LinkedHashMap<>();
-        Map<ExceptionPolicyKey, OnExceptionDefinition> contextScoped = new 
LinkedHashMap<>();
+        Map<Integer, ExceptionPolicy> candidates = new TreeMap<>();
+        Map<ExceptionPolicyKey, ExceptionPolicy> routeScoped = new 
LinkedHashMap<>();
+        Map<ExceptionPolicyKey, ExceptionPolicy> contextScoped = new 
LinkedHashMap<>();
 
         // split policies into route and context scoped
         initRouteAndContextScopedExceptionPolicies(exceptionPolicies, 
routeScoped, contextScoped);
@@ -96,13 +93,13 @@ public class DefaultExceptionPolicyStrategy implements 
ExceptionPolicyStrategy {
         }
     }
 
-    private void 
initRouteAndContextScopedExceptionPolicies(Map<ExceptionPolicyKey, 
OnExceptionDefinition> exceptionPolicies,
-                                                            
Map<ExceptionPolicyKey, OnExceptionDefinition> routeScoped,
-                                                            
Map<ExceptionPolicyKey, OnExceptionDefinition> contextScoped) {
+    private void 
initRouteAndContextScopedExceptionPolicies(Map<ExceptionPolicyKey, 
ExceptionPolicy> exceptionPolicies,
+                                                            
Map<ExceptionPolicyKey, ExceptionPolicy> routeScoped,
+                                                            
Map<ExceptionPolicyKey, ExceptionPolicy> contextScoped) {
 
         // loop through all the entries and split into route and context scoped
-        Set<Map.Entry<ExceptionPolicyKey, OnExceptionDefinition>> entries = 
exceptionPolicies.entrySet();
-        for (Map.Entry<ExceptionPolicyKey, OnExceptionDefinition> entry : 
entries) {
+        Set<Map.Entry<ExceptionPolicyKey, ExceptionPolicy>> entries = 
exceptionPolicies.entrySet();
+        for (Map.Entry<ExceptionPolicyKey, ExceptionPolicy> entry : entries) {
             if (entry.getKey().getRouteId() != null) {
                 routeScoped.put(entry.getKey(), entry.getValue());
             } else {
@@ -112,9 +109,9 @@ public class DefaultExceptionPolicyStrategy implements 
ExceptionPolicyStrategy {
     }
 
 
-    private boolean findMatchedExceptionPolicy(Map<ExceptionPolicyKey, 
OnExceptionDefinition> exceptionPolicies,
+    private boolean findMatchedExceptionPolicy(Map<ExceptionPolicyKey, 
ExceptionPolicy> exceptionPolicies,
                                                Exchange exchange, Throwable 
exception,
-                                               Map<Integer, 
OnExceptionDefinition> candidates) {
+                                               Map<Integer, ExceptionPolicy> 
candidates) {
         if (LOG.isTraceEnabled()) {
             LOG.trace("Finding best suited exception policy for thrown 
exception {}", exception.getClass().getName());
         }
@@ -122,21 +119,21 @@ public class DefaultExceptionPolicyStrategy implements 
ExceptionPolicyStrategy {
         // the goal is to find the exception with the same/closet inheritance 
level as the target exception being thrown
         int targetLevel = getInheritanceLevel(exception.getClass());
         // candidate is the best candidate found so far to return
-        OnExceptionDefinition candidate = null;
+        ExceptionPolicy candidate = null;
         // difference in inheritance level between the current candidate and 
the thrown exception (target level)
         int candidateDiff = Integer.MAX_VALUE;
 
         // loop through all the entries and find the best candidates to use
-        Set<Map.Entry<ExceptionPolicyKey, OnExceptionDefinition>> entries = 
exceptionPolicies.entrySet();
-        for (Map.Entry<ExceptionPolicyKey, OnExceptionDefinition> entry : 
entries) {
+        Set<Map.Entry<ExceptionPolicyKey, ExceptionPolicy>> entries = 
exceptionPolicies.entrySet();
+        for (Map.Entry<ExceptionPolicyKey, ExceptionPolicy> entry : entries) {
             Class<?> clazz = entry.getKey().getExceptionClass();
-            OnExceptionDefinition type = entry.getValue();
+            ExceptionPolicy type = entry.getValue();
 
-            // if OnException is route scoped then the current route 
(Exchange) must match
-            // so we will not pick an OnException from another route
+            // if ExceptionPolicy is route scoped then the current route 
(Exchange) must match
+            // so we will not pick an ExceptionPolicy from another route
             if (exchange != null && exchange.getUnitOfWork() != null && 
type.isRouteScoped()) {
                 String route = exchange.getUnitOfWork().getRouteContext() != 
null ? exchange.getUnitOfWork().getRouteContext().getRouteId() : null;
-                String typeRoute = ProcessorDefinitionHelper.getRouteId(type);
+                String typeRoute = type.getRouteId();
                 if (route != null && typeRoute != null && 
!route.equals(typeRoute)) {
                     if (LOG.isTraceEnabled()) {
                         LOG.trace("The type is scoped for route: {} however 
Exchange is at route: {}", typeRoute, route);
@@ -203,7 +200,7 @@ public class DefaultExceptionPolicyStrategy implements 
ExceptionPolicyStrategy {
      * @param exception      the thrown exception
      * @return <tt>true</tt> if the to current exception class is a candidate, 
<tt>false</tt> to skip it.
      */
-    protected boolean filter(OnExceptionDefinition type, Class<?> 
exceptionClass, Throwable exception) {
+    protected boolean filter(ExceptionPolicy type, Class<?> exceptionClass, 
Throwable exception) {
         // must be instance of check to ensure that the exceptionClass is one 
type of the thrown exception
         return exceptionClass.isInstance(exception);
     }
@@ -221,17 +218,17 @@ public class DefaultExceptionPolicyStrategy implements 
ExceptionPolicyStrategy {
      * @param exchange the current {@link Exchange}
      * @return <tt>true</tt> if matched, <tt>false</tt> otherwise.
      */
-    protected boolean matchesWhen(OnExceptionDefinition definition, Exchange 
exchange) {
-        if (definition.getOnWhen() == null || 
definition.getOnWhen().getExpression() == null) {
+    protected boolean matchesWhen(ExceptionPolicy definition, Exchange 
exchange) {
+        if (definition.getOnWhen() == null || definition.getOnWhen() == null) {
             // if no predicate then it's always a match
             return true;
         }
-        return definition.getOnWhen().getExpression().matches(exchange);
+        return definition.getOnWhen().matches(exchange);
     }
 
     /**
      * Strategy method creating the iterator to walk the exception in the 
order Camel should use
-     * for find the {@link OnExceptionDefinition} should be used.
+     * for find the {@link ExceptionPolicy} should be used.
      * <p/>
      * The default iterator will walk from the bottom upwards
      * (the last caused by going upwards to the exception)
diff --git 
a/core/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/ExceptionPolicy.java
 
b/core/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/ExceptionPolicy.java
new file mode 100644
index 0000000..cb0cecd
--- /dev/null
+++ 
b/core/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/ExceptionPolicy.java
@@ -0,0 +1,85 @@
+package org.apache.camel.processor.exceptionpolicy;
+
+import java.util.List;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Predicate;
+import org.apache.camel.Processor;
+import org.apache.camel.model.OnExceptionDefinition;
+import org.apache.camel.model.ProcessorDefinitionHelper;
+import org.apache.camel.model.RedeliveryPolicyDefinition;
+import org.apache.camel.processor.errorhandler.RedeliveryPolicy;
+import org.apache.camel.reifier.errorhandler.ErrorHandlerReifier;
+
+public class ExceptionPolicy {
+
+    private final OnExceptionDefinition def;
+
+    public ExceptionPolicy(OnExceptionDefinition def) {
+        this.def = def;
+    }
+
+    public String getId() {
+        return def.getId();
+    }
+
+    public String getRouteId() {
+        return ProcessorDefinitionHelper.getRouteId(def);
+    }
+
+    public boolean isRouteScoped() {
+        return def.getRouteScoped() != null && def.getRouteScoped();
+    }
+
+    public Predicate getOnWhen() {
+        return def.getOnWhen() != null ? def.getOnWhen().getExpression() : 
null;
+    }
+
+    public String getRedeliveryPolicyRef() {
+        return def.getRedeliveryPolicyRef();
+    }
+
+    public boolean hasOutputs() {
+        return def.getOutputs() != null && !def.getOutputs().isEmpty();
+    }
+
+    public RedeliveryPolicyDefinition getRedeliveryPolicyType() {
+        return def.getRedeliveryPolicyType();
+    }
+
+    public Predicate getHandledPolicy() {
+        return def.getHandledPolicy();
+    }
+
+    public Predicate getContinuedPolicy() {
+        return def.getContinuedPolicy();
+    }
+
+    public Predicate getRetryWhilePolicy() {
+        return def.getRetryWhilePolicy();
+    }
+
+    public boolean getUseOriginalInMessage() {
+        return def.getUseOriginalMessagePolicy() != null && 
def.getUseOriginalMessagePolicy();
+    }
+
+    public Processor getOnRedelivery() {
+        return def.getOnRedelivery();
+    }
+
+    public Processor getOnExceptionOccurred() {
+        return def.getOnExceptionOccurred();
+    }
+
+    public List<String> getExceptions() {
+        return def.getExceptions();
+    }
+
+    public boolean determineIfRedeliveryIsEnabled(CamelContext context) throws 
Exception {
+        return ErrorHandlerReifier.determineIfRedeliveryIsEnabled(this, 
context);
+    }
+
+    public RedeliveryPolicy createRedeliveryPolicy(CamelContext context, 
RedeliveryPolicy parent) {
+        return ErrorHandlerReifier.createRedeliveryPolicy(this, context, 
parent);
+    }
+}
diff --git 
a/core/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/ExceptionPolicyKey.java
 
b/core/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/ExceptionPolicyKey.java
index f564cbe..8efdf59 100644
--- 
a/core/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/ExceptionPolicyKey.java
+++ 
b/core/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/ExceptionPolicyKey.java
@@ -16,7 +16,7 @@
  */
 package org.apache.camel.processor.exceptionpolicy;
 
-import org.apache.camel.model.WhenDefinition;
+import org.apache.camel.Predicate;
 
 /**
  * Exception policy key is a compound key for storing:
@@ -28,7 +28,7 @@ public final class ExceptionPolicyKey {
 
     private final String routeId;
     private final Class<? extends Throwable> exceptionClass;
-    private final WhenDefinition when;
+    private final Predicate when;
 
     /**
      * Key for exception clause
@@ -37,7 +37,7 @@ public final class ExceptionPolicyKey {
      * @param exceptionClass   the exception class
      * @param when             optional predicate when the exception clause 
should trigger
      */
-    public ExceptionPolicyKey(String routeId, Class<? extends Throwable> 
exceptionClass, WhenDefinition when) {
+    public ExceptionPolicyKey(String routeId, Class<? extends Throwable> 
exceptionClass, Predicate when) {
         this.routeId = routeId;
         this.exceptionClass = exceptionClass;
         this.when = when;
@@ -47,7 +47,7 @@ public final class ExceptionPolicyKey {
         return exceptionClass;
     }
 
-    public WhenDefinition getWhen() {
+    public Predicate getWhen() {
         return when;
     }
 
diff --git 
a/core/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/ExceptionPolicyStrategy.java
 
b/core/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/ExceptionPolicyStrategy.java
index b192e71..482085a 100644
--- 
a/core/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/ExceptionPolicyStrategy.java
+++ 
b/core/camel-core/src/main/java/org/apache/camel/processor/exceptionpolicy/ExceptionPolicyStrategy.java
@@ -19,10 +19,9 @@ package org.apache.camel.processor.exceptionpolicy;
 import java.util.Map;
 
 import org.apache.camel.Exchange;
-import org.apache.camel.model.OnExceptionDefinition;
 
 /**
- * A strategy to determine which {@link 
org.apache.camel.model.OnExceptionDefinition} should handle the thrown
+ * A strategy to determine which {@link ExceptionPolicy} should handle the 
thrown
  * exception.
  *
  * @see 
org.apache.camel.processor.exceptionpolicy.DefaultExceptionPolicyStrategy 
DefaultExceptionPolicy
@@ -30,14 +29,14 @@ import org.apache.camel.model.OnExceptionDefinition;
 public interface ExceptionPolicyStrategy {
 
     /**
-     * Resolves the {@link org.apache.camel.model.OnExceptionDefinition} that 
should handle the thrown exception.
+     * Resolves the {@link ExceptionPolicy} that should handle the thrown 
exception.
      *
      * @param exceptionPolicies the configured exception policies to resolve 
from
      * @param exchange           the exchange
      * @param exception          the exception that was thrown
      * @return the resolved exception type to handle this exception, 
<tt>null</tt> if none found.
      */
-    OnExceptionDefinition getExceptionPolicy(Map<ExceptionPolicyKey, 
OnExceptionDefinition> exceptionPolicies,
-                                             Exchange exchange, Throwable 
exception);
+    ExceptionPolicy getExceptionPolicy(Map<ExceptionPolicyKey, 
ExceptionPolicy> exceptionPolicies,
+                                       Exchange exchange, Throwable exception);
 
 }
diff --git 
a/core/camel-core/src/main/java/org/apache/camel/reifier/DynamicRouterReifier.java
 
b/core/camel-core/src/main/java/org/apache/camel/reifier/DynamicRouterReifier.java
index 04eee55..f030abd 100644
--- 
a/core/camel-core/src/main/java/org/apache/camel/reifier/DynamicRouterReifier.java
+++ 
b/core/camel-core/src/main/java/org/apache/camel/reifier/DynamicRouterReifier.java
@@ -24,6 +24,7 @@ import org.apache.camel.model.DynamicRouterDefinition;
 import org.apache.camel.model.ProcessorDefinition;
 import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.processor.DynamicRouter;
+import org.apache.camel.reifier.errorhandler.ErrorHandlerReifier;
 import org.apache.camel.spi.RouteContext;
 
 class DynamicRouterReifier extends 
ExpressionReifier<DynamicRouterDefinition<?>> {
@@ -49,7 +50,7 @@ class DynamicRouterReifier extends 
ExpressionReifier<DynamicRouterDefinition<?>>
         ErrorHandlerFactory builder = routeContext.getErrorHandlerFactory();
         // create error handler (create error handler directly to keep it 
light weight,
         // instead of using ProcessorDefinition.wrapInErrorHandler)
-        AsyncProcessor errorHandler = (AsyncProcessor) 
builder.createErrorHandler(routeContext, 
dynamicRouter.newRoutingSlipProcessorForErrorHandler());
+        AsyncProcessor errorHandler = (AsyncProcessor) 
ErrorHandlerReifier.reifier(builder).createErrorHandler(routeContext, 
dynamicRouter.newRoutingSlipProcessorForErrorHandler());
         dynamicRouter.setErrorHandler(errorHandler);
 
         return dynamicRouter;
diff --git 
a/core/camel-core/src/main/java/org/apache/camel/reifier/OnExceptionReifier.java
 
b/core/camel-core/src/main/java/org/apache/camel/reifier/OnExceptionReifier.java
index 98d19f8..82e5ec7 100644
--- 
a/core/camel-core/src/main/java/org/apache/camel/reifier/OnExceptionReifier.java
+++ 
b/core/camel-core/src/main/java/org/apache/camel/reifier/OnExceptionReifier.java
@@ -26,6 +26,7 @@ import org.apache.camel.model.OnExceptionDefinition;
 import org.apache.camel.model.ProcessorDefinition;
 import org.apache.camel.processor.CatchProcessor;
 import org.apache.camel.processor.FatalFallbackErrorHandler;
+import org.apache.camel.processor.exceptionpolicy.ExceptionPolicy;
 import org.apache.camel.spi.ClassResolver;
 import org.apache.camel.spi.RouteContext;
 import org.apache.camel.support.CamelContextHelper;
diff --git 
a/core/camel-core/src/main/java/org/apache/camel/reifier/ProcessorReifier.java 
b/core/camel-core/src/main/java/org/apache/camel/reifier/ProcessorReifier.java
index e42afe1..f689433 100644
--- 
a/core/camel-core/src/main/java/org/apache/camel/reifier/ProcessorReifier.java
+++ 
b/core/camel-core/src/main/java/org/apache/camel/reifier/ProcessorReifier.java
@@ -103,6 +103,7 @@ import 
org.apache.camel.processor.InterceptEndpointProcessor;
 import org.apache.camel.processor.Pipeline;
 import org.apache.camel.processor.channel.DefaultChannel;
 import org.apache.camel.processor.interceptor.HandleFault;
+import org.apache.camel.reifier.errorhandler.ErrorHandlerReifier;
 import org.apache.camel.spi.IdAware;
 import org.apache.camel.spi.InterceptStrategy;
 import org.apache.camel.spi.LifecycleStrategy;
@@ -367,7 +368,7 @@ public abstract class ProcessorReifier<T extends 
ProcessorDefinition<?>> {
     protected Processor wrapInErrorHandler(RouteContext routeContext, 
Processor output) throws Exception {
         ErrorHandlerFactory builder = routeContext.getErrorHandlerFactory();
         // create error handler
-        Processor errorHandler = builder.createErrorHandler(routeContext, 
output);
+        Processor errorHandler = 
ErrorHandlerReifier.reifier(builder).createErrorHandler(routeContext, output);
 
         // invoke lifecycles so we can manage this error handler builder
         for (LifecycleStrategy strategy : 
routeContext.getCamelContext().getLifecycleStrategies()) {
diff --git 
a/core/camel-core/src/main/java/org/apache/camel/reifier/RoutingSlipReifier.java
 
b/core/camel-core/src/main/java/org/apache/camel/reifier/RoutingSlipReifier.java
index 68089e0..bb3a706 100644
--- 
a/core/camel-core/src/main/java/org/apache/camel/reifier/RoutingSlipReifier.java
+++ 
b/core/camel-core/src/main/java/org/apache/camel/reifier/RoutingSlipReifier.java
@@ -25,6 +25,7 @@ import org.apache.camel.model.RouteDefinition;
 import org.apache.camel.model.RoutingSlipDefinition;
 
 import org.apache.camel.processor.RoutingSlip;
+import org.apache.camel.reifier.errorhandler.ErrorHandlerReifier;
 import org.apache.camel.spi.RouteContext;
 
 import static org.apache.camel.model.RoutingSlipDefinition.DEFAULT_DELIMITER;
@@ -52,7 +53,7 @@ class RoutingSlipReifier extends 
ExpressionReifier<RoutingSlipDefinition<?>> {
         ErrorHandlerFactory builder = routeContext.getErrorHandlerFactory();
         // create error handler (create error handler directly to keep it 
light weight,
         // instead of using ProcessorDefinition.wrapInErrorHandler)
-        AsyncProcessor errorHandler = (AsyncProcessor) 
builder.createErrorHandler(routeContext, 
routingSlip.newRoutingSlipProcessorForErrorHandler());
+        AsyncProcessor errorHandler = (AsyncProcessor) 
ErrorHandlerReifier.reifier(builder).createErrorHandler(routeContext, 
routingSlip.newRoutingSlipProcessorForErrorHandler());
         routingSlip.setErrorHandler(errorHandler);
 
         return routingSlip;
diff --git 
a/core/camel-core/src/main/java/org/apache/camel/reifier/errorhandler/DeadLetterChannelReifier.java
 
b/core/camel-core/src/main/java/org/apache/camel/reifier/errorhandler/DeadLetterChannelReifier.java
new file mode 100644
index 0000000..af841d0
--- /dev/null
+++ 
b/core/camel-core/src/main/java/org/apache/camel/reifier/errorhandler/DeadLetterChannelReifier.java
@@ -0,0 +1,48 @@
+package org.apache.camel.reifier.errorhandler;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.ErrorHandlerFactory;
+import org.apache.camel.NoSuchEndpointException;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.DeadLetterChannelBuilder;
+import org.apache.camel.processor.errorhandler.DeadLetterChannel;
+import org.apache.camel.spi.RouteContext;
+import org.apache.camel.util.StringHelper;
+
+public class DeadLetterChannelReifier extends 
DefaultErrorHandlerReifier<DeadLetterChannelBuilder> {
+
+    public DeadLetterChannelReifier(ErrorHandlerFactory definition) {
+        super((DeadLetterChannelBuilder) definition);
+    }
+
+    public Processor createErrorHandler(RouteContext routeContext, Processor 
processor) throws Exception {
+        validateDeadLetterUri(routeContext);
+
+        DeadLetterChannel answer = new 
DeadLetterChannel(routeContext.getCamelContext(), processor,
+                definition.getLogger(), definition.getOnRedelivery(),
+                definition.getRedeliveryPolicy(), 
definition.getExceptionPolicyStrategy(),
+                definition.getFailureProcessor(), 
definition.getDeadLetterUri(),
+                definition.isDeadLetterHandleNewException(), 
definition.isUseOriginalMessage(),
+                definition.getRetryWhilePolicy(routeContext.getCamelContext()),
+                getExecutorService(routeContext.getCamelContext()),
+                definition.getOnPrepareFailure(), 
definition.getOnExceptionOccurred());
+        // configure error handler before we can use it
+        configure(routeContext, answer);
+        return answer;
+    }
+
+    protected void validateDeadLetterUri(RouteContext routeContext) {
+        Endpoint deadLetter = definition.getDeadLetter();
+        String deadLetterUri = definition.getDeadLetterUri();
+        if (deadLetter == null) {
+            StringHelper.notEmpty(deadLetterUri, "deadLetterUri", this);
+            deadLetter = 
routeContext.getCamelContext().getEndpoint(deadLetterUri);
+            if (deadLetter == null) {
+                throw new NoSuchEndpointException(deadLetterUri);
+            }
+            // TODO: ErrorHandler: no modification to the model should be done
+            definition.setDeadLetter(deadLetter);
+        }
+    }
+
+}
diff --git 
a/core/camel-core/src/main/java/org/apache/camel/reifier/errorhandler/DefaultErrorHandlerReifier.java
 
b/core/camel-core/src/main/java/org/apache/camel/reifier/errorhandler/DefaultErrorHandlerReifier.java
new file mode 100644
index 0000000..a262509a
--- /dev/null
+++ 
b/core/camel-core/src/main/java/org/apache/camel/reifier/errorhandler/DefaultErrorHandlerReifier.java
@@ -0,0 +1,69 @@
+package org.apache.camel.reifier.errorhandler;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ScheduledExecutorService;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
+import org.apache.camel.ErrorHandlerFactory;
+import org.apache.camel.NoSuchEndpointException;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.DeadLetterChannelBuilder;
+import org.apache.camel.builder.DefaultErrorHandlerBuilder;
+import org.apache.camel.processor.errorhandler.DeadLetterChannel;
+import org.apache.camel.processor.errorhandler.DefaultErrorHandler;
+import org.apache.camel.spi.ExecutorServiceManager;
+import org.apache.camel.spi.RouteContext;
+import org.apache.camel.spi.ThreadPoolProfile;
+import org.apache.camel.util.StringHelper;
+
+public class DefaultErrorHandlerReifier<T extends DefaultErrorHandlerBuilder> 
extends ErrorHandlerReifier<T> {
+
+    public DefaultErrorHandlerReifier(ErrorHandlerFactory definition) {
+        super((T) definition);
+    }
+
+    public Processor createErrorHandler(RouteContext routeContext, Processor 
processor) throws Exception {
+        DefaultErrorHandler answer = new DefaultErrorHandler(
+                routeContext.getCamelContext(),
+                processor,
+                definition.getLogger(),
+                definition.getOnRedelivery(),
+                definition.getRedeliveryPolicy(),
+                definition.getExceptionPolicyStrategy(),
+                definition.getRetryWhilePolicy(routeContext.getCamelContext()),
+                getExecutorService(routeContext.getCamelContext()),
+                definition.getOnPrepareFailure(),
+                definition.getOnExceptionOccurred());
+        // configure error handler before we can use it
+        configure(routeContext, answer);
+        return answer;
+    }
+
+    protected synchronized ScheduledExecutorService 
getExecutorService(CamelContext camelContext) {
+        ScheduledExecutorService executorService = 
definition.getExecutorService();
+        String executorServiceRef = definition.getExecutorServiceRef();
+        if (executorService == null || executorService.isShutdown()) {
+            // camel context will shutdown the executor when it shutdown so no 
need to shut it down when stopping
+            if (executorServiceRef != null) {
+                executorService = 
camelContext.getRegistry().lookupByNameAndType(executorServiceRef, 
ScheduledExecutorService.class);
+                if (executorService == null) {
+                    ExecutorServiceManager manager = 
camelContext.getExecutorServiceManager();
+                    ThreadPoolProfile profile = 
manager.getThreadPoolProfile(executorServiceRef);
+                    executorService = manager.newScheduledThreadPool(this, 
executorServiceRef, profile);
+                }
+                if (executorService == null) {
+                    throw new IllegalArgumentException("ExecutorServiceRef " + 
executorServiceRef + " not found in registry.");
+                }
+            } else {
+                // no explicit configured thread pool, so leave it up to the 
error handler to decide if it need
+                // a default thread pool from 
CamelContext#getErrorHandlerExecutorService
+                executorService = null;
+            }
+            // TODO: ErrorHandler: no modification to the model should be done
+            definition.setExecutorService(executorService);
+        }
+        return executorService;
+    }
+
+}
diff --git 
a/core/camel-core/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerRefReifier.java
 
b/core/camel-core/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerRefReifier.java
new file mode 100644
index 0000000..f35173f
--- /dev/null
+++ 
b/core/camel-core/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerRefReifier.java
@@ -0,0 +1,19 @@
+package org.apache.camel.reifier.errorhandler;
+
+import org.apache.camel.ErrorHandlerFactory;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.ErrorHandlerBuilderRef;
+import org.apache.camel.spi.RouteContext;
+
+public class ErrorHandlerRefReifier extends 
ErrorHandlerReifier<ErrorHandlerBuilderRef> {
+
+    public ErrorHandlerRefReifier(ErrorHandlerFactory definition) {
+        super((ErrorHandlerBuilderRef) definition);
+    }
+
+    @Override
+    public Processor createErrorHandler(RouteContext routeContext, Processor 
processor) throws Exception {
+        return definition.createErrorHandler(routeContext, processor);
+    }
+
+}
diff --git 
a/core/camel-core/src/main/java/org/apache/camel/reifier/ErrorHandlerReifier.java
 
b/core/camel-core/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerReifier.java
similarity index 59%
rename from 
core/camel-core/src/main/java/org/apache/camel/reifier/ErrorHandlerReifier.java
rename to 
core/camel-core/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerReifier.java
index 57eb65b..c0b90c4 100644
--- 
a/core/camel-core/src/main/java/org/apache/camel/reifier/ErrorHandlerReifier.java
+++ 
b/core/camel-core/src/main/java/org/apache/camel/reifier/errorhandler/ErrorHandlerReifier.java
@@ -14,21 +14,103 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.camel.reifier;
+package org.apache.camel.reifier.errorhandler;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.function.Function;
 
 import org.apache.camel.CamelContext;
+import org.apache.camel.ErrorHandlerFactory;
+import org.apache.camel.Processor;
 import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.builder.DeadLetterChannelBuilder;
+import org.apache.camel.builder.DefaultErrorHandlerBuilder;
+import org.apache.camel.builder.ErrorHandlerBuilderRef;
+import org.apache.camel.builder.ErrorHandlerBuilderSupport;
+import org.apache.camel.builder.NoErrorHandlerBuilder;
 import org.apache.camel.model.OnExceptionDefinition;
 import org.apache.camel.model.RedeliveryPolicyDefinition;
+import org.apache.camel.processor.ErrorHandler;
+import org.apache.camel.processor.errorhandler.ErrorHandlerSupport;
+import org.apache.camel.processor.errorhandler.RedeliveryErrorHandler;
 import org.apache.camel.processor.errorhandler.RedeliveryPolicy;
+import org.apache.camel.processor.exceptionpolicy.ExceptionPolicy;
+import org.apache.camel.spi.RouteContext;
 import org.apache.camel.support.CamelContextHelper;
 
-public final class ErrorHandlerReifier {
-    
+public abstract class ErrorHandlerReifier<T extends 
ErrorHandlerBuilderSupport> {
+
+    private static final Map<Class<?>, Function<ErrorHandlerFactory, 
ErrorHandlerReifier<? extends ErrorHandlerFactory>>> ERROR_HANDLERS;
+    static {
+        Map<Class<?>, Function<ErrorHandlerFactory, ErrorHandlerReifier<? 
extends ErrorHandlerFactory>>> map = new HashMap<>();
+        map.put(DeadLetterChannelBuilder.class, DeadLetterChannelReifier::new);
+        map.put(DefaultErrorHandlerBuilder.class, 
DefaultErrorHandlerReifier::new);
+        map.put(ErrorHandlerBuilderRef.class, ErrorHandlerRefReifier::new);
+        map.put(NoErrorHandlerBuilder.class, NoErrorHandlerReifier::new);
+        ERROR_HANDLERS = map;
+    }
+
+    public static void registerReifier(Class<?> errorHandlerClass, 
Function<ErrorHandlerFactory, ErrorHandlerReifier<? extends 
ErrorHandlerFactory>> creator) {
+        ERROR_HANDLERS.put(errorHandlerClass, creator);
+    }
+
+    protected T definition;
+
     /**
      * Utility classes should not have a public constructor.
      */
-    private ErrorHandlerReifier() {
+    ErrorHandlerReifier(T definition) {
+        this.definition = definition;
+    }
+
+    public static ErrorHandlerReifier<? extends ErrorHandlerFactory> 
reifier(ErrorHandlerFactory definition) {
+        Function<ErrorHandlerFactory, ErrorHandlerReifier<? extends 
ErrorHandlerFactory>> reifier = ERROR_HANDLERS.get(definition.getClass());
+        if (reifier != null) {
+            return reifier.apply(definition);
+        } else if (definition instanceof ErrorHandlerBuilderSupport) {
+            return new 
ErrorHandlerReifier<ErrorHandlerBuilderSupport>((ErrorHandlerBuilderSupport) 
definition) {
+                @Override
+                public Processor createErrorHandler(RouteContext routeContext, 
Processor processor) throws Exception {
+                    return definition.createErrorHandler(routeContext, 
processor);
+                }
+            };
+        } else {
+            throw new IllegalStateException("Unsupported definition: " + 
definition);
+        }
+    }
+
+    /**
+     * Creates the error handler
+     *
+     * @param routeContext the route context
+     * @param processor the outer processor
+     * @return the error handler
+     * @throws Exception is thrown if the error handler could not be created
+     */
+    public abstract Processor createErrorHandler(RouteContext routeContext, 
Processor processor) throws Exception;
+
+    public void configure(RouteContext routeContext, ErrorHandler handler) {
+        if (handler instanceof ErrorHandlerSupport) {
+            ErrorHandlerSupport handlerSupport = (ErrorHandlerSupport) handler;
+
+            List<OnExceptionDefinition> list = 
definition.getOnExceptions().get(routeContext);
+            if (list != null) {
+                for (OnExceptionDefinition exception : list) {
+                    
ErrorHandlerBuilderSupport.addExceptionPolicy(handlerSupport, routeContext, 
exception);
+                }
+            }
+        }
+        if (handler instanceof RedeliveryErrorHandler) {
+            boolean original = ((RedeliveryErrorHandler) 
handler).isUseOriginalMessagePolicy();
+            if (original) {
+                // ensure allow original is turned on
+                routeContext.setAllowUseOriginalMessage(true);
+            }
+        }
     }
 
     public static RedeliveryPolicy 
createRedeliveryPolicy(RedeliveryPolicyDefinition definition, CamelContext 
context, RedeliveryPolicy parentPolicy) {
@@ -133,12 +215,12 @@ public final class ErrorHandlerReifier {
      * @return a newly created redelivery policy, or return the original 
policy if no customization is required
      *         for this exception handler.
      */
-    public static RedeliveryPolicy 
createRedeliveryPolicy(OnExceptionDefinition definition, CamelContext context, 
RedeliveryPolicy parentPolicy) {
+    public static RedeliveryPolicy createRedeliveryPolicy(ExceptionPolicy 
definition, CamelContext context, RedeliveryPolicy parentPolicy) {
         if (definition.getRedeliveryPolicyRef() != null) {
             return CamelContextHelper.mandatoryLookup(context, 
definition.getRedeliveryPolicyRef(), RedeliveryPolicy.class);
         } else if (definition.getRedeliveryPolicyType() != null) {
             return 
createRedeliveryPolicy(definition.getRedeliveryPolicyType(), context, 
parentPolicy);
-        } else if (!definition.getOutputs().isEmpty() && 
parentPolicy.getMaximumRedeliveries() != 0) {
+        } else if (definition.hasOutputs() && 
parentPolicy.getMaximumRedeliveries() != 0) {
             // if we have outputs, then do not inherit parent 
maximumRedeliveries
             // as you would have to explicit configure maximumRedeliveries on 
this onException to use it
             // this is the behavior Camel has always had
@@ -149,4 +231,28 @@ public final class ErrorHandlerReifier {
             return parentPolicy;
         }
     }
+
+    public static boolean determineIfRedeliveryIsEnabled(ExceptionPolicy def, 
CamelContext camelContext) throws Exception {
+        String ref = def.getRedeliveryPolicyRef();
+        if (ref != null) {
+            // lookup in registry if ref provided
+            RedeliveryPolicy policy = 
CamelContextHelper.mandatoryLookup(camelContext, ref, RedeliveryPolicy.class);
+            if (policy.getMaximumRedeliveries() != 0) {
+                // must check for != 0 as (-1 means redeliver forever)
+                return true;
+            }
+        } else if (def.getRedeliveryPolicyType() != null) {
+            Integer max = CamelContextHelper.parseInteger(camelContext, 
def.getRedeliveryPolicyType().getMaximumRedeliveries());
+            if (max != null && max != 0) {
+                // must check for != 0 as (-1 means redeliver forever)
+                return true;
+            }
+        }
+
+        if (def.getRetryWhilePolicy() != null) {
+            return true;
+        }
+
+        return false;
+    }
 }
diff --git 
a/core/camel-core/src/main/java/org/apache/camel/reifier/errorhandler/NoErrorHandlerReifier.java
 
b/core/camel-core/src/main/java/org/apache/camel/reifier/errorhandler/NoErrorHandlerReifier.java
new file mode 100644
index 0000000..89dde35
--- /dev/null
+++ 
b/core/camel-core/src/main/java/org/apache/camel/reifier/errorhandler/NoErrorHandlerReifier.java
@@ -0,0 +1,41 @@
+package org.apache.camel.reifier.errorhandler;
+
+import org.apache.camel.AsyncCallback;
+import org.apache.camel.ErrorHandlerFactory;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.NoErrorHandlerBuilder;
+import org.apache.camel.spi.RouteContext;
+import org.apache.camel.support.processor.DelegateAsyncProcessor;
+
+public class NoErrorHandlerReifier extends 
ErrorHandlerReifier<NoErrorHandlerBuilder> {
+
+    public NoErrorHandlerReifier(ErrorHandlerFactory definition) {
+        super((NoErrorHandlerBuilder) definition);
+    }
+
+    @Override
+    public Processor createErrorHandler(RouteContext routeContext, Processor 
processor) throws Exception {
+        return new DelegateAsyncProcessor(processor) {
+            @Override
+            public boolean process(final Exchange exchange, final 
AsyncCallback callback) {
+                return super.process(exchange, new AsyncCallback() {
+                    @Override
+                    public void done(boolean doneSync) {
+                        exchange.removeProperty(Exchange.REDELIVERY_EXHAUSTED);
+                        callback.done(doneSync);
+                    }
+                });
+            }
+
+            @Override
+            public String toString() {
+                if (processor == null) {
+                    // if no output then dont do any description
+                    return "";
+                }
+                return "NoErrorHandler[" + processor + "]";
+            }
+        };
+    }
+}
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/component/validator/ValidatorEndpointClearCachedSchemaTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/component/validator/ValidatorEndpointClearCachedSchemaTest.java
index 0566c3a..1a2b006 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/component/validator/ValidatorEndpointClearCachedSchemaTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/component/validator/ValidatorEndpointClearCachedSchemaTest.java
@@ -30,6 +30,7 @@ import org.apache.camel.Exchange;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.mock.MockEndpoint;
 import org.apache.camel.impl.DefaultCamelContext;
+import org.apache.camel.support.CamelContextHelper;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -142,6 +143,10 @@ public class ValidatorEndpointClearCachedSchemaTest 
extends ContextTestSupport {
     }
 
     private void clearCachedSchema() throws Exception {
+        CamelContext context = this.context;
+        if (context == null) {
+            return;
+        }
         Collection<Endpoint> endpoints = context.getEndpoints();
         for (Endpoint endpoint : endpoints) {
             LOG.info("Endpoint URI: " + endpoint.getEndpointUri());
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/processor/errorhandler/ErrorHandlerSupportTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/processor/errorhandler/ErrorHandlerSupportTest.java
index 801ebd0..833e71b 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/processor/errorhandler/ErrorHandlerSupportTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/processor/errorhandler/ErrorHandlerSupportTest.java
@@ -22,6 +22,7 @@ import java.util.List;
 import org.apache.camel.ContextTestSupport;
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
+import org.apache.camel.builder.ErrorHandlerBuilderSupport;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.model.OnExceptionDefinition;
 import org.junit.Test;
@@ -35,7 +36,7 @@ public class ErrorHandlerSupportTest extends 
ContextTestSupport {
         exceptions.add(ParentException.class);
 
         ErrorHandlerSupport support = new ShuntErrorHandlerSupport();
-        support.addExceptionPolicy(context.getRoute("foo").getRouteContext(), 
new OnExceptionDefinition(exceptions));
+        ErrorHandlerBuilderSupport.addExceptionPolicy(support, 
context.getRoute("foo").getRouteContext(), new 
OnExceptionDefinition(exceptions));
 
         assertEquals(ChildException.class.getName(), 
getExceptionPolicyFor(support, new ChildException(), 0));
         assertEquals(ParentException.class.getName(), 
getExceptionPolicyFor(support, new ParentException(), 1));
@@ -48,7 +49,7 @@ public class ErrorHandlerSupportTest extends 
ContextTestSupport {
         exceptions.add(ChildException.class);
 
         ErrorHandlerSupport support = new ShuntErrorHandlerSupport();
-        support.addExceptionPolicy(context.getRoute("foo").getRouteContext(), 
new OnExceptionDefinition(exceptions));
+        ErrorHandlerBuilderSupport.addExceptionPolicy(support, 
context.getRoute("foo").getRouteContext(), new 
OnExceptionDefinition(exceptions));
 
         assertEquals(ChildException.class.getName(), 
getExceptionPolicyFor(support, new ChildException(), 1));
         assertEquals(ParentException.class.getName(), 
getExceptionPolicyFor(support, new ParentException(), 0));
@@ -57,8 +58,8 @@ public class ErrorHandlerSupportTest extends 
ContextTestSupport {
     @Test
     public void testTwoPolicyChildFirst() {
         ErrorHandlerSupport support = new ShuntErrorHandlerSupport();
-        support.addExceptionPolicy(context.getRoute("foo").getRouteContext(), 
new OnExceptionDefinition(ChildException.class));
-        support.addExceptionPolicy(context.getRoute("foo").getRouteContext(), 
new OnExceptionDefinition(ParentException.class));
+        ErrorHandlerBuilderSupport.addExceptionPolicy(support, 
context.getRoute("foo").getRouteContext(), new 
OnExceptionDefinition(ChildException.class));
+        ErrorHandlerBuilderSupport.addExceptionPolicy(support, 
context.getRoute("foo").getRouteContext(), new 
OnExceptionDefinition(ParentException.class));
 
         assertEquals(ChildException.class.getName(), 
getExceptionPolicyFor(support, new ChildException(), 0));
         assertEquals(ParentException.class.getName(), 
getExceptionPolicyFor(support, new ParentException(), 0));
@@ -67,8 +68,8 @@ public class ErrorHandlerSupportTest extends 
ContextTestSupport {
     @Test
     public void testTwoPolicyChildLast() {
         ErrorHandlerSupport support = new ShuntErrorHandlerSupport();
-        support.addExceptionPolicy(context.getRoute("foo").getRouteContext(), 
new OnExceptionDefinition(ParentException.class));
-        support.addExceptionPolicy(context.getRoute("foo").getRouteContext(), 
new OnExceptionDefinition(ChildException.class));
+        ErrorHandlerBuilderSupport.addExceptionPolicy(support, 
context.getRoute("foo").getRouteContext(), new 
OnExceptionDefinition(ParentException.class));
+        ErrorHandlerBuilderSupport.addExceptionPolicy(support, 
context.getRoute("foo").getRouteContext(), new 
OnExceptionDefinition(ChildException.class));
 
         assertEquals(ChildException.class.getName(), 
getExceptionPolicyFor(support, new ChildException(), 0));
         assertEquals(ParentException.class.getName(), 
getExceptionPolicyFor(support, new ParentException(), 0));
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/CustomExceptionPolicyStrategyTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/CustomExceptionPolicyStrategyTest.java
index 4c36a10..f6cb8b8 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/CustomExceptionPolicyStrategyTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/CustomExceptionPolicyStrategyTest.java
@@ -25,7 +25,6 @@ import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.component.mock.MockEndpoint;
-import org.apache.camel.model.OnExceptionDefinition;
 import org.junit.Test;
 
 /**
@@ -43,7 +42,7 @@ public class CustomExceptionPolicyStrategyTest extends 
ContextTestSupport {
     // START SNIPPET e2
     public static class MyPolicy implements ExceptionPolicyStrategy {
 
-        public OnExceptionDefinition 
getExceptionPolicy(Map<ExceptionPolicyKey, OnExceptionDefinition> 
exceptionPolicices,
+        public ExceptionPolicy getExceptionPolicy(Map<ExceptionPolicyKey, 
ExceptionPolicy> exceptionPolicices,
                                                 Exchange exchange,
                                                 Throwable exception) {
             // This is just an example that always forces the exception type 
configured
diff --git 
a/core/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategyTest.java
 
b/core/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategyTest.java
index cc054f4..af8ef8a 100644
--- 
a/core/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategyTest.java
+++ 
b/core/camel-core/src/test/java/org/apache/camel/processor/exceptionpolicy/DefaultExceptionPolicyStrategyTest.java
@@ -38,17 +38,17 @@ import org.junit.Test;
 public class DefaultExceptionPolicyStrategyTest extends Assert {
 
     private DefaultExceptionPolicyStrategy strategy;
-    private HashMap<ExceptionPolicyKey, OnExceptionDefinition> policies;
-    private OnExceptionDefinition type1;
-    private OnExceptionDefinition type2;
-    private OnExceptionDefinition type3;
+    private HashMap<ExceptionPolicyKey, ExceptionPolicy> policies;
+    private ExceptionPolicy type1;
+    private ExceptionPolicy type2;
+    private ExceptionPolicy type3;
 
     private void setupPolicies() {
         strategy = new DefaultExceptionPolicyStrategy();
         policies = new HashMap<>();
-        type1 = new OnExceptionDefinition(CamelExchangeException.class);
-        type2 = new OnExceptionDefinition(Exception.class);
-        type3 = new OnExceptionDefinition(IOException.class);
+        type1 = new ExceptionPolicy(new 
OnExceptionDefinition(CamelExchangeException.class));
+        type2 = new ExceptionPolicy(new 
OnExceptionDefinition(Exception.class));
+        type3 = new ExceptionPolicy(new 
OnExceptionDefinition(IOException.class));
         policies.put(new ExceptionPolicyKey(null, 
CamelExchangeException.class, null), type1);
         policies.put(new ExceptionPolicyKey(null, Exception.class, null), 
type2);
         policies.put(new ExceptionPolicyKey(null, IOException.class, null), 
type3);
@@ -58,8 +58,8 @@ public class DefaultExceptionPolicyStrategyTest extends 
Assert {
         // without the top level exception that can be used as fallback
         strategy = new DefaultExceptionPolicyStrategy();
         policies = new HashMap<>();
-        type1 = new OnExceptionDefinition(CamelExchangeException.class);
-        type3 = new OnExceptionDefinition(IOException.class);
+        type1 = new ExceptionPolicy(new 
OnExceptionDefinition(CamelExchangeException.class));
+        type3 = new ExceptionPolicy(new 
OnExceptionDefinition(IOException.class));
         policies.put(new ExceptionPolicyKey(null, 
CamelExchangeException.class, null), type1);
         policies.put(new ExceptionPolicyKey(null, IOException.class, null), 
type3);
     }
@@ -67,9 +67,9 @@ public class DefaultExceptionPolicyStrategyTest extends 
Assert {
     private void setupPoliciesCausedBy() {
         strategy = new DefaultExceptionPolicyStrategy();
         policies = new HashMap<>();
-        type1 = new OnExceptionDefinition(FileNotFoundException.class);
-        type2 = new OnExceptionDefinition(ConnectException.class);
-        type3 = new OnExceptionDefinition(IOException.class);
+        type1 = new ExceptionPolicy(new 
OnExceptionDefinition(FileNotFoundException.class));
+        type2 = new ExceptionPolicy(new 
OnExceptionDefinition(ConnectException.class));
+        type3 = new ExceptionPolicy(new 
OnExceptionDefinition(IOException.class));
         policies.put(new ExceptionPolicyKey(null, FileNotFoundException.class, 
null), type1);
         policies.put(new ExceptionPolicyKey(null, IOException.class, null), 
type2);
         policies.put(new ExceptionPolicyKey(null, ConnectException.class, 
null), type3);
@@ -78,28 +78,28 @@ public class DefaultExceptionPolicyStrategyTest extends 
Assert {
     @Test
     public void testDirectMatch1() {
         setupPolicies();
-        OnExceptionDefinition result = strategy.getExceptionPolicy(policies, 
null, new CamelExchangeException("", null));
+        ExceptionPolicy result = strategy.getExceptionPolicy(policies, null, 
new CamelExchangeException("", null));
         assertEquals(type1, result);
     }
 
     @Test
     public void testDirectMatch2() {
         setupPolicies();
-        OnExceptionDefinition result = strategy.getExceptionPolicy(policies, 
null, new Exception(""));
+        ExceptionPolicy result = strategy.getExceptionPolicy(policies, null, 
new Exception(""));
         assertEquals(type2, result);
     }
 
     @Test
     public void testDirectMatch3() {
         setupPolicies();
-        OnExceptionDefinition result = strategy.getExceptionPolicy(policies, 
null, new IOException(""));
+        ExceptionPolicy result = strategy.getExceptionPolicy(policies, null, 
new IOException(""));
         assertEquals(type3, result);
     }
 
     @Test
     public void testClosetMatch3() {
         setupPolicies();
-        OnExceptionDefinition result = strategy.getExceptionPolicy(policies, 
null, new ConnectException(""));
+        ExceptionPolicy result = strategy.getExceptionPolicy(policies, null, 
new ConnectException(""));
         assertEquals(type3, result);
 
         result = strategy.getExceptionPolicy(policies, null, new 
SocketException(""));
@@ -112,7 +112,7 @@ public class DefaultExceptionPolicyStrategyTest extends 
Assert {
     @Test
     public void testClosetMatch2() {
         setupPolicies();
-        OnExceptionDefinition result = strategy.getExceptionPolicy(policies, 
null, new ClassCastException(""));
+        ExceptionPolicy result = strategy.getExceptionPolicy(policies, null, 
new ClassCastException(""));
         assertEquals(type2, result);
 
         result = strategy.getExceptionPolicy(policies, null, new 
NumberFormatException(""));
@@ -125,7 +125,7 @@ public class DefaultExceptionPolicyStrategyTest extends 
Assert {
     @Test
     public void testClosetMatch1() {
         setupPolicies();
-        OnExceptionDefinition result = strategy.getExceptionPolicy(policies, 
null, new ValidationException(null, ""));
+        ExceptionPolicy result = strategy.getExceptionPolicy(policies, null, 
new ValidationException(null, ""));
         assertEquals(type1, result);
 
         result = strategy.getExceptionPolicy(policies, null, new 
ExchangeTimedOutException(null, 0));
@@ -135,14 +135,14 @@ public class DefaultExceptionPolicyStrategyTest extends 
Assert {
     @Test
     public void testNoMatch1ThenMatchingJustException() {
         setupPolicies();
-        OnExceptionDefinition result = strategy.getExceptionPolicy(policies, 
null, new AlreadyStoppedException());
+        ExceptionPolicy result = strategy.getExceptionPolicy(policies, null, 
new AlreadyStoppedException());
         assertEquals(type2, result);
     }
 
     @Test
     public void testNoMatch1ThenNull() {
         setupPoliciesNoTopLevelException();
-        OnExceptionDefinition result = strategy.getExceptionPolicy(policies, 
null, new AlreadyStoppedException());
+        ExceptionPolicy result = strategy.getExceptionPolicy(policies, null, 
new AlreadyStoppedException());
         assertNull("Should not find an exception policy to use", result);
     }
 
@@ -152,7 +152,7 @@ public class DefaultExceptionPolicyStrategyTest extends 
Assert {
 
         IOException ioe = new IOException("Damm");
         ioe.initCause(new FileNotFoundException("Somefile not found"));
-        OnExceptionDefinition result = strategy.getExceptionPolicy(policies, 
null, ioe);
+        ExceptionPolicy result = strategy.getExceptionPolicy(policies, null, 
ioe);
         assertEquals(type1, result);
     }
 
@@ -162,7 +162,7 @@ public class DefaultExceptionPolicyStrategyTest extends 
Assert {
 
         IOException ioe = new IOException("Damm");
         ioe.initCause(new FileNotFoundException("Somefile not found"));
-        OnExceptionDefinition result = strategy.getExceptionPolicy(policies, 
null, new RuntimeCamelException(ioe));
+        ExceptionPolicy result = strategy.getExceptionPolicy(policies, null, 
new RuntimeCamelException(ioe));
         assertEquals(type1, result);
     }
 
@@ -172,7 +172,7 @@ public class DefaultExceptionPolicyStrategyTest extends 
Assert {
 
         IOException ioe = new IOException("Damm");
         ioe.initCause(new ConnectException("Not connected"));
-        OnExceptionDefinition result = strategy.getExceptionPolicy(policies, 
null, ioe);
+        ExceptionPolicy result = strategy.getExceptionPolicy(policies, null, 
ioe);
         assertEquals(type3, result);
     }
 
@@ -182,7 +182,7 @@ public class DefaultExceptionPolicyStrategyTest extends 
Assert {
 
         IOException ioe = new IOException("Damm");
         ioe.initCause(new MalformedURLException("Bad url"));
-        OnExceptionDefinition result = strategy.getExceptionPolicy(policies, 
null, ioe);
+        ExceptionPolicy result = strategy.getExceptionPolicy(policies, null, 
ioe);
         assertEquals(type2, result);
     }
 

Reply via email to