diff --git a/org.springframework.context.support/src/main/java/org/springframework/scheduling/commonj/TimerManagerTaskScheduler.java b/org.springframework.context.support/src/main/java/org/springframework/scheduling/commonj/TimerManagerTaskScheduler.java index 1a29e7d334c..d9cba9e5b82 100644 --- a/org.springframework.context.support/src/main/java/org/springframework/scheduling/commonj/TimerManagerTaskScheduler.java +++ b/org.springframework.context.support/src/main/java/org/springframework/scheduling/commonj/TimerManagerTaskScheduler.java @@ -27,9 +27,9 @@ import commonj.timers.TimerListener; import org.springframework.scheduling.TaskScheduler; 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.TaskUtils; +import org.springframework.util.ErrorHandler; /** * 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) { - ErrorHandler errorHandler = this.errorHandler != null ? this.errorHandler - : (isRepeatingTask ? ErrorHandler.LOG_AND_SUPPRESS : ErrorHandler.LOG_AND_PROPAGATE); - return new DelegatingErrorHandlingRunnable(delegate, errorHandler); + return TaskUtils.decorateTaskWithErrorHandler(delegate, this.errorHandler, isRepeatingTask); } diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskScheduler.java b/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskScheduler.java index db1bf1d43c7..bde333356fa 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskScheduler.java +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ConcurrentTaskScheduler.java @@ -27,8 +27,9 @@ import java.util.concurrent.TimeUnit; import org.springframework.core.task.TaskRejectedException; import org.springframework.scheduling.TaskScheduler; 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.ErrorHandler; /** * Adapter that takes a JDK 1.5 java.util.concurrent.ScheduledExecutorService @@ -180,7 +181,7 @@ public class ConcurrentTaskScheduler extends ConcurrentTaskExecutor implements T } private Runnable errorHandlingTask(Runnable task, boolean isRepeatingTask) { - return TaskUtils.errorHandlingTask(task, this.errorHandler, isRepeatingTask); + return TaskUtils.decorateTaskWithErrorHandler(task, this.errorHandler, isRepeatingTask); } } diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ReschedulingRunnable.java b/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ReschedulingRunnable.java index ce1324fdbb7..f63a77bb065 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ReschedulingRunnable.java +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ReschedulingRunnable.java @@ -26,8 +26,8 @@ import java.util.concurrent.TimeoutException; 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.util.ErrorHandler; /** * Internal adapter that reschedules an underlying {@link Runnable} according diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ScheduledExecutorFactoryBean.java b/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ScheduledExecutorFactoryBean.java index bccc9dec84a..8b152235f88 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ScheduledExecutorFactoryBean.java +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ScheduledExecutorFactoryBean.java @@ -25,7 +25,7 @@ import java.util.concurrent.ThreadFactory; import org.springframework.beans.factory.FactoryBean; 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.ObjectUtils; @@ -196,8 +196,8 @@ public class ScheduledExecutorFactoryBean extends ExecutorConfigurationSupport */ protected Runnable getRunnableToSchedule(ScheduledExecutorTask task) { return this.continueScheduledExecutionAfterException - ? new DelegatingErrorHandlingRunnable(task.getRunnable(), ErrorHandler.LOG_AND_SUPPRESS) - : new DelegatingErrorHandlingRunnable(task.getRunnable(), ErrorHandler.LOG_AND_PROPAGATE); + ? new DelegatingErrorHandlingRunnable(task.getRunnable(), TaskUtils.LOG_AND_SUPPRESS_ERROR_HANDLER) + : new DelegatingErrorHandlingRunnable(task.getRunnable(), TaskUtils.LOG_AND_PROPAGATE_ERROR_HANDLER); } diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/TaskUtils.java b/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/TaskUtils.java deleted file mode 100644 index c03792be83b..00000000000 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/TaskUtils.java +++ /dev/null @@ -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); - } - -} diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskScheduler.java b/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskScheduler.java index 42a01029350..ba49d36e779 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskScheduler.java +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/concurrent/ThreadPoolTaskScheduler.java @@ -33,8 +33,9 @@ import org.springframework.core.task.TaskRejectedException; import org.springframework.scheduling.SchedulingTaskExecutor; import org.springframework.scheduling.TaskScheduler; 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.ErrorHandler; /** * Implementation of Spring's {@link TaskScheduler} interface, wrapping @@ -221,7 +222,7 @@ public class ThreadPoolTaskScheduler extends ExecutorConfigurationSupport } private Runnable errorHandlingTask(Runnable task, boolean isRepeatingTask) { - return TaskUtils.errorHandlingTask(task, this.errorHandler, isRepeatingTask); + return TaskUtils.decorateTaskWithErrorHandler(task, this.errorHandler, isRepeatingTask); } diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/support/DelegatingErrorHandlingRunnable.java b/org.springframework.context/src/main/java/org/springframework/scheduling/support/DelegatingErrorHandlingRunnable.java index 30da07db14e..4702b73986f 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/support/DelegatingErrorHandlingRunnable.java +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/support/DelegatingErrorHandlingRunnable.java @@ -17,6 +17,7 @@ package org.springframework.scheduling.support; import org.springframework.util.Assert; +import org.springframework.util.ErrorHandler; /** * Runnable wrapper that catches any exception or error thrown from its diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/support/ErrorHandler.java b/org.springframework.context/src/main/java/org/springframework/scheduling/support/ErrorHandler.java deleted file mode 100644 index 783026afc80..00000000000 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/support/ErrorHandler.java +++ /dev/null @@ -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); - -} diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/support/LoggingErrorHandler.java b/org.springframework.context/src/main/java/org/springframework/scheduling/support/LoggingErrorHandler.java deleted file mode 100644 index 8afdb2b973e..00000000000 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/support/LoggingErrorHandler.java +++ /dev/null @@ -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); - } - } - -} diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/support/TaskUtils.java b/org.springframework.context/src/main/java/org/springframework/scheduling/support/TaskUtils.java new file mode 100644 index 00000000000..3b9bfc284a5 --- /dev/null +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/support/TaskUtils.java @@ -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); + } + + } + +} diff --git a/org.springframework.context/src/test/java/org/springframework/scheduling/concurrent/ThreadPoolTaskSchedulerTests.java b/org.springframework.context/src/test/java/org/springframework/scheduling/concurrent/ThreadPoolTaskSchedulerTests.java index f299e123082..dbf22d24a9c 100644 --- a/org.springframework.context/src/test/java/org/springframework/scheduling/concurrent/ThreadPoolTaskSchedulerTests.java +++ b/org.springframework.context/src/test/java/org/springframework/scheduling/concurrent/ThreadPoolTaskSchedulerTests.java @@ -34,7 +34,7 @@ import org.junit.Test; import org.springframework.scheduling.Trigger; import org.springframework.scheduling.TriggerContext; -import org.springframework.scheduling.support.ErrorHandler; +import org.springframework.util.ErrorHandler; /** * @author Mark Fisher diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/support/PropagatingErrorHandler.java b/org.springframework.core/src/main/java/org/springframework/util/ErrorHandler.java similarity index 62% rename from org.springframework.context/src/main/java/org/springframework/scheduling/support/PropagatingErrorHandler.java rename to org.springframework.core/src/main/java/org/springframework/util/ErrorHandler.java index c91ba940666..82c57f26f58 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/support/PropagatingErrorHandler.java +++ b/org.springframework.core/src/main/java/org/springframework/util/ErrorHandler.java @@ -14,22 +14,19 @@ * limitations under the License. */ -package org.springframework.scheduling.support; - -import org.springframework.util.ReflectionUtils; +package org.springframework.util; /** - * An {@link ErrorHandler} implementation that logs the Throwable at error - * level and then propagates it. + * A strategy for handling errors. This is especially useful for handling + * 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 - * @since 3.0 + * @since 3.0. */ -class PropagatingErrorHandler extends LoggingErrorHandler { +public interface ErrorHandler { - public void handleError(Throwable t) { - super.handleError(t); - ReflectionUtils.rethrowRuntimeException(t); - } + void handleError(Throwable t); }