org.springframework.scheduling.support.TaskUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.springframework.scheduling.support.TaskUtils.java

Source

/*
 * Copyright 2002-2019 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
 *
 *      https://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.lang.Nullable;
import org.springframework.util.ErrorHandler;
import org.springframework.util.ReflectionUtils;

/**
 * Utility methods for decorating tasks with error handling.
 *
 * <p><b>NOTE:</b> This class is intended for internal use by Spring's scheduler
 * implementations. It is only public so that it may be accessed from impl classes
 * within other packages. It is <i>not</i> intended for general use.
 *
 * @author Mark Fisher
 * @author Juergen Hoeller
 * @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();

    /**
     * Decorate the task for error handling. If the provided {@link ErrorHandler}
     * is not {@code 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,
            @Nullable ErrorHandler errorHandler, boolean isRepeatingTask) {

        if (task instanceof DelegatingErrorHandlingRunnable) {
            return (DelegatingErrorHandlingRunnable) task;
        }
        ErrorHandler eh = (errorHandler != null ? errorHandler : getDefaultErrorHandler(isRepeatingTask));
        return new DelegatingErrorHandlingRunnable(task, eh);
    }

    /**
     * Return the default {@link ErrorHandler} implementation based on the boolean
     * value indicating whether the task will be repeating or not. For repeating tasks
     * it will suppress errors, but for one-time tasks it will propagate. In both
     * cases, the error will be logged.
     */
    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.
     */
    private static class LoggingErrorHandler implements ErrorHandler {

        private final Log logger = LogFactory.getLog(LoggingErrorHandler.class);

        @Override
        public void handleError(Throwable t) {
            logger.error("Unexpected error occurred in scheduled task", t);
        }
    }

    /**
     * An {@link ErrorHandler} implementation that logs the Throwable at error
     * level and then propagates it.
     */
    private static class PropagatingErrorHandler extends LoggingErrorHandler {

        @Override
        public void handleError(Throwable t) {
            super.handleError(t);
            ReflectionUtils.rethrowRuntimeException(t);
        }
    }

}