camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From davscl...@apache.org
Subject [01/10] camel git commit: CAMEL-7050: DeadLetterChannel should make more clear that it handles any new exception also. Added option to configure this behavior so ppl can turn that off and let new exceptions be unhandled, so transactions can rollback.
Date Mon, 19 Jan 2015 08:53:47 GMT
Repository: camel
Updated Branches:
  refs/heads/master f98e86be1 -> 9461db295


CAMEL-7050: DeadLetterChannel should make more clear that it handles any new exception also. Added option to configure this behavior so ppl can turn that off and let new exceptions be unhandled, so transactions can rollback.


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/b05668f7
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/b05668f7
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/b05668f7

Branch: refs/heads/master
Commit: b05668f78d83086181a5be6b3430b868089e4a93
Parents: f98e86b
Author: Claus Ibsen <davsclaus@apache.org>
Authored: Sun Jan 18 14:05:54 2015 +0100
Committer: Claus Ibsen <davsclaus@apache.org>
Committed: Sun Jan 18 14:05:54 2015 +0100

----------------------------------------------------------------------
 .../camel/builder/DeadLetterChannelBuilder.java | 17 ++--
 .../builder/DefaultErrorHandlerBuilder.java     | 33 +++++++-
 .../camel/model/RedeliveryPolicyDefinition.java | 40 +++++++++
 .../camel/processor/DeadLetterChannel.java      |  8 +-
 .../camel/processor/DefaultErrorHandler.java    |  2 +-
 .../processor/FatalFallbackErrorHandler.java    | 37 +++++++--
 .../camel/processor/RedeliveryErrorHandler.java | 87 +++++++++++++++-----
 .../camel/processor/RedeliveryPolicy.java       | 21 +++++
 .../apache/camel/processor/SendProcessor.java   | 18 ----
 .../camel/component/jms/CamelJmsTestHelper.java |  9 +-
 ...msDeadLetterChannelHandlerExceptionTest.java | 77 -----------------
 ...erChannelHandlerRollbackOnExceptionTest.java | 84 +++++++++++++++++++
 ...hannelNotHandlerRollbackOnExceptionTest.java | 39 +++++++++
 ...actedOnExceptionRollbackOnExceptionTest.java | 77 +++++++++++++++++
 .../src/test/resources/log4j.properties         |  2 +-
 15 files changed, 410 insertions(+), 141 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/camel-core/src/main/java/org/apache/camel/builder/DeadLetterChannelBuilder.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/builder/DeadLetterChannelBuilder.java b/camel-core/src/main/java/org/apache/camel/builder/DeadLetterChannelBuilder.java
index 4ea7f1d..e1e417d 100644
--- a/camel-core/src/main/java/org/apache/camel/builder/DeadLetterChannelBuilder.java
+++ b/camel-core/src/main/java/org/apache/camel/builder/DeadLetterChannelBuilder.java
@@ -22,6 +22,7 @@ import org.apache.camel.LoggingLevel;
 import org.apache.camel.NoSuchEndpointException;
 import org.apache.camel.Processor;
 import org.apache.camel.processor.DeadLetterChannel;
+import org.apache.camel.processor.FatalFallbackErrorHandler;
 import org.apache.camel.processor.RedeliveryPolicy;
 import org.apache.camel.processor.SendProcessor;
 import org.apache.camel.spi.RouteContext;
