diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/step/job/JobStep.java b/spring-batch-core/src/main/java/org/springframework/batch/core/step/job/JobStep.java index 4a2214c44..7ed15a692 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/step/job/JobStep.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/step/job/JobStep.java @@ -16,6 +16,7 @@ package org.springframework.batch.core.step.job; import org.springframework.batch.core.BatchStatus; +import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.Job; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobParameters; @@ -116,6 +117,9 @@ public class JobStep extends AbstractStep { } JobExecution jobExecution = jobLauncher.run(job, jobParameters); + + stepExecution.setExitStatus(determineStepExitStatus(stepExecution, jobExecution)); + if (jobExecution.getStatus().isUnsuccessful()) { // AbstractStep will take care of the step execution status throw new UnexpectedJobExecutionException("Step failure: the delegate Job failed in JobStep."); @@ -123,7 +127,20 @@ public class JobStep extends AbstractStep { else if(jobExecution.getStatus().equals(BatchStatus.STOPPED)) { stepExecution.setStatus(BatchStatus.STOPPED); } - + } + + /** + * Determines the {@link ExitStatus} taking into consideration the {@link ExitStatus} from + * the {@link StepExecution}, which invoked the {@link JobStep}, and the {@link JobExecution}. + * + * @param stepExecution the {@link StepExecution} which invoked the {@link JobExecution} + * @param jobExecution the {@link JobExecution} + * @return the final {@link ExitStatus} + */ + private ExitStatus determineStepExitStatus(StepExecution stepExecution, JobExecution jobExecution) { + ExitStatus exitStatus = stepExecution.getExitStatus() != null ? stepExecution.getExitStatus() : ExitStatus.COMPLETED; + + return exitStatus.and(jobExecution.getExitStatus()); } } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/job/JobStepTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/job/JobStepTests.java index c44e4e14e..0f0a4306b 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/job/JobStepTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/job/JobStepTests.java @@ -21,6 +21,7 @@ import org.junit.Before; import org.junit.Test; import org.springframework.batch.core.BatchStatus; +import org.springframework.batch.core.ExitStatus; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobParameters; import org.springframework.batch.core.StepExecution; @@ -203,4 +204,19 @@ public class JobStepTests { assertEquals(BatchStatus.STOPPED, stepExecution.getStatus()); } + + @Test + public void testStepExecutionExitStatus() throws Exception { + step.setJob(new JobSupport("child") { + @Override + public void execute(JobExecution execution) throws UnexpectedJobExecutionException { + execution.setStatus(BatchStatus.COMPLETED); + execution.setExitStatus(new ExitStatus("CUSTOM")); + execution.setEndTime(new Date()); + } + }); + step.afterPropertiesSet(); + step.execute(stepExecution); + assertEquals("CUSTOM", stepExecution.getExitStatus().getExitCode()); + } }