diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/domain/JobExecution.java b/spring-batch-core/src/main/java/org/springframework/batch/core/domain/JobExecution.java index e3ed8f7c6..823a708eb 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/domain/JobExecution.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/domain/JobExecution.java @@ -66,7 +66,7 @@ public class JobExecution extends Entity { public JobExecution(JobInstance job) { this(job, null); } - + public Date getEndTime() { return endTime; } @@ -164,7 +164,7 @@ public class JobExecution extends Entity { * @return true if the end time is null */ public boolean isRunning() { - return endTime == null; + return endTime == null && !(BatchStatus.STOPPED==status); } /** @@ -177,5 +177,6 @@ public class JobExecution extends Entity { StepExecution stepExecution = (StepExecution) it.next(); stepExecution.setTerminateOnly(); } + status = BatchStatus.STOPPED; } } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/domain/StepInterruptedException.java b/spring-batch-core/src/main/java/org/springframework/batch/core/domain/JobInterruptedException.java similarity index 69% rename from spring-batch-core/src/main/java/org/springframework/batch/core/domain/StepInterruptedException.java rename to spring-batch-core/src/main/java/org/springframework/batch/core/domain/JobInterruptedException.java index 004b64a38..ab8afee72 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/domain/StepInterruptedException.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/domain/JobInterruptedException.java @@ -19,19 +19,19 @@ package org.springframework.batch.core.domain; import org.springframework.batch.io.exception.BatchCriticalException; /** - * Exception to indicate the the lifecycle has been interrupted. The exception - * state indicated is not normally recoverable by batch application clients, but - * internally it is useful to force a check. The exception will be wrapped in a - * runtime exception (usually {@link BatchCriticalException} before reaching the - * client. + * Exception to indicate the the job has been interrupted. The exception state + * indicated is not normally recoverable by batch application clients, but + * internally it is useful to force a check. The exception will often be wrapped + * in a runtime exception (usually {@link BatchCriticalException} before + * reaching the client. * * @author Lucas Ward * @author Dave Syer * */ -public class StepInterruptedException extends JobExecutionException { +public class JobInterruptedException extends JobExecutionException { - public StepInterruptedException(String msg) { + public JobInterruptedException(String msg) { super(msg); } } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/domain/Step.java b/spring-batch-core/src/main/java/org/springframework/batch/core/domain/Step.java index 62d488b3e..be33980d8 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/domain/Step.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/domain/Step.java @@ -62,10 +62,10 @@ public interface Step { * * @param stepExecution an entity representing the step to be executed * - * @throws StepInterruptedException if the step is interrupted externally + * @throws JobInterruptedException if the step is interrupted externally * @throws BatchCriticalException if there is a problem that needs to be * signalled to the caller */ - void execute(StepExecution stepExecution) throws StepInterruptedException, BatchCriticalException; + void execute(StepExecution stepExecution) throws JobInterruptedException, BatchCriticalException; } \ No newline at end of file diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/domain/StepSupport.java b/spring-batch-core/src/main/java/org/springframework/batch/core/domain/StepSupport.java index 9ccc76bed..420ac1aa3 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/domain/StepSupport.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/domain/StepSupport.java @@ -117,7 +117,7 @@ public class StepSupport implements Step, BeanNameAware { * * @see org.springframework.batch.core.domain.Step#execute(org.springframework.batch.core.domain.StepExecution) */ - public void execute(StepExecution stepExecution) throws StepInterruptedException, BatchCriticalException { + public void execute(StepExecution stepExecution) throws JobInterruptedException, BatchCriticalException { throw new UnsupportedOperationException( "Cannot process a StepExecution. Use a smarter subclass of StepSupport."); } diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/runtime/ExitCodeExceptionClassifier.java b/spring-batch-core/src/main/java/org/springframework/batch/core/runtime/ExitStatusExceptionClassifier.java similarity index 63% rename from spring-batch-core/src/main/java/org/springframework/batch/core/runtime/ExitCodeExceptionClassifier.java rename to spring-batch-core/src/main/java/org/springframework/batch/core/runtime/ExitStatusExceptionClassifier.java index 0b308c34a..15a1517a9 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/runtime/ExitCodeExceptionClassifier.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/runtime/ExitStatusExceptionClassifier.java @@ -19,21 +19,22 @@ import org.springframework.batch.common.ExceptionClassifier; import org.springframework.batch.repeat.ExitStatus; /** - * Extension of the ExceptionClassifier that explicitly deals with - * returns an ExitStatus. This is useful for mapping from an exception - * type to an Exit Code with a detailed message. + * Extension of the {@link ExceptionClassifier} that explicitly deals with + * returns an {@link ExitStatus}. This is useful for mapping from an exception + * type to an exit status with a customised code or detailed message. * * @author Lucas Ward - * + * */ -public interface ExitCodeExceptionClassifier extends ExceptionClassifier { +public interface ExitStatusExceptionClassifier extends ExceptionClassifier { + + public static final String FATAL_EXCEPTION = "FATAL_EXCEPTION"; + + public static final String JOB_INTERRUPTED = "JOB_INTERRUPTED"; - static final String FATAL_EXCEPTION = "FATAL_EXCEPTION"; - static final String STEP_INTERRUPTED = "STEP_INTERRUPTED"; - /** - * Typesafe version of classify that explicitly returns an {@link ExitStatus} - * object. + * Typesafe version of classify that explicitly returns an + * {@link ExitStatus} object. * * @param throwable * @return ExitStatus representing the ExitCode and Message for the given diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/domain/JobExecutionTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/domain/JobExecutionTests.java index 4aee15cf5..200bccefa 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/domain/JobExecutionTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/domain/JobExecutionTests.java @@ -57,6 +57,16 @@ public class JobExecutionTests extends TestCase { assertFalse(execution.isRunning()); } + /** + * Test method for + * {@link org.springframework.batch.core.domain.JobExecution#getEndTime()}. + */ + public void testIsRunningWithStoppedExecution() { + assertTrue(execution.isRunning()); + execution.stop(); + assertFalse(execution.isRunning()); + } + /** * Test method for * {@link org.springframework.batch.core.domain.JobExecution#getStartTime()}. diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/domain/StepInterruptedExceptionTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/domain/JobInterruptedExceptionTests.java similarity index 84% rename from spring-batch-core/src/test/java/org/springframework/batch/core/domain/StepInterruptedExceptionTests.java rename to spring-batch-core/src/test/java/org/springframework/batch/core/domain/JobInterruptedExceptionTests.java index b4ca19ba3..1fdc49a15 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/domain/StepInterruptedExceptionTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/domain/JobInterruptedExceptionTests.java @@ -16,19 +16,19 @@ package org.springframework.batch.core.domain; import org.springframework.batch.core.AbstractExceptionTests; -import org.springframework.batch.core.domain.StepInterruptedException; +import org.springframework.batch.core.domain.JobInterruptedException; /** * @author Dave Syer * */ -public class StepInterruptedExceptionTests extends AbstractExceptionTests { +public class JobInterruptedExceptionTests extends AbstractExceptionTests { /* (non-Javadoc) * @see org.springframework.batch.io.exception.AbstractExceptionTests#getException(java.lang.String) */ public Exception getException(String msg) throws Exception { - return new StepInterruptedException(msg); + return new JobInterruptedException(msg); } /* (non-Javadoc) diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/bootstrap/support/CommandLineJobRunner.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/bootstrap/support/CommandLineJobRunner.java index c34769fac..9536e39b4 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/bootstrap/support/CommandLineJobRunner.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/bootstrap/support/CommandLineJobRunner.java @@ -24,10 +24,10 @@ import org.springframework.batch.core.domain.JobSupport; import org.springframework.batch.core.domain.JobExecution; import org.springframework.batch.core.domain.JobParameters; import org.springframework.batch.core.repository.JobLocator; -import org.springframework.batch.core.runtime.ExitCodeExceptionClassifier; +import org.springframework.batch.core.runtime.ExitStatusExceptionClassifier; import org.springframework.batch.core.runtime.JobParametersFactory; import org.springframework.batch.execution.launch.JobLauncher; -import org.springframework.batch.execution.step.simple.SimpleExitCodeExceptionClassifier; +import org.springframework.batch.execution.step.simple.SimpleExitStatusExceptionClassifier; import org.springframework.beans.factory.BeanDefinitionStoreException; import org.springframework.beans.factory.config.AutowireCapableBeanFactory; import org.springframework.context.ApplicationContext; @@ -122,7 +122,7 @@ public class CommandLineJobRunner { private ExitCodeMapper exitCodeMapper = new SimpleJvmExitCodeMapper(); - private ExitCodeExceptionClassifier exceptionClassifier = new SimpleExitCodeExceptionClassifier(); + private ExitStatusExceptionClassifier exceptionClassifier = new SimpleExitStatusExceptionClassifier(); private JobLauncher launcher; @@ -143,12 +143,12 @@ public class CommandLineJobRunner { } /** - * Injection setter for the {@link ExitCodeExceptionClassifier} + * Injection setter for the {@link ExitStatusExceptionClassifier} * * @param exceptionClassifier */ public void setExceptionClassifier( - ExitCodeExceptionClassifier exceptionClassifier) { + ExitStatusExceptionClassifier exceptionClassifier) { this.exceptionClassifier = exceptionClassifier; } diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/job/simple/SimpleJob.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/job/simple/SimpleJob.java index efc9bd524..ebcf5e0cf 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/job/simple/SimpleJob.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/job/simple/SimpleJob.java @@ -28,10 +28,10 @@ import org.springframework.batch.core.domain.JobSupport; import org.springframework.batch.core.domain.Step; import org.springframework.batch.core.domain.StepExecution; import org.springframework.batch.core.domain.StepInstance; -import org.springframework.batch.core.domain.StepInterruptedException; +import org.springframework.batch.core.domain.JobInterruptedException; import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.core.runtime.ExitCodeExceptionClassifier; -import org.springframework.batch.execution.step.simple.SimpleExitCodeExceptionClassifier; +import org.springframework.batch.core.runtime.ExitStatusExceptionClassifier; +import org.springframework.batch.execution.step.simple.SimpleExitStatusExceptionClassifier; import org.springframework.batch.io.exception.BatchCriticalException; import org.springframework.batch.repeat.ExitStatus; @@ -47,7 +47,7 @@ public class SimpleJob extends JobSupport { private JobRepository jobRepository; - private ExitCodeExceptionClassifier exceptionClassifier = new SimpleExitCodeExceptionClassifier(); + private ExitStatusExceptionClassifier exceptionClassifier = new SimpleExitStatusExceptionClassifier(); /** * Run the specified job by looping through the steps and delegating to the @@ -59,7 +59,6 @@ public class SimpleJob extends JobSupport { JobInstance jobInstance = execution.getJobInstance(); jobInstance.setLastExecution(execution); - updateStatus(execution, BatchStatus.STARTING); List stepInstances = jobInstance.getStepInstances(); @@ -67,6 +66,14 @@ public class SimpleJob extends JobSupport { try { + // The job was already stopped before we even got this far. Deal + // with it in the same way as any other interruption. + if (execution.getStatus() == BatchStatus.STOPPED) { + throw new JobInterruptedException("JobExecution already stopped before being executed."); + } + + updateStatus(execution, BatchStatus.STARTING); + int startedCount = 0; List steps = getSteps(); @@ -97,7 +104,7 @@ public class SimpleJob extends JobSupport { updateStatus(execution, BatchStatus.COMPLETED); } - catch (StepInterruptedException e) { + catch (JobInterruptedException e) { updateStatus(execution, BatchStatus.STOPPED); status = exceptionClassifier.classifyForExitCode(e); rethrow(e); @@ -138,11 +145,9 @@ public class SimpleJob extends JobSupport { } if (stepStatus == BatchStatus.UNKNOWN) { - throw new BatchCriticalException( - "Cannot restart step from UNKNOWN status. " + - "The last execution ended with a failure that could not be rolled back, " + - "so it may be dangerous to proceed. " + - "Manual intervention is probably necessary."); + throw new BatchCriticalException("Cannot restart step from UNKNOWN status. " + + "The last execution ended with a failure that could not be rolled back, " + + "so it may be dangerous to proceed. " + "Manual intervention is probably necessary."); } if (stepStatus == BatchStatus.COMPLETED && step.isAllowStartIfComplete() == false) { @@ -191,7 +196,7 @@ public class SimpleJob extends JobSupport { * * @param exceptionClassifier */ - public void setExceptionClassifier(ExitCodeExceptionClassifier exceptionClassifier) { + public void setExceptionClassifier(ExitStatusExceptionClassifier exceptionClassifier) { this.exceptionClassifier = exceptionClassifier; } } diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/AbstractStep.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/AbstractStep.java index ab4af08fc..ae0377653 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/AbstractStep.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/AbstractStep.java @@ -17,7 +17,7 @@ package org.springframework.batch.execution.step.simple; import org.springframework.batch.core.domain.Step; import org.springframework.batch.core.domain.StepExecution; -import org.springframework.batch.core.domain.StepInterruptedException; +import org.springframework.batch.core.domain.JobInterruptedException; import org.springframework.batch.core.domain.StepSupport; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.io.exception.BatchCriticalException; @@ -174,7 +174,7 @@ public abstract class AbstractStep extends StepSupport implements InitializingBe } - public void execute(StepExecution stepExecution) throws StepInterruptedException, BatchCriticalException { + public void execute(StepExecution stepExecution) throws JobInterruptedException, BatchCriticalException { SimpleStepExecutor executor = createStepExecutor(); executor.execute(stepExecution); } diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/RepeatOperationsStep.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/RepeatOperationsStep.java index 9f789fc1b..d3fe3a8d4 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/RepeatOperationsStep.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/RepeatOperationsStep.java @@ -18,7 +18,7 @@ package org.springframework.batch.execution.step.simple; import org.springframework.batch.core.domain.Step; import org.springframework.batch.core.domain.StepExecution; -import org.springframework.batch.core.domain.StepInterruptedException; +import org.springframework.batch.core.domain.JobInterruptedException; import org.springframework.batch.io.exception.BatchCriticalException; import org.springframework.batch.repeat.RepeatOperations; @@ -72,7 +72,7 @@ public class RepeatOperationsStep extends AbstractStep implements RepeatOperatio this.stepOperations = stepOperations; } - public void execute(StepExecution stepExecution) throws StepInterruptedException, BatchCriticalException { + public void execute(StepExecution stepExecution) throws JobInterruptedException, BatchCriticalException { assertMandatoryProperties(); SimpleStepExecutor executor = (SimpleStepExecutor) super.createStepExecutor(); if (stepOperations != null) { diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleExitCodeExceptionClassifier.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleExitStatusExceptionClassifier.java similarity index 78% rename from spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleExitCodeExceptionClassifier.java rename to spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleExitStatusExceptionClassifier.java index 266667362..8ef14e342 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleExitCodeExceptionClassifier.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleExitStatusExceptionClassifier.java @@ -18,13 +18,13 @@ package org.springframework.batch.execution.step.simple; import java.io.PrintWriter; import java.io.StringWriter; -import org.springframework.batch.core.domain.StepInterruptedException; -import org.springframework.batch.core.runtime.ExitCodeExceptionClassifier; +import org.springframework.batch.core.domain.JobInterruptedException; +import org.springframework.batch.core.runtime.ExitStatusExceptionClassifier; import org.springframework.batch.repeat.ExitStatus; /** *

- * Simple implementation of {@link ExitCodeExceptionClassifier} that returns + * Simple implementation of {@link ExitStatusExceptionClassifier} that returns * basic String exit codes, and defaults to the class name of the throwable for * the message. Most users will want to write their own implementation that * creates more specific exit codes for different exception types. @@ -33,8 +33,8 @@ import org.springframework.batch.repeat.ExitStatus; * @author Lucas Ward * */ -public class SimpleExitCodeExceptionClassifier implements - ExitCodeExceptionClassifier { +public class SimpleExitStatusExceptionClassifier implements + ExitStatusExceptionClassifier { /* (non-Javadoc) * @see org.springframework.batch.core.executor.ExitCodeExceptionClassifier#classifyForExitCode(java.lang.Throwable) @@ -50,9 +50,9 @@ public class SimpleExitCodeExceptionClassifier implements ExitStatus exitStatus = ExitStatus.FAILED; - if (throwable instanceof StepInterruptedException) { - exitStatus = new ExitStatus(false, STEP_INTERRUPTED, - StepInterruptedException.class.getName()); + if (throwable instanceof JobInterruptedException) { + exitStatus = new ExitStatus(false, JOB_INTERRUPTED, + JobInterruptedException.class.getName()); } else { String message = ""; if (throwable!=null) { diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleStepExecutor.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleStepExecutor.java index b01d28fc1..79968190a 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleStepExecutor.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/SimpleStepExecutor.java @@ -24,9 +24,9 @@ import org.springframework.batch.core.domain.Step; import org.springframework.batch.core.domain.StepContribution; import org.springframework.batch.core.domain.StepExecution; import org.springframework.batch.core.domain.StepInstance; -import org.springframework.batch.core.domain.StepInterruptedException; +import org.springframework.batch.core.domain.JobInterruptedException; import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.core.runtime.ExitCodeExceptionClassifier; +import org.springframework.batch.core.runtime.ExitStatusExceptionClassifier; import org.springframework.batch.core.tasklet.Tasklet; import org.springframework.batch.execution.scope.SimpleStepContext; import org.springframework.batch.execution.scope.StepContext; @@ -85,7 +85,7 @@ public class SimpleStepExecutor implements InitializingBean { private JobRepository jobRepository; - private ExitCodeExceptionClassifier exceptionClassifier = new SimpleExitCodeExceptionClassifier(); + private ExitStatusExceptionClassifier exceptionClassifier = new SimpleExitStatusExceptionClassifier(); // default to checking current thread for interruption. private StepInterruptionPolicy interruptionPolicy = new ThreadStepInterruptionPolicy(); @@ -164,12 +164,12 @@ public class SimpleStepExecutor implements InitializingBean { } /** - * Setter for the {@link ExitCodeExceptionClassifier} that will be used to classify any exception that causes a job + * Setter for the {@link ExitStatusExceptionClassifier} that will be used to classify any exception that causes a job * to fail. * * @param exceptionClassifier */ - public void setExceptionClassifier(ExitCodeExceptionClassifier exceptionClassifier) { + public void setExceptionClassifier(ExitStatusExceptionClassifier exceptionClassifier) { this.exceptionClassifier = exceptionClassifier; } @@ -267,11 +267,11 @@ public class SimpleStepExecutor implements InitializingBean { * information are also added to the current context (the {@link RepeatContext} governing the step execution, which * would normally be available to the caller somehow through the step's {@link JobExecutionContext}.
* - * @throws StepInterruptedException if the step or a chunk is interrupted + * @throws JobInterruptedException if the step or a chunk is interrupted * @throws RuntimeException if there is an exception during a chunk execution * @see StepExecutor#execute(StepExecution) */ - public void execute(final StepExecution stepExecution) throws BatchCriticalException, StepInterruptedException { + public void execute(final StepExecution stepExecution) throws BatchCriticalException, JobInterruptedException { final StepInstance stepInstance = stepExecution.getStep(); Assert.notNull(stepInstance); @@ -386,9 +386,9 @@ public class SimpleStepExecutor implements InitializingBean { // classify exception so an exit code can be stored. status = exceptionClassifier.classifyForExitCode(e); - if (e.getCause() instanceof StepInterruptedException) { + if (e.getCause() instanceof JobInterruptedException) { updateStatus(stepExecution, BatchStatus.STOPPED); - throw (StepInterruptedException) e.getCause(); + throw (JobInterruptedException) e.getCause(); } else if (e instanceof ResetFailedException) { updateStatus(stepExecution, BatchStatus.UNKNOWN); throw (ResetFailedException) e; diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/StepInterruptionPolicy.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/StepInterruptionPolicy.java index 1a2f27aab..f1a9eabd3 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/StepInterruptionPolicy.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/StepInterruptionPolicy.java @@ -17,7 +17,7 @@ package org.springframework.batch.execution.step.simple; import org.springframework.batch.core.domain.Step; -import org.springframework.batch.core.domain.StepInterruptedException; +import org.springframework.batch.core.domain.JobInterruptedException; import org.springframework.batch.repeat.RepeatContext; /** @@ -31,10 +31,10 @@ public interface StepInterruptionPolicy { /** * Has the job been interrupted? If so then throw a - * {@link StepInterruptedException}. + * {@link JobInterruptedException}. * @param context the current context of the running step. * - * @throws StepInterruptedException when the job has been interrupted. + * @throws JobInterruptedException when the job has been interrupted. */ - void checkInterrupted(RepeatContext context) throws StepInterruptedException; + void checkInterrupted(RepeatContext context) throws JobInterruptedException; } diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/ThreadStepInterruptionPolicy.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/ThreadStepInterruptionPolicy.java index 5832532a8..03fe801ed 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/ThreadStepInterruptionPolicy.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/simple/ThreadStepInterruptionPolicy.java @@ -18,7 +18,7 @@ package org.springframework.batch.execution.step.simple; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.springframework.batch.core.domain.StepInterruptedException; +import org.springframework.batch.core.domain.JobInterruptedException; import org.springframework.batch.repeat.RepeatContext; /** @@ -38,10 +38,10 @@ public class ThreadStepInterruptionPolicy implements StepInterruptionPolicy { * Returns if the current job lifecycle has been interrupted by checking if * the current thread is interrupted. */ - public void checkInterrupted(RepeatContext context) throws StepInterruptedException { + public void checkInterrupted(RepeatContext context) throws JobInterruptedException { if (isInterrupted(context)) { - throw new StepInterruptedException("Job interrupted status detected."); + throw new JobInterruptedException("Job interrupted status detected."); } } diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/tasklet/TaskletStep.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/tasklet/TaskletStep.java index 6871336de..4734e29ad 100644 --- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/tasklet/TaskletStep.java +++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/step/tasklet/TaskletStep.java @@ -22,7 +22,7 @@ import org.apache.commons.logging.LogFactory; import org.springframework.batch.core.domain.BatchStatus; import org.springframework.batch.core.domain.Step; import org.springframework.batch.core.domain.StepExecution; -import org.springframework.batch.core.domain.StepInterruptedException; +import org.springframework.batch.core.domain.JobInterruptedException; import org.springframework.batch.core.domain.StepSupport; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.core.tasklet.Tasklet; @@ -106,7 +106,7 @@ public class TaskletStep extends StepSupport implements InitializingBean { this.jobRepository = jobRepository; } - public void execute(StepExecution stepExecution) throws StepInterruptedException, BatchCriticalException { + public void execute(StepExecution stepExecution) throws JobInterruptedException, BatchCriticalException { stepExecution.setStartTime(new Date()); updateStatus(stepExecution, BatchStatus.STARTED); diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/bootstrap/support/CommandLineJobRunnerTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/bootstrap/support/CommandLineJobRunnerTests.java index 21266f3ba..4fb846d1b 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/bootstrap/support/CommandLineJobRunnerTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/bootstrap/support/CommandLineJobRunnerTests.java @@ -21,7 +21,7 @@ import org.springframework.batch.core.domain.Job; import org.springframework.batch.core.domain.JobExecution; import org.springframework.batch.core.domain.JobParameters; import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException; -import org.springframework.batch.core.runtime.ExitCodeExceptionClassifier; +import org.springframework.batch.core.runtime.ExitStatusExceptionClassifier; import org.springframework.batch.execution.launch.JobLauncher; import org.springframework.batch.repeat.ExitStatus; @@ -133,7 +133,7 @@ public class CommandLineJobRunnerTests extends TestCase { } } - public static class StubExceptionClassifier implements ExitCodeExceptionClassifier{ + public static class StubExceptionClassifier implements ExitStatusExceptionClassifier{ public static Throwable exception; diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/job/simple/SimpleJobTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/job/simple/SimpleJobTests.java index 6e25902b5..e7e7aeffa 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/job/simple/SimpleJobTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/job/simple/SimpleJobTests.java @@ -24,12 +24,12 @@ import junit.framework.TestCase; import org.springframework.batch.core.domain.BatchStatus; import org.springframework.batch.core.domain.JobExecution; import org.springframework.batch.core.domain.JobInstance; +import org.springframework.batch.core.domain.JobInterruptedException; import org.springframework.batch.core.domain.JobParameters; import org.springframework.batch.core.domain.StepExecution; import org.springframework.batch.core.domain.StepInstance; -import org.springframework.batch.core.domain.StepInterruptedException; import org.springframework.batch.core.repository.JobRepository; -import org.springframework.batch.core.runtime.ExitCodeExceptionClassifier; +import org.springframework.batch.core.runtime.ExitStatusExceptionClassifier; import org.springframework.batch.execution.repository.SimpleJobRepository; import org.springframework.batch.execution.repository.dao.JobDao; import org.springframework.batch.execution.repository.dao.MapJobDao; @@ -170,7 +170,7 @@ public class SimpleJobTests extends TestCase { public void testInterrupted() throws Exception { stepConfiguration1.setStartLimit(5); stepConfiguration2.setStartLimit(5); - final StepInterruptedException exception = new StepInterruptedException("Interrupt!"); + final JobInterruptedException exception = new JobInterruptedException("Interrupt!"); stepConfiguration1.setProcessException(exception); try { job.execute(jobExecution); @@ -179,7 +179,7 @@ public class SimpleJobTests extends TestCase { assertEquals(exception, e.getCause()); } assertEquals(0, list.size()); - checkRepository(BatchStatus.STOPPED, new ExitStatus(false, ExitCodeExceptionClassifier.STEP_INTERRUPTED)); + checkRepository(BatchStatus.STOPPED, new ExitStatus(false, ExitStatusExceptionClassifier.JOB_INTERRUPTED)); } public void testFailed() throws Exception { @@ -194,7 +194,7 @@ public class SimpleJobTests extends TestCase { assertEquals(exception, e); } assertEquals(0, list.size()); - checkRepository(BatchStatus.FAILED, new ExitStatus(false, ExitCodeExceptionClassifier.FATAL_EXCEPTION)); + checkRepository(BatchStatus.FAILED, new ExitStatus(false, ExitStatusExceptionClassifier.FATAL_EXCEPTION)); } public void testStepShouldNotStart() throws Exception { @@ -229,8 +229,25 @@ public class SimpleJobTests extends TestCase { job.execute(jobExecution); ExitStatus exitStatus = jobExecution.getExitStatus(); - assertTrue("Wrong message in execution: " + exitStatus, exitStatus.getExitDescription().indexOf( - "steps already completed") >= 0); + assertEquals(ExitStatus.NOOP.getExitCode(), exitStatus.getExitCode()); + assertTrue("Wrong message in execution: " + exitStatus, exitStatus.getExitDescription().contains( + "steps already completed")); + } + + public void testNotExecutedIfAlreadyStopped() throws Exception { + jobExecution.stop(); + try { + job.execute(jobExecution); + } + catch (BatchCriticalException e) { + assertTrue(e.getCause() instanceof JobInterruptedException); + } + assertEquals(0, list.size()); + checkRepository(BatchStatus.STOPPED, new ExitStatus(false, ExitStatusExceptionClassifier.JOB_INTERRUPTED)); + ExitStatus exitStatus = jobExecution.getExitStatus(); + assertEquals(ExitStatusExceptionClassifier.JOB_INTERRUPTED, exitStatus.getExitCode()); + assertTrue("Wrong message in execution: " + exitStatus, exitStatus.getExitDescription().contains( + "JobInterruptedException")); } /* @@ -277,12 +294,12 @@ public class SimpleJobTests extends TestCase { this.runnable = runnable; } - public void execute(StepExecution stepExecution) throws StepInterruptedException, BatchCriticalException { + public void execute(StepExecution stepExecution) throws JobInterruptedException, BatchCriticalException { if (exception instanceof RuntimeException) { throw (RuntimeException)exception; } - if (exception instanceof StepInterruptedException) { - throw (StepInterruptedException)exception; + if (exception instanceof JobInterruptedException) { + throw (JobInterruptedException)exception; } if (runnable!=null) { runnable.run(); diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/AbstractStepDaoTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/AbstractStepDaoTests.java index c1fcad017..057b08e5e 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/AbstractStepDaoTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/repository/dao/AbstractStepDaoTests.java @@ -26,7 +26,7 @@ import org.springframework.batch.core.domain.JobParameters; import org.springframework.batch.core.domain.JobSupport; import org.springframework.batch.core.domain.StepExecution; import org.springframework.batch.core.domain.StepInstance; -import org.springframework.batch.core.runtime.ExitCodeExceptionClassifier; +import org.springframework.batch.core.runtime.ExitStatusExceptionClassifier; import org.springframework.batch.item.ExecutionAttributes; import org.springframework.batch.repeat.ExitStatus; import org.springframework.batch.support.PropertiesConverter; @@ -178,7 +178,7 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour execution.setStatus(BatchStatus.STARTED); execution.setStartTime(new Date(System.currentTimeMillis())); execution.setExecutionAttributes(new ExecutionAttributes(PropertiesConverter.stringToProperties("key1=0,key2=5"))); - execution.setExitStatus(new ExitStatus(false, ExitCodeExceptionClassifier.FATAL_EXCEPTION, + execution.setExitStatus(new ExitStatus(false, ExitStatusExceptionClassifier.FATAL_EXCEPTION, "java.lang.Exception")); stepExecutionDao.saveStepExecution(execution); List executions = stepExecutionDao.findStepExecutions(step2); @@ -196,7 +196,7 @@ public abstract class AbstractStepDaoTests extends AbstractTransactionalDataSour stepExecution.setCommitCount(5); stepExecution.setTaskCount(5); stepExecution.setExecutionAttributes(new ExecutionAttributes()); - stepExecution.setExitStatus(new ExitStatus(false, ExitCodeExceptionClassifier.FATAL_EXCEPTION, + stepExecution.setExitStatus(new ExitStatus(false, ExitStatusExceptionClassifier.FATAL_EXCEPTION, "java.lang.Exception")); stepExecutionDao.updateStepExecution(stepExecution); List executions = stepExecutionDao.findStepExecutions(step1); diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleExitCodeExceptionClassifierTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleExitStatusExceptionClassifierTests.java similarity index 81% rename from spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleExitCodeExceptionClassifierTests.java rename to spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleExitStatusExceptionClassifierTests.java index 084e334b3..5e6159b81 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleExitCodeExceptionClassifierTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleExitStatusExceptionClassifierTests.java @@ -16,8 +16,8 @@ package org.springframework.batch.execution.step.simple; -import org.springframework.batch.core.domain.StepInterruptedException; -import org.springframework.batch.core.runtime.ExitCodeExceptionClassifier; +import org.springframework.batch.core.domain.JobInterruptedException; +import org.springframework.batch.core.runtime.ExitStatusExceptionClassifier; import org.springframework.batch.repeat.ExitStatus; import junit.framework.TestCase; @@ -26,15 +26,14 @@ import junit.framework.TestCase; * @author Lucas Ward * */ -public class SimpleExitCodeExceptionClassifierTests extends TestCase { +public class SimpleExitStatusExceptionClassifierTests extends TestCase { NullPointerException exception; - SimpleExitCodeExceptionClassifier classifier = new SimpleExitCodeExceptionClassifier(); + SimpleExitStatusExceptionClassifier classifier = new SimpleExitStatusExceptionClassifier(); protected void setUp() throws Exception { super.setUp(); - exception = new NullPointerException(); } @@ -69,9 +68,9 @@ public class SimpleExitCodeExceptionClassifierTests extends TestCase { } public void testClassifyInterruptedException(){ - ExitStatus exitStatus = (ExitStatus)classifier.classifyForExitCode(new StepInterruptedException("")); - assertEquals(exitStatus.getExitCode(), ExitCodeExceptionClassifier.STEP_INTERRUPTED); + ExitStatus exitStatus = (ExitStatus)classifier.classifyForExitCode(new JobInterruptedException("")); + assertEquals(exitStatus.getExitCode(), ExitStatusExceptionClassifier.JOB_INTERRUPTED); assertEquals(exitStatus.getExitDescription(), - StepInterruptedException.class.getName()); + JobInterruptedException.class.getName()); } } diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleStepExecutorTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleStepExecutorTests.java index dd768f309..dd8eab773 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleStepExecutorTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleStepExecutorTests.java @@ -32,7 +32,7 @@ import org.springframework.batch.core.domain.JobSupport; import org.springframework.batch.core.domain.StepContribution; import org.springframework.batch.core.domain.StepExecution; import org.springframework.batch.core.domain.StepInstance; -import org.springframework.batch.core.domain.StepInterruptedException; +import org.springframework.batch.core.domain.JobInterruptedException; import org.springframework.batch.execution.repository.SimpleJobRepository; import org.springframework.batch.execution.repository.dao.MapJobDao; import org.springframework.batch.execution.repository.dao.MapStepDao; @@ -478,8 +478,8 @@ public class SimpleStepExecutorTests extends TestCase { StepInterruptionPolicy interruptionPolicy = new StepInterruptionPolicy() { - public void checkInterrupted(RepeatContext context) throws StepInterruptedException { - throw new StepInterruptedException(""); + public void checkInterrupted(RepeatContext context) throws JobInterruptedException { + throw new JobInterruptedException(""); } }; @@ -514,11 +514,11 @@ public class SimpleStepExecutorTests extends TestCase { stepExecutor.execute(stepExecution); fail("Expected StepInterruptedException"); } - catch (StepInterruptedException ex) { + catch (JobInterruptedException ex) { assertEquals(BatchStatus.STOPPED, stepExecution.getStatus()); String msg = stepExecution.getExitStatus().getExitDescription(); - assertTrue("Message does not contain StepInterruptedException: " + msg, msg - .contains("StepInterruptedException")); + assertTrue("Message does not contain JobInterruptedException: " + msg, msg + .contains("JobInterruptedException")); } } diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/StepExecutorInterruptionTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/StepExecutorInterruptionTests.java index a9880b881..78e87a351 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/StepExecutorInterruptionTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/StepExecutorInterruptionTests.java @@ -27,7 +27,7 @@ import org.springframework.batch.core.domain.JobParameters; import org.springframework.batch.core.domain.JobSupport; import org.springframework.batch.core.domain.StepExecution; import org.springframework.batch.core.domain.StepInstance; -import org.springframework.batch.core.domain.StepInterruptedException; +import org.springframework.batch.core.domain.JobInterruptedException; import org.springframework.batch.core.repository.JobRepository; import org.springframework.batch.execution.repository.SimpleJobRepository; import org.springframework.batch.execution.repository.dao.JobDao; @@ -98,7 +98,7 @@ public class StepExecutorInterruptionTests extends TestCase { try { step.execute(stepExecution); } - catch (StepInterruptedException e) { + catch (JobInterruptedException e) { // do nothing... } } diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/ThreadStepInterruptionPolicyTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/ThreadStepInterruptionPolicyTests.java index 640b2c443..6d4a4b0d9 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/ThreadStepInterruptionPolicyTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/ThreadStepInterruptionPolicyTests.java @@ -17,7 +17,7 @@ package org.springframework.batch.execution.step.simple; import junit.framework.TestCase; -import org.springframework.batch.core.domain.StepInterruptedException; +import org.springframework.batch.core.domain.JobInterruptedException; import org.springframework.batch.repeat.RepeatContext; import org.springframework.batch.repeat.context.RepeatContextSupport; @@ -48,7 +48,7 @@ public class ThreadStepInterruptionPolicyTests extends TestCase { try { policy.checkInterrupted(context); fail("Expected StepInterruptedException"); - } catch (StepInterruptedException e) { + } catch (JobInterruptedException e) { // expected assertTrue(e.getMessage().indexOf("interrupt")>=0); } diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/tasklet/TaskletStepTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/tasklet/TaskletStepTests.java index abcccc934..b247b7e59 100644 --- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/tasklet/TaskletStepTests.java +++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/tasklet/TaskletStepTests.java @@ -10,7 +10,7 @@ import org.springframework.batch.core.domain.JobInstance; import org.springframework.batch.core.domain.JobParameters; import org.springframework.batch.core.domain.StepExecution; import org.springframework.batch.core.domain.StepInstance; -import org.springframework.batch.core.domain.StepInterruptedException; +import org.springframework.batch.core.domain.JobInterruptedException; import org.springframework.batch.core.tasklet.Tasklet; import org.springframework.batch.execution.step.simple.JobRepositorySupport; import org.springframework.batch.io.exception.BatchCriticalException; @@ -83,7 +83,7 @@ public class TaskletStepTests extends TestCase { assertEquals(2, list.size()); } - public void testExceptionExecution() throws StepInterruptedException, BatchCriticalException { + public void testExceptionExecution() throws JobInterruptedException, BatchCriticalException { TaskletStep step = new TaskletStep(new StubTasklet(false, true), new JobRepositorySupport()); try { step.execute(stepExecution); diff --git a/spring-batch-samples/src/main/resources/simple-container-definition.xml b/spring-batch-samples/src/main/resources/simple-container-definition.xml index 68610f5ed..bcdc933b4 100644 --- a/spring-batch-samples/src/main/resources/simple-container-definition.xml +++ b/spring-batch-samples/src/main/resources/simple-container-definition.xml @@ -58,15 +58,6 @@ ref="jobExecutionIncrementer" /> - -