@@ -37,7 +38,6 @@ import org.slf4j.LoggerFactory;
  * @version 
  */
 public class DeadLetterChannelBuilder extends DefaultErrorHandlerBuilder {
-    boolean checkException;
 
     public DeadLetterChannelBuilder() {
         // no-arg constructor used by Spring DSL
@@ -51,17 +51,12 @@ public class DeadLetterChannelBuilder extends DefaultErrorHandlerBuilder {
         setDeadLetterUri(uri);
     }
     
-    public DeadLetterChannelBuilder checkException() {
-        checkException = true;
-        return this;
-    }
-
     public Processor createErrorHandler(RouteContext routeContext, Processor processor) throws Exception {
         validateDeadLetterUri(routeContext);
 
         DeadLetterChannel answer = new DeadLetterChannel(routeContext.getCamelContext(), processor, getLogger(), getOnRedelivery(), 
-                getRedeliveryPolicy(), getExceptionPolicyStrategy(), getFailureProcessor(), getDeadLetterUri(), isUseOriginalMessage(),
-                getRetryWhilePolicy(routeContext.getCamelContext()), getExecutorService(routeContext.getCamelContext()));
+                getRedeliveryPolicy(), getExceptionPolicyStrategy(), getFailureProcessor(), getDeadLetterUri(), isDeadLetterHandleNewException(),
+                isUseOriginalMessage(), getRetryWhilePolicy(routeContext.getCamelContext()), getExecutorService(routeContext.getCamelContext()));
         // configure error handler before we can use it
         configure(routeContext, answer);
         return answer;
@@ -83,10 +78,10 @@ public class DeadLetterChannelBuilder extends DefaultErrorHandlerBuilder {
 
     public Processor getFailureProcessor() {
         if (failureProcessor == null) {
+            // wrap in our special safe fallback error handler if sending to dead letter channel fails
+            Processor child = new SendProcessor(deadLetter, ExchangePattern.InOnly);
             // force MEP to be InOnly so when sending to DLQ we would not expect a reply if the MEP was InOut
-            // If the checkException is true, sendProcessor will checkException 
-            // and mark the exchange ERRORHANDLER_HANDLED property to false
-            failureProcessor = new SendProcessor(deadLetter, ExchangePattern.InOnly, checkException);
+            failureProcessor = new FatalFallbackErrorHandler(child, true);
         }
         return failureProcessor;
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java b/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java
index 9e641cf..d57f110 100644
--- a/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java
+++ b/camel-core/src/main/java/org/apache/camel/builder/DefaultErrorHandlerBuilder.java
@@ -49,6 +49,7 @@ public class DefaultErrorHandlerBuilder extends ErrorHandlerBuilderSupport {
     protected Processor failureProcessor;
     protected Endpoint deadLetter;
     protected String deadLetterUri;
+    protected boolean deadLetterHandleNewException = true;
     protected boolean useOriginalMessage;
     protected boolean asyncDelayedRedelivery;
     protected String executorServiceRef;
@@ -103,6 +104,7 @@ public class DefaultErrorHandlerBuilder extends ErrorHandlerBuilderSupport {
         if (deadLetterUri != null) {
             other.setDeadLetterUri(deadLetterUri);
         }
+        other.setDeadLetterHandleNewException(deadLetterHandleNewException);
         other.setUseOriginalMessage(useOriginalMessage);
         other.setAsyncDelayedRedelivery(asyncDelayedRedelivery);
         other.setExecutorServiceRef(executorServiceRef);
@@ -204,7 +206,6 @@ public class DefaultErrorHandlerBuilder extends ErrorHandlerBuilderSupport {
         return this;
     }
 
-
     /**
      * Will allow asynchronous delayed redeliveries.
      *
@@ -340,8 +341,26 @@ public class DefaultErrorHandlerBuilder extends ErrorHandlerBuilderSupport {
         setUseOriginalMessage(true);
         return this;
     }
-    
-    
+
+    /**
+     * Whether the dead letter channel should handle (and ignore) any new exception that may been thrown during sending the
+     * message to the dead letter endpoint.
+     * <p/>
+     * The default value is <tt>true</tt> which means any such kind of exception is handled and ignored. Set this to <tt>false</tt>
+     * to let the exception be propagated back on the {@link org.apache.camel.Exchange}. This can be used in situations
+     * where you use transactions, and want to use Camel's dead letter channel to deal with exceptions during routing,
+     * but if the dead letter channel itself fails because of a new exception being thrown, then by setting this to <tt>false</tt>
+     * the new exceptions is propagated back and set on the {@link org.apache.camel.Exchange}, which allows the transaction
+     * to detect the exception, and rollback.
+     *
+     * @param handleNewException <tt>true</tt> to handle (and ignore), <tt>false</tt> to catch and propagated the exception on the {@link org.apache.camel.Exchange}
+     * @return the builder
+     */
+    public DefaultErrorHandlerBuilder deadLetterHandleNewException(boolean handleNewException) {
+        setDeadLetterHandleNewException(handleNewException);
+        return this;
+    }
+
     // Properties
     // -------------------------------------------------------------------------
 
@@ -432,6 +451,14 @@ public class DefaultErrorHandlerBuilder extends ErrorHandlerBuilderSupport {
         this.deadLetterUri = deadLetter.getEndpointUri();
     }
 
+    public boolean isDeadLetterHandleNewException() {
+        return deadLetterHandleNewException;
+    }
+
+    public void setDeadLetterHandleNewException(boolean deadLetterHandleNewException) {
+        this.deadLetterHandleNewException = deadLetterHandleNewException;
+    }
+
     public boolean isUseOriginalMessage() {
         return useOriginalMessage;
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/camel-core/src/main/java/org/apache/camel/model/RedeliveryPolicyDefinition.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/model/RedeliveryPolicyDefinition.java b/camel-core/src/main/java/org/apache/camel/model/RedeliveryPolicyDefinition.java
index 0fb68ff..5501246 100644
--- a/camel-core/src/main/java/org/apache/camel/model/RedeliveryPolicyDefinition.java
+++ b/camel-core/src/main/java/org/apache/camel/model/RedeliveryPolicyDefinition.java
@@ -66,6 +66,8 @@ public class RedeliveryPolicyDefinition {
     @XmlAttribute
     private String logHandled;
     @XmlAttribute
+    private String logNewException;
+    @XmlAttribute
     private String logContinued;
     @XmlAttribute
     private String logExhausted;
@@ -133,6 +135,9 @@ public class RedeliveryPolicyDefinition {
             if (logHandled != null) {
                 answer.setLogHandled(CamelContextHelper.parseBoolean(context, logHandled));
             }
+            if (logNewException != null) {
+                answer.setLogNewException(CamelContextHelper.parseBoolean(context, logNewException));
+            }
             if (logContinued != null) {
                 answer.setLogContinued(CamelContextHelper.parseBoolean(context, logContinued));
             }
@@ -394,6 +399,33 @@ public class RedeliveryPolicyDefinition {
     }
 
     /**
+     * Sets whether new exceptions should be logged or not.
+     * Can be used to include or reduce verbose.
+     * <p/>
+     * A new exception is an exception that was thrown while handling a previous exception.
+     *
+     * @param logNewException  whether new exceptions should be logged or not
+     * @return the builder
+     */
+    public RedeliveryPolicyDefinition logNewException(boolean logNewException) {
+        return logNewException(Boolean.toString(logNewException));
+    }
+
+    /**
+     * Sets whether new exceptions should be logged or not (supports property placeholders).
+     * Can be used to include or reduce verbose.
+     * <p/>
+     * A new exception is an exception that was thrown while handling a previous exception.
+     *
+     * @param logNewException  whether new exceptions should be logged or not
+     * @return the builder
+     */
+    public RedeliveryPolicyDefinition logNewException(String logNewException) {
+        logNewException(logNewException);
+        return this;
+    }
+
+    /**
      * Sets whether continued exceptions should be logged or not.
      * Can be used to include or reduce verbose.
      *
@@ -684,6 +716,14 @@ public class RedeliveryPolicyDefinition {
         this.logHandled = logHandled;
     }
 
+    public String getLogNewException() {
+        return logNewException;
+    }
+
+    public void setLogNewException(String logNewException) {
+        this.logNewException = logNewException;
+    }
+
     public String getLogContinued() {
         return logContinued;
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/camel-core/src/main/java/org/apache/camel/processor/DeadLetterChannel.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/processor/DeadLetterChannel.java b/camel-core/src/main/java/org/apache/camel/processor/DeadLetterChannel.java
index 7e5863c..c7545ee 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/DeadLetterChannel.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/DeadLetterChannel.java
@@ -48,15 +48,17 @@ public class DeadLetterChannel extends RedeliveryErrorHandler {
      * @param exceptionPolicyStrategy   strategy for onException handling
      * @param deadLetter                the failure processor to send failed exchanges to
      * @param deadLetterUri             an optional uri for logging purpose
+     * @param deadLetterHandleException whether dead letter channel should handle (and ignore) exceptions which may be thrown during sending the message to the dead letter endpoint
      * @param useOriginalBodyPolicy     should the original IN body be moved to the dead letter queue or the current exchange IN body?
      * @param retryWhile                retry while
      * @param executorService           the {@link java.util.concurrent.ScheduledExecutorService} to be used for redelivery thread pool. Can be <tt>null</tt>.
      */
     public DeadLetterChannel(CamelContext camelContext, Processor output, CamelLogger logger, Processor redeliveryProcessor, RedeliveryPolicy redeliveryPolicy,
-            ExceptionPolicyStrategy exceptionPolicyStrategy, Processor deadLetter, String deadLetterUri, boolean useOriginalBodyPolicy, Predicate retryWhile,
-            ScheduledExecutorService executorService) {
+            ExceptionPolicyStrategy exceptionPolicyStrategy, Processor deadLetter, String deadLetterUri, boolean deadLetterHandleException,
+            boolean useOriginalBodyPolicy, Predicate retryWhile, ScheduledExecutorService executorService) {
 
-        super(camelContext, output, logger, redeliveryProcessor, redeliveryPolicy, deadLetter, deadLetterUri, useOriginalBodyPolicy, retryWhile, executorService);
+        super(camelContext, output, logger, redeliveryProcessor, redeliveryPolicy, deadLetter, deadLetterUri, deadLetterHandleException,
+                useOriginalBodyPolicy, retryWhile, executorService);
         setExceptionPolicy(exceptionPolicyStrategy);
     }
 

http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/camel-core/src/main/java/org/apache/camel/processor/DefaultErrorHandler.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/processor/DefaultErrorHandler.java b/camel-core/src/main/java/org/apache/camel/processor/DefaultErrorHandler.java
index 5b5a0aa..8f1c931 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/DefaultErrorHandler.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/DefaultErrorHandler.java
@@ -47,7 +47,7 @@ public class DefaultErrorHandler extends RedeliveryErrorHandler {
     public DefaultErrorHandler(CamelContext camelContext, Processor output, CamelLogger logger, Processor redeliveryProcessor,
             RedeliveryPolicy redeliveryPolicy, ExceptionPolicyStrategy exceptionPolicyStrategy, Predicate retryWhile, ScheduledExecutorService executorService) {
 
-        super(camelContext, output, logger, redeliveryProcessor, redeliveryPolicy, null, null, false, retryWhile, executorService);
+        super(camelContext, output, logger, redeliveryProcessor, redeliveryPolicy, null, null, true, false, retryWhile, executorService);
         setExceptionPolicy(exceptionPolicyStrategy);
     }
 

http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/camel-core/src/main/java/org/apache/camel/processor/FatalFallbackErrorHandler.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/processor/FatalFallbackErrorHandler.java b/camel-core/src/main/java/org/apache/camel/processor/FatalFallbackErrorHandler.java
index b9feb8b..8d03d78 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/FatalFallbackErrorHandler.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/FatalFallbackErrorHandler.java
@@ -32,8 +32,15 @@ public class FatalFallbackErrorHandler extends DelegateAsyncProcessor implements
 
     private static final Logger LOG = LoggerFactory.getLogger(FatalFallbackErrorHandler.class);
 
+    private boolean logWarn;
+
     public FatalFallbackErrorHandler(Processor processor) {
+        this(processor, false);
+    }
+
+    public FatalFallbackErrorHandler(Processor processor, boolean logWarn) {
         super(processor);
+        this.logWarn = logWarn;
     }
 
     @Override
@@ -50,12 +57,12 @@ public class FatalFallbackErrorHandler extends DelegateAsyncProcessor implements
                             + exchange.getExchangeId() + " using: [" + processor + "].";
                     if (previous != null) {
                         msg += " The previous and the new exception will be logged in the following.";
-                        LOG.error(msg);
-                        LOG.error("\\--> Previous exception on exchangeId: " + exchange.getExchangeId() , previous);
-                        LOG.error("\\--> New exception on exchangeId: " + exchange.getExchangeId(), exchange.getException());
+                        log(msg);
+                        log("\\--> Previous exception on exchangeId: " + exchange.getExchangeId(), previous);
+                        log("\\--> New exception on exchangeId: " + exchange.getExchangeId(), exchange.getException());
                     } else {
-                        LOG.error(msg);
-                        LOG.error("\\--> New exception on exchangeId: " + exchange.getExchangeId(), exchange.getException());
+                        log(msg);
+                        log("\\--> New exception on exchangeId: " + exchange.getExchangeId(), exchange.getException());
                     }
 
                     // we can propagated that exception to the caught property on the exchange
@@ -75,6 +82,26 @@ public class FatalFallbackErrorHandler extends DelegateAsyncProcessor implements
         return sync;
     }
 
+    private void log(String message) {
+        log(message, null);
+    }
+
+    private void log(String message, Throwable t) {
+        if (logWarn) {
+            if (t != null) {
+                LOG.warn(message, t);
+            } else {
+                LOG.warn(message);
+            }
+        } else {
+            if (t != null) {
+                LOG.error(message, t);
+            } else {
+                LOG.error(message);
+            }
+        }
+    }
+
     @Override
     public String toString() {
         return "FatalFallbackErrorHandler[" + processor + "]";

http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java b/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
index 1ea0fd3..c0a8c4f 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/RedeliveryErrorHandler.java
@@ -62,6 +62,7 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
     protected final CamelContext camelContext;
     protected final Processor deadLetter;
     protected final String deadLetterUri;
+    protected final boolean deadLetterHandleNewException;
     protected final Processor output;
     protected final AsyncProcessor outputAsync;
     protected final Processor redeliveryProcessor;
@@ -81,17 +82,29 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
         boolean sync = true;
         int redeliveryCounter;
         long redeliveryDelay;
-        Predicate retryWhilePredicate = retryWhilePolicy;
+        Predicate retryWhilePredicate;
         boolean redeliverFromSync;
 
         // default behavior which can be overloaded on a per exception basis
-        RedeliveryPolicy currentRedeliveryPolicy = redeliveryPolicy;
-        Processor deadLetterProcessor = deadLetter;
+        RedeliveryPolicy currentRedeliveryPolicy;
+        Processor deadLetterProcessor;
         Processor failureProcessor;
-        Processor onRedeliveryProcessor = redeliveryProcessor;
-        Predicate handledPredicate = getDefaultHandledPredicate();
+        Processor onRedeliveryProcessor;
+        Predicate handledPredicate;
         Predicate continuedPredicate;
-        boolean useOriginalInMessage = useOriginalMessagePolicy;
+        boolean useOriginalInMessage;
+        boolean handleNewException;
+
+        public RedeliveryData() {
+            // init with values from the error handler
+            this.retryWhilePredicate = retryWhilePolicy;
+            this.currentRedeliveryPolicy = redeliveryPolicy;
+            this.deadLetterProcessor = deadLetter;
+            this.onRedeliveryProcessor = redeliveryProcessor;
+            this.handledPredicate = getDefaultHandledPredicate();
+            this.useOriginalInMessage = useOriginalMessagePolicy;
+            this.handleNewException = deadLetterHandleNewException;
+        }
     }
 
     /**
@@ -182,7 +195,7 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
 
     public RedeliveryErrorHandler(CamelContext camelContext, Processor output, CamelLogger logger,
             Processor redeliveryProcessor, RedeliveryPolicy redeliveryPolicy, Processor deadLetter,
-            String deadLetterUri, boolean useOriginalMessagePolicy, Predicate retryWhile, ScheduledExecutorService executorService) {
+            String deadLetterUri, boolean deadLetterHandleNewException, boolean useOriginalMessagePolicy, Predicate retryWhile, ScheduledExecutorService executorService) {
 
         ObjectHelper.notNull(camelContext, "CamelContext", this);
         ObjectHelper.notNull(redeliveryPolicy, "RedeliveryPolicy", this);
@@ -195,6 +208,7 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
         this.redeliveryPolicy = redeliveryPolicy;
         this.logger = logger;
         this.deadLetterUri = deadLetterUri;
+        this.deadLetterHandleNewException = deadLetterHandleNewException;
         this.useOriginalMessagePolicy = useOriginalMessagePolicy;
         this.retryWhilePolicy = retryWhile;
         this.executorService = executorService;
@@ -693,7 +707,7 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
         msg = msg + ". Handled and continue routing.";
 
         // log that we failed but want to continue
-        logFailedDelivery(false, false, true, exchange, msg, data, null);
+        logFailedDelivery(false, false, false, true, exchange, msg, data, null);
     }
 
     protected void prepareExchangeForRedelivery(Exchange exchange, RedeliveryData data) {
@@ -777,7 +791,7 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
         if (!ExchangeHelper.isFailureHandled(exchange) && !ExchangeHelper.isUnitOfWorkExhausted(exchange)) {
             String msg = "Failed delivery for " + ExchangeHelper.logIds(exchange)
                     + ". On delivery attempt: " + data.redeliveryCounter + " caught: " + e;
-            logFailedDelivery(true, false, false, exchange, msg, data, e);
+            logFailedDelivery(true, false, false, false, exchange, msg, data, e);
         }
 
         data.redeliveryCounter = incrementRedeliveryCounter(exchange, e, data);
@@ -876,9 +890,9 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
                 public void done(boolean sync) {
                     log.trace("Failure processor done: {} processing Exchange: {}", processor, exchange);
                     try {
-                        prepareExchangeAfterFailure(exchange, data, shouldHandle, shouldContinue);
+                        prepareExchangeAfterFailure(exchange, data, isDeadLetterChannel, shouldHandle, shouldContinue);
                         // fire event as we had a failure processor to handle it, which there is a event for
-                        boolean deadLetterChannel = processor == data.deadLetterProcessor && data.deadLetterProcessor != null;
+                        boolean deadLetterChannel = processor == data.deadLetterProcessor;
                         EventHelper.notifyExchangeFailureHandled(exchange.getContext(), exchange, processor, deadLetterChannel);
                     } finally {
                         // if the fault was handled asynchronously, this should be reflected in the callback as well
@@ -890,7 +904,7 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
         } else {
             try {
                 // no processor but we need to prepare after failure as well
-                prepareExchangeAfterFailure(exchange, data, shouldHandle, shouldContinue);
+                prepareExchangeAfterFailure(exchange, data, isDeadLetterChannel, shouldHandle, shouldContinue);
             } finally {
                 // callback we are done
                 callback.done(data.sync);
@@ -905,24 +919,40 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
         }
 
         // log that we failed delivery as we are exhausted
-        logFailedDelivery(false, handled, false, exchange, msg, data, null);
+        logFailedDelivery(false, false, handled, false, exchange, msg, data, null);
 
         return sync;
     }
 
     protected void prepareExchangeAfterFailure(final Exchange exchange, final RedeliveryData data,
-                                               final boolean shouldHandle, final boolean shouldContinue) {
+                                               final boolean isDeadLetterChannel, final boolean shouldHandle, final boolean shouldContinue) {
+
+        Exception newException = exchange.getException();
+
         // we could not process the exchange so we let the failure processor handled it
         ExchangeHelper.setFailureHandled(exchange);
 
+        if (isDeadLetterChannel && shouldHandle) {
+            if (data.handleNewException) {
+                // if there is a new exception then log a warning about that
+                String msg = "DeadLetterChannel failed processing exchange due new exception: " + newException.getMessage()
+                        + ". This new exception is handled and ignored. The option deadLetterChannelHandleNewException can be turned off to not handle new exceptions";
+                logFailedDelivery(false, true, false, false, exchange, msg, data, newException);
+            } else {
+                // exception not handled, put exception back in the exchange
+                exchange.setException(exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class));
+                // and put failure endpoint back as well
+                exchange.setProperty(Exchange.FAILURE_ENDPOINT, exchange.getProperty(Exchange.TO_ENDPOINT));
+            }
+            return;
+        }
+
         // honor if already set a handling
         boolean alreadySet = exchange.getProperty(Exchange.ERRORHANDLER_HANDLED) != null;
         if (alreadySet) {
             boolean handled = exchange.getProperty(Exchange.ERRORHANDLER_HANDLED, Boolean.class);
             log.trace("This exchange has already been marked for handling: {}", handled);
-            if (handled) {
-                exchange.setException(null);
-            } else {
+            if (!handled) {
                 // exception not handled, put exception back in the exchange
                 exchange.setException(exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class));
                 // and put failure endpoint back as well
@@ -953,12 +983,23 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
         }
     }
 
-    private void logFailedDelivery(boolean shouldRedeliver, boolean handled, boolean continued, Exchange exchange, String message, RedeliveryData data, Throwable e) {
+    private void logFailedDelivery(boolean shouldRedeliver, boolean newException, boolean handled, boolean continued, Exchange exchange, String message, RedeliveryData data, Throwable e) {
         if (logger == null) {
             return;
         }
 
         if (!exchange.isRollbackOnly()) {
+            if (newException && !data.currentRedeliveryPolicy.isLogNewException()) {
+                // do not log new exception
+                return;
+            }
+
+            // if we should not rollback, then check whether logging is enabled
+            if (handled && !data.currentRedeliveryPolicy.isLogHandled()) {
+                // do not log handled
+                return;
+            }
+
             // if we should not rollback, then check whether logging is enabled
             if (handled && !data.currentRedeliveryPolicy.isLogHandled()) {
                 // do not log handled
@@ -997,7 +1038,15 @@ public abstract class RedeliveryErrorHandler extends ErrorHandlerSupport impleme
             e = exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Exception.class);
         }
 
-        if (exchange.isRollbackOnly()) {
+        if (newException) {
+            // special for logging the new exception
+            String msg = message + " " + ExchangeHelper.logIds(exchange);
+            if (e != null && logStackTrace) {
+                logger.log(msg, e, newLogLevel);
+            } else {
+                logger.log(msg, newLogLevel);
+            }
+        } else if (exchange.isRollbackOnly()) {
             String msg = "Rollback " + ExchangeHelper.logIds(exchange);
             Throwable cause = exchange.getException() != null ? exchange.getException() : exchange.getProperty(Exchange.EXCEPTION_CAUGHT, Throwable.class);
             if (cause != null) {

http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/camel-core/src/main/java/org/apache/camel/processor/RedeliveryPolicy.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/processor/RedeliveryPolicy.java b/camel-core/src/main/java/org/apache/camel/processor/RedeliveryPolicy.java
index ab25bf2..7a62d5c 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/RedeliveryPolicy.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/RedeliveryPolicy.java
@@ -94,6 +94,7 @@ public class RedeliveryPolicy implements Cloneable, Serializable {
     protected boolean logHandled;
     protected boolean logContinued;
     protected boolean logExhausted = true;
+    protected boolean logNewException = true;
     protected boolean logExhaustedMessageHistory = true;
     protected boolean logRetryAttempted = true;
     protected String delayPattern;
@@ -119,6 +120,7 @@ public class RedeliveryPolicy implements Cloneable, Serializable {
             + ", logHandled=" + logHandled
             + ", logContinued=" + logContinued
             + ", logExhausted=" + logExhausted
+            + ", logNewException=" + logNewException
             + ", logExhaustedMessageHistory=" + logExhaustedMessageHistory
             + ", useExponentialBackOff="  + useExponentialBackOff
             + ", backOffMultiplier=" + backOffMultiplier
@@ -377,6 +379,14 @@ public class RedeliveryPolicy implements Cloneable, Serializable {
     }
 
     /**
+     * Sets whether errors should be logged when a new exception occurred during handling a previous exception
+     */
+    public RedeliveryPolicy logNewException(boolean logNewException) {
+        setLogNewException(logNewException);
+        return this;
+    }
+
+    /**
      * Sets whether to log exhausted errors
      */
     public RedeliveryPolicy logExhausted(boolean logExhausted) {
@@ -630,6 +640,17 @@ public class RedeliveryPolicy implements Cloneable, Serializable {
         this.logHandled = logHandled;
     }
 
+    public boolean isLogNewException() {
+        return logNewException;
+    }
+
+    /**
+     * Sets whether errors should be logged when a new exception occurred during handling a previous exception
+     */
+    public void setLogNewException(boolean logNewException) {
+        this.logNewException = logNewException;
+    }
+
     public boolean isLogContinued() {
         return logContinued;
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/camel-core/src/main/java/org/apache/camel/processor/SendProcessor.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/processor/SendProcessor.java b/camel-core/src/main/java/org/apache/camel/processor/SendProcessor.java
index 59ceb85..9b9e0d3 100644
--- a/camel-core/src/main/java/org/apache/camel/processor/SendProcessor.java
+++ b/camel-core/src/main/java/org/apache/camel/processor/SendProcessor.java
@@ -57,22 +57,16 @@ public class SendProcessor extends ServiceSupport implements AsyncProcessor, Tra
     protected AsyncProcessor producer;
     protected Endpoint destination;
     protected ExchangePattern destinationExchangePattern;
-    protected final boolean unhandleException;
 
     public SendProcessor(Endpoint destination) {
         this(destination, null);
     }
 
     public SendProcessor(Endpoint destination, ExchangePattern pattern) {
-        this(destination, pattern, false);
-    }
-    
-    public SendProcessor(Endpoint destination, ExchangePattern pattern, boolean unhandleException) {
         ObjectHelper.notNull(destination, "destination");
         this.destination = destination;
         this.camelContext = destination.getCamelContext();
         this.pattern = pattern;
-        this.unhandleException = unhandleException;
         try {
             this.destinationExchangePattern = null;
             this.destinationExchangePattern = EndpointHelper.resolveExchangePatternFromUrl(destination.getEndpointUri());
@@ -142,14 +136,12 @@ public class SendProcessor extends ServiceSupport implements AsyncProcessor, Tra
                             long timeTaken = watch.stop();
                             EventHelper.notifyExchangeSent(target.getContext(), target, destination, timeTaken);
                         } finally {
-                            checkException(target);
                             callback.done(doneSync);
                         }
                     }
                 });
             } catch (Throwable throwable) {
                 exchange.setException(throwable);
-                checkException(exchange);
                 callback.done(sync);
             }
 
@@ -166,7 +158,6 @@ public class SendProcessor extends ServiceSupport implements AsyncProcessor, Tra
                     public void done(boolean doneSync) {
                         // restore previous MEP
                         target.setPattern(existingPattern);
-                        checkException(target);
                         // signal we are done
                         callback.done(doneSync);
                     }
@@ -175,15 +166,6 @@ public class SendProcessor extends ServiceSupport implements AsyncProcessor, Tra
         });
     }
     
-    protected void checkException(Exchange exchange) {
-        if (unhandleException && exchange.getException() != null) {
-            // Override the default setting of DeadLetterChannel
-            exchange.setProperty(Exchange.ERRORHANDLER_HANDLED, "false");
-            // just override the exception with the new added
-            exchange.setProperty(Exchange.EXCEPTION_CAUGHT, exchange.getException());
-        }
-    }
-
     public Endpoint getDestination() {
         return destination;
     }

http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/components/camel-jms/src/test/java/org/apache/camel/component/jms/CamelJmsTestHelper.java
----------------------------------------------------------------------
diff --git a/components/camel-jms/src/test/java/org/apache/camel/component/jms/CamelJmsTestHelper.java b/components/camel-jms/src/test/java/org/apache/camel/component/jms/CamelJmsTestHelper.java
index e8d1b3a..121f905 100644
--- a/components/camel-jms/src/test/java/org/apache/camel/component/jms/CamelJmsTestHelper.java
+++ b/components/camel-jms/src/test/java/org/apache/camel/component/jms/CamelJmsTestHelper.java
@@ -37,7 +37,7 @@ public final class CamelJmsTestHelper {
     }
 
     public static PooledConnectionFactory createPooledConnectionFactory() {
-        ConnectionFactory cf = createConnectionFactory(null);
+        ConnectionFactory cf = createConnectionFactory(null, null);
         PooledConnectionFactory pooled = new PooledConnectionFactory();
         pooled.setConnectionFactory(cf);
         pooled.setMaxConnections(8);
@@ -45,10 +45,10 @@ public final class CamelJmsTestHelper {
     }
 
     public static ConnectionFactory createConnectionFactory() {
-        return createConnectionFactory(null);
+        return createConnectionFactory(null, null);
     }
 
-    public static ConnectionFactory createConnectionFactory(String options) {
+    public static ConnectionFactory createConnectionFactory(String options, Integer maximumRedeliveries) {
         // using a unique broker name improves testing when running the entire test suite in the same JVM
         int id = counter.incrementAndGet();
         String url = "vm://test-broker-" + id + "?broker.persistent=false&broker.useJmx=false";
@@ -65,6 +65,9 @@ public final class CamelJmsTestHelper {
         // Another way of guaranteeing order is to use persistent messages or transactions.
         connectionFactory.setUseAsyncSend(false);
         connectionFactory.setAlwaysSessionAsync(false);
+        if (maximumRedeliveries != null) {
+            connectionFactory.getRedeliveryPolicy().setMaximumRedeliveries(maximumRedeliveries);
+        }
         return connectionFactory;
     }
 

http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsDeadLetterChannelHandlerExceptionTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsDeadLetterChannelHandlerExceptionTest.java b/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsDeadLetterChannelHandlerExceptionTest.java
deleted file mode 100644
index 8604e87..0000000
--- a/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsDeadLetterChannelHandlerExceptionTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.camel.component.jms.issues;
-
-
-import java.util.UUID;
-
-import javax.jms.ConnectionFactory;
-
-import org.apache.camel.CamelContext;
-import org.apache.camel.Exchange;
-import org.apache.camel.Handler;
-import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.component.jms.CamelJmsTestHelper;
-import org.apache.camel.test.junit4.CamelTestSupport;
-import org.junit.Test;
-
-import static org.apache.camel.component.jms.JmsComponent.jmsComponentTransacted;
-
-public class JmsDeadLetterChannelHandlerExceptionTest extends CamelTestSupport {
-    
-    public static class BadErrorHandler {
-        @Handler
-        public void onException(Exchange exchange, Exception exception) throws Exception {
-            
-            throw new RuntimeException("error in errorhandler");
-        }
-    }
-   
-    private final String testingEndpoint = "activemq:test." + getClass().getName();
-
-    @Override
-    protected RouteBuilder createRouteBuilder() throws Exception {
-        return new RouteBuilder() {
-            @Override
-            public void configure() throws Exception {
-                
-                errorHandler(deadLetterChannel("bean:" + BadErrorHandler.class.getName()).checkException());
-
-                from(testingEndpoint).throwException(new RuntimeException("bad error"));
-                
-                
-            }
-        };
-    }
-
-    @Test
-    public void shouldNotLoseMessagesOnExceptionInErrorHandler() throws Exception {
-        UUID message = UUID.randomUUID();
-        template.sendBody(testingEndpoint, message);
-
-        Object dlqBody = consumer.receiveBody("activemq:ActiveMQ.DLQ", 3000);
-
-        assertEquals(message, dlqBody);
-    }
-
-    protected CamelContext createCamelContext() throws Exception {
-        CamelContext camelContext = super.createCamelContext();
-        ConnectionFactory connectionFactory = CamelJmsTestHelper.createConnectionFactory();
-        camelContext.addComponent("activemq", jmsComponentTransacted(connectionFactory));
-        return camelContext;
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedDeadLetterChannelHandlerRollbackOnExceptionTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedDeadLetterChannelHandlerRollbackOnExceptionTest.java b/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedDeadLetterChannelHandlerRollbackOnExceptionTest.java
new file mode 100644
index 0000000..9052144
--- /dev/null
+++ b/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedDeadLetterChannelHandlerRollbackOnExceptionTest.java
@@ -0,0 +1,84 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.jms.issues;
+
+import javax.jms.ConnectionFactory;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.Handler;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.jms.CamelJmsTestHelper;
+import org.apache.camel.component.jms.JmsComponent;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+import static org.apache.camel.component.jms.JmsComponent.jmsComponentTransacted;
+
+public class JmsTransactedDeadLetterChannelHandlerRollbackOnExceptionTest extends CamelTestSupport {
+    
+    public static class BadErrorHandler {
+        @Handler
+        public void onException(Exchange exchange, Exception exception) throws Exception {
+            throw new RuntimeException("error in errorhandler");
+        }
+    }
+   
+    protected final String testingEndpoint = "activemq:test." + getClass().getName();
+
+    protected boolean isHandleNew() {
+        return true;
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                // we use DLC to handle the exception but if it throw a new exception
+                // then the DLC handles that too (the transaction will always commit)
+                errorHandler(deadLetterChannel("bean:" + BadErrorHandler.class.getName())
+                        .deadLetterHandleNewException(isHandleNew()));
+
+                from(testingEndpoint)
+                    .log("Incoming JMS message ${body}")
+                    .throwException(new RuntimeException("bad error"));
+            }
+        };
+    }
+
+    @Test
+    public void shouldNotLoseMessagesOnExceptionInErrorHandler() throws Exception {
+        template.sendBody(testingEndpoint, "Hello World");
+
+        // as we handle new exception, then the exception is ignored
+        // and causes the transaction to commit, so there is no message in the ActiveMQ DLQ queue
+        Object dlqBody = consumer.receiveBody("activemq:ActiveMQ.DLQ", 2000);
+        assertNull("Should not rollback the transaction", dlqBody);
+    }
+
+    protected CamelContext createCamelContext() throws Exception {
+        CamelContext camelContext = super.createCamelContext();
+
+        // no redeliveries
+        ConnectionFactory connectionFactory = CamelJmsTestHelper.createConnectionFactory(null, 0);
+        JmsComponent component = jmsComponentTransacted(connectionFactory);
+        camelContext.addComponent("activemq", component);
+        return camelContext;
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedDeadLetterChannelNotHandlerRollbackOnExceptionTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedDeadLetterChannelNotHandlerRollbackOnExceptionTest.java b/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedDeadLetterChannelNotHandlerRollbackOnExceptionTest.java
new file mode 100644
index 0000000..5701a71
--- /dev/null
+++ b/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedDeadLetterChannelNotHandlerRollbackOnExceptionTest.java
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.jms.issues;
+
+import org.junit.Test;
+
+public class JmsTransactedDeadLetterChannelNotHandlerRollbackOnExceptionTest extends JmsTransactedDeadLetterChannelHandlerRollbackOnExceptionTest {
+
+    @Override
+    protected boolean isHandleNew() {
+        return false;
+    }
+
+    @Test
+    public void shouldNotLoseMessagesOnExceptionInErrorHandler() throws Exception {
+        template.sendBody(testingEndpoint, "Hello World");
+
+        // as we do not handle new exception, then the exception propagates back
+        // and causes the transaction to rollback, and we can find the message in the ActiveMQ DLQ
+        Object dlqBody = consumer.receiveBody("activemq:ActiveMQ.DLQ", 2000);
+        assertEquals("Hello World", dlqBody);
+    }
+
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedOnExceptionRollbackOnExceptionTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedOnExceptionRollbackOnExceptionTest.java b/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedOnExceptionRollbackOnExceptionTest.java
new file mode 100644
index 0000000..4360436
--- /dev/null
+++ b/components/camel-jms/src/test/java/org/apache/camel/component/jms/issues/JmsTransactedOnExceptionRollbackOnExceptionTest.java
@@ -0,0 +1,77 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.jms.issues;
+
+import javax.jms.ConnectionFactory;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Exchange;
+import org.apache.camel.Handler;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.jms.CamelJmsTestHelper;
+import org.apache.camel.component.jms.JmsComponent;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+import static org.apache.camel.component.jms.JmsComponent.jmsComponentTransacted;
+
+public class JmsTransactedOnExceptionRollbackOnExceptionTest extends CamelTestSupport {
+    
+    public static class BadErrorHandler {
+        @Handler
+        public void onException(Exchange exchange, Exception exception) throws Exception {
+            throw new RuntimeException("error in errorhandler");
+        }
+    }
+   
+    protected final String testingEndpoint = "activemq:test." + getClass().getName();
+
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                // we attempt to handle the exception but if it throw a new exception
+                // then it causes the JMS transaction to rollback
+                onException(Exception.class).handled(true).bean(BadErrorHandler.class);
+
+                from(testingEndpoint)
+                    .log("Incoming JMS message ${body}")
+                    .throwException(new RuntimeException("bad error"));
+            }
+        };
+    }
+
+    @Test
+    public void shouldNotLoseMessagesOnExceptionInErrorHandler() throws Exception {
+        template.sendBody(testingEndpoint, "Hello World");
+
+        Object dlqBody = consumer.receiveBody("activemq:ActiveMQ.DLQ", 2000);
+        assertEquals("Hello World", dlqBody);
+    }
+
+    protected CamelContext createCamelContext() throws Exception {
+        CamelContext camelContext = super.createCamelContext();
+
+        // no redeliveries
+        ConnectionFactory connectionFactory = CamelJmsTestHelper.createConnectionFactory(null, 0);
+        JmsComponent component = jmsComponentTransacted(connectionFactory);
+        camelContext.addComponent("activemq", component);
+        return camelContext;
+    }
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/camel/blob/b05668f7/components/camel-jms/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/components/camel-jms/src/test/resources/log4j.properties b/components/camel-jms/src/test/resources/log4j.properties
index 4732904..14beeb0 100644
--- a/components/camel-jms/src/test/resources/log4j.properties
+++ b/components/camel-jms/src/test/resources/log4j.properties
@@ -18,7 +18,7 @@
 #
 # The logging properties used
 #
-log4j.rootLogger=INFO, out
+log4j.rootLogger=INFO, stdout
 
 #log4j.logger.org.apache.activemq.spring=WARN
 #log4j.logger.org.apache.camel.component.jms=DEBUG


Mime
View raw message