SPR-6142 Moved ErrorHandler strategy interface to the org.springframework.util package so that it can be used by MessageListener containers in addition to TaskSchedulers.
This commit is contained in:
parent
e2c36fd592
commit
dedecf7ae9
|
|
@ -27,9 +27,9 @@ import commonj.timers.TimerListener;
|
||||||
|
|
||||||
import org.springframework.scheduling.TaskScheduler;
|
import org.springframework.scheduling.TaskScheduler;
|
||||||
import org.springframework.scheduling.Trigger;
|
import org.springframework.scheduling.Trigger;
|
||||||
import org.springframework.scheduling.support.DelegatingErrorHandlingRunnable;
|
|
||||||
import org.springframework.scheduling.support.ErrorHandler;
|
|
||||||
import org.springframework.scheduling.support.SimpleTriggerContext;
|
import org.springframework.scheduling.support.SimpleTriggerContext;
|
||||||
|
import org.springframework.scheduling.support.TaskUtils;
|
||||||
|
import org.springframework.util.ErrorHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of Spring's {@link TaskScheduler} interface, wrapping
|
* Implementation of Spring's {@link TaskScheduler} interface, wrapping
|
||||||
|
|
@ -87,9 +87,7 @@ public class TimerManagerTaskScheduler extends TimerManagerAccessor implements T
|
||||||
}
|
}
|
||||||
|
|
||||||
private Runnable errorHandlingTask(Runnable delegate, boolean isRepeatingTask) {
|
private Runnable errorHandlingTask(Runnable delegate, boolean isRepeatingTask) {
|
||||||
ErrorHandler errorHandler = this.errorHandler != null ? this.errorHandler
|
return TaskUtils.decorateTaskWithErrorHandler(delegate, this.errorHandler, isRepeatingTask);
|
||||||
: (isRepeatingTask ? ErrorHandler.LOG_AND_SUPPRESS : ErrorHandler.LOG_AND_PROPAGATE);
|
|
||||||
return new DelegatingErrorHandlingRunnable(delegate, errorHandler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,9 @@ import java.util.concurrent.TimeUnit;
|
||||||
import org.springframework.core.task.TaskRejectedException;
|
import org.springframework.core.task.TaskRejectedException;
|
||||||
import org.springframework.scheduling.TaskScheduler;
|
import org.springframework.scheduling.TaskScheduler;
|
||||||
import org.springframework.scheduling.Trigger;
|
import org.springframework.scheduling.Trigger;
|
||||||
import org.springframework.scheduling.support.ErrorHandler;
|
import org.springframework.scheduling.support.TaskUtils;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.ErrorHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapter that takes a JDK 1.5 <code>java.util.concurrent.ScheduledExecutorService</code>
|
* Adapter that takes a JDK 1.5 <code>java.util.concurrent.ScheduledExecutorService</code>
|
||||||
|
|
@ -180,7 +181,7 @@ public class ConcurrentTaskScheduler extends ConcurrentTaskExecutor implements T
|
||||||
}
|
}
|
||||||
|
|
||||||
private Runnable errorHandlingTask(Runnable task, boolean isRepeatingTask) {
|
private Runnable errorHandlingTask(Runnable task, boolean isRepeatingTask) {
|
||||||
return TaskUtils.errorHandlingTask(task, this.errorHandler, isRepeatingTask);
|
return TaskUtils.decorateTaskWithErrorHandler(task, this.errorHandler, isRepeatingTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,8 @@ import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import org.springframework.scheduling.Trigger;
|
import org.springframework.scheduling.Trigger;
|
||||||
import org.springframework.scheduling.support.DelegatingErrorHandlingRunnable;
|
import org.springframework.scheduling.support.DelegatingErrorHandlingRunnable;
|
||||||
import org.springframework.scheduling.support.ErrorHandler;
|
|
||||||
import org.springframework.scheduling.support.SimpleTriggerContext;
|
import org.springframework.scheduling.support.SimpleTriggerContext;
|
||||||
|
import org.springframework.util.ErrorHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Internal adapter that reschedules an underlying {@link Runnable} according
|
* Internal adapter that reschedules an underlying {@link Runnable} according
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ import java.util.concurrent.ThreadFactory;
|
||||||
|
|
||||||
import org.springframework.beans.factory.FactoryBean;
|
import org.springframework.beans.factory.FactoryBean;
|
||||||
import org.springframework.scheduling.support.DelegatingErrorHandlingRunnable;
|
import org.springframework.scheduling.support.DelegatingErrorHandlingRunnable;
|
||||||
import org.springframework.scheduling.support.ErrorHandler;
|
import org.springframework.scheduling.support.TaskUtils;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.ObjectUtils;
|
import org.springframework.util.ObjectUtils;
|
||||||
|
|
||||||
|
|
@ -196,8 +196,8 @@ public class ScheduledExecutorFactoryBean extends ExecutorConfigurationSupport
|
||||||
*/
|
*/
|
||||||
protected Runnable getRunnableToSchedule(ScheduledExecutorTask task) {
|
protected Runnable getRunnableToSchedule(ScheduledExecutorTask task) {
|
||||||
return this.continueScheduledExecutionAfterException
|
return this.continueScheduledExecutionAfterException
|
||||||
? new DelegatingErrorHandlingRunnable(task.getRunnable(), ErrorHandler.LOG_AND_SUPPRESS)
|
? new DelegatingErrorHandlingRunnable(task.getRunnable(), TaskUtils.LOG_AND_SUPPRESS_ERROR_HANDLER)
|
||||||
: new DelegatingErrorHandlingRunnable(task.getRunnable(), ErrorHandler.LOG_AND_PROPAGATE);
|
: new DelegatingErrorHandlingRunnable(task.getRunnable(), TaskUtils.LOG_AND_PROPAGATE_ERROR_HANDLER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2002-2009 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed 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.springframework.scheduling.concurrent;
|
|
||||||
|
|
||||||
import java.util.concurrent.Future;
|
|
||||||
|
|
||||||
import org.springframework.scheduling.support.DelegatingErrorHandlingRunnable;
|
|
||||||
import org.springframework.scheduling.support.ErrorHandler;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Mark Fisher
|
|
||||||
* @since 3.0
|
|
||||||
*/
|
|
||||||
abstract class TaskUtils {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decorates the task for error handling. If the provided
|
|
||||||
* {@link ErrorHandler} is not null, it will be used. Otherwise,
|
|
||||||
* repeating tasks will have errors suppressed by default whereas
|
|
||||||
* one-shot tasks will have errors propagated by default since those
|
|
||||||
* errors may be expected through the returned {@link Future}. In both
|
|
||||||
* cases, the errors will be logged.
|
|
||||||
*/
|
|
||||||
static DelegatingErrorHandlingRunnable errorHandlingTask(
|
|
||||||
Runnable task, ErrorHandler errorHandler, boolean isRepeatingTask) {
|
|
||||||
|
|
||||||
if (task instanceof DelegatingErrorHandlingRunnable) {
|
|
||||||
return (DelegatingErrorHandlingRunnable) task;
|
|
||||||
}
|
|
||||||
ErrorHandler eh = errorHandler != null ? errorHandler : getDefaultErrorHandler(isRepeatingTask);
|
|
||||||
return new DelegatingErrorHandlingRunnable(task, eh);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ErrorHandler getDefaultErrorHandler(boolean isRepeatingTask) {
|
|
||||||
return (isRepeatingTask ? ErrorHandler.LOG_AND_SUPPRESS : ErrorHandler.LOG_AND_PROPAGATE);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -33,8 +33,9 @@ import org.springframework.core.task.TaskRejectedException;
|
||||||
import org.springframework.scheduling.SchedulingTaskExecutor;
|
import org.springframework.scheduling.SchedulingTaskExecutor;
|
||||||
import org.springframework.scheduling.TaskScheduler;
|
import org.springframework.scheduling.TaskScheduler;
|
||||||
import org.springframework.scheduling.Trigger;
|
import org.springframework.scheduling.Trigger;
|
||||||
import org.springframework.scheduling.support.ErrorHandler;
|
import org.springframework.scheduling.support.TaskUtils;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.ErrorHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of Spring's {@link TaskScheduler} interface, wrapping
|
* Implementation of Spring's {@link TaskScheduler} interface, wrapping
|
||||||
|
|
@ -221,7 +222,7 @@ public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupport
|
||||||
}
|
}
|
||||||
|
|
||||||
private Runnable errorHandlingTask(Runnable task, boolean isRepeatingTask) {
|
private Runnable errorHandlingTask(Runnable task, boolean isRepeatingTask) {
|
||||||
return TaskUtils.errorHandlingTask(task, this.errorHandler, isRepeatingTask);
|
return TaskUtils.decorateTaskWithErrorHandler(task, this.errorHandler, isRepeatingTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
package org.springframework.scheduling.support;
|
package org.springframework.scheduling.support;
|
||||||
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.ErrorHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runnable wrapper that catches any exception or error thrown from its
|
* Runnable wrapper that catches any exception or error thrown from its
|
||||||
|
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2002-2009 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed 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.springframework.scheduling.support;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A strategy for handling errors that occur during asynchronous
|
|
||||||
* execution of tasks that have been submitted to a TaskScheduler.
|
|
||||||
*
|
|
||||||
* @author Mark Fisher
|
|
||||||
* @since 3.0.
|
|
||||||
*/
|
|
||||||
public interface ErrorHandler {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An ErrorHandler strategy that will log the Exception but perform
|
|
||||||
* no further handling. This will suppress the error so that
|
|
||||||
* subsequent executions of the task will not be prevented.
|
|
||||||
*/
|
|
||||||
static final ErrorHandler LOG_AND_SUPPRESS = new LoggingErrorHandler();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An ErrorHandler strategy that will log at error level and then
|
|
||||||
* re-throw the Exception. Note: this will typically prevent subsequent
|
|
||||||
* execution of a scheduled task.
|
|
||||||
*/
|
|
||||||
static final ErrorHandler LOG_AND_PROPAGATE = new PropagatingErrorHandler();
|
|
||||||
|
|
||||||
|
|
||||||
void handleError(Throwable t);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2002-2009 the original author or authors.
|
|
||||||
*
|
|
||||||
* Licensed 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.springframework.scheduling.support;
|
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An {@link ErrorHandler} implementation that logs the Throwable at error
|
|
||||||
* level. It does not perform any additional error handling. This can be
|
|
||||||
* useful when suppression of errors is the intended behavior.
|
|
||||||
*
|
|
||||||
* @author Mark Fisher
|
|
||||||
* @since 3.0
|
|
||||||
*/
|
|
||||||
class LoggingErrorHandler implements ErrorHandler {
|
|
||||||
|
|
||||||
private final Log logger = LogFactory.getLog(LoggingErrorHandler.class);
|
|
||||||
|
|
||||||
public void handleError(Throwable t) {
|
|
||||||
if (logger.isErrorEnabled()) {
|
|
||||||
logger.error("Unexpected error occurred in scheduled task.", t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,104 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2009 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed 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.springframework.scheduling.support;
|
||||||
|
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import org.springframework.util.ErrorHandler;
|
||||||
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility methods for decorating tasks with error handling.
|
||||||
|
*
|
||||||
|
* @author Mark Fisher
|
||||||
|
* @since 3.0
|
||||||
|
*/
|
||||||
|
public abstract class TaskUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An ErrorHandler strategy that will log the Exception but perform
|
||||||
|
* no further handling. This will suppress the error so that
|
||||||
|
* subsequent executions of the task will not be prevented.
|
||||||
|
*/
|
||||||
|
public static final ErrorHandler LOG_AND_SUPPRESS_ERROR_HANDLER = new LoggingErrorHandler();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An ErrorHandler strategy that will log at error level and then
|
||||||
|
* re-throw the Exception. Note: this will typically prevent subsequent
|
||||||
|
* execution of a scheduled task.
|
||||||
|
*/
|
||||||
|
public static final ErrorHandler LOG_AND_PROPAGATE_ERROR_HANDLER = new PropagatingErrorHandler();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decorates the task for error handling. If the provided
|
||||||
|
* {@link ErrorHandler} is not null, it will be used. Otherwise,
|
||||||
|
* repeating tasks will have errors suppressed by default whereas
|
||||||
|
* one-shot tasks will have errors propagated by default since those
|
||||||
|
* errors may be expected through the returned {@link Future}. In both
|
||||||
|
* cases, the errors will be logged.
|
||||||
|
*/
|
||||||
|
public static DelegatingErrorHandlingRunnable decorateTaskWithErrorHandler(
|
||||||
|
Runnable task, ErrorHandler errorHandler, boolean isRepeatingTask) {
|
||||||
|
|
||||||
|
if (task instanceof DelegatingErrorHandlingRunnable) {
|
||||||
|
return (DelegatingErrorHandlingRunnable) task;
|
||||||
|
}
|
||||||
|
ErrorHandler eh = errorHandler != null ? errorHandler : getDefaultErrorHandler(isRepeatingTask);
|
||||||
|
return new DelegatingErrorHandlingRunnable(task, eh);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ErrorHandler getDefaultErrorHandler(boolean isRepeatingTask) {
|
||||||
|
return (isRepeatingTask ? LOG_AND_SUPPRESS_ERROR_HANDLER : LOG_AND_PROPAGATE_ERROR_HANDLER);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An {@link ErrorHandler} implementation that logs the Throwable at error
|
||||||
|
* level. It does not perform any additional error handling. This can be
|
||||||
|
* useful when suppression of errors is the intended behavior.
|
||||||
|
*/
|
||||||
|
static class LoggingErrorHandler implements ErrorHandler {
|
||||||
|
|
||||||
|
private final Log logger = LogFactory.getLog(LoggingErrorHandler.class);
|
||||||
|
|
||||||
|
public void handleError(Throwable t) {
|
||||||
|
if (logger.isErrorEnabled()) {
|
||||||
|
logger.error("Unexpected error occurred in scheduled task.", t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An {@link ErrorHandler} implementation that logs the Throwable at error
|
||||||
|
* level and then propagates it.
|
||||||
|
*/
|
||||||
|
static class PropagatingErrorHandler extends LoggingErrorHandler {
|
||||||
|
|
||||||
|
public void handleError(Throwable t) {
|
||||||
|
super.handleError(t);
|
||||||
|
ReflectionUtils.rethrowRuntimeException(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -34,7 +34,7 @@ import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.scheduling.Trigger;
|
import org.springframework.scheduling.Trigger;
|
||||||
import org.springframework.scheduling.TriggerContext;
|
import org.springframework.scheduling.TriggerContext;
|
||||||
import org.springframework.scheduling.support.ErrorHandler;
|
import org.springframework.util.ErrorHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Mark Fisher
|
* @author Mark Fisher
|
||||||
|
|
|
||||||
|
|
@ -14,22 +14,19 @@
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.scheduling.support;
|
package org.springframework.util;
|
||||||
|
|
||||||
import org.springframework.util.ReflectionUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An {@link ErrorHandler} implementation that logs the Throwable at error
|
* A strategy for handling errors. This is especially useful for handling
|
||||||
* level and then propagates it.
|
* errors that occur during asynchronous execution of tasks that have been
|
||||||
|
* submitted to a TaskScheduler. In such cases, it may not be possible to
|
||||||
|
* throw the error to the original caller.
|
||||||
*
|
*
|
||||||
* @author Mark Fisher
|
* @author Mark Fisher
|
||||||
* @since 3.0
|
* @since 3.0.
|
||||||
*/
|
*/
|
||||||
class PropagatingErrorHandler extends LoggingErrorHandler {
|
public interface ErrorHandler {
|
||||||
|
|
||||||
public void handleError(Throwable t) {
|
void handleError(Throwable t);
|
||||||
super.handleError(t);
|
|
||||||
ReflectionUtils.rethrowRuntimeException(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue