diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/launch/JobLauncher.java b/spring-batch-core/src/main/java/org/springframework/batch/core/launch/JobLauncher.java index 557f02461..03dd171fe 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/launch/JobLauncher.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/launch/JobLauncher.java @@ -15,6 +15,7 @@ */ package org.springframework.batch.core.launch; +import org.springframework.batch.core.BatchStatus; import org.springframework.batch.core.Job; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobParameters; @@ -37,12 +38,17 @@ import org.springframework.batch.core.repository.JobExecutionAlreadyRunningExcep public interface JobLauncher { /** - * Start a job execution for the given {@link Job} and {@link JobParameters}. If - * a JobExecution was able to be created successfully, it will always be returned - * by this method, regardless of whether or not the execution was successful. + * Start a job execution for the given {@link Job} and {@link JobParameters} + * . If a JobExecution was able to be created successfully, it will always + * be returned by this method, regardless of whether or not the execution + * was successful. + * + * If there exists a past {@link JobExecution} and its status is + * {@link BatchStatus#PAUSED}, the same JobExecution should be continued + * instead of new one created. * * @return the {@link JobExecution} if it returns synchronously. If the - * implementation is asynchronous, the status might well be unknown. + * implementation is asynchronous, the status might well be unknown. * * @throws JobExecutionAlreadyRunningException if the JobInstance identified * by the properties already has an execution running. diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/SimpleJobLauncherTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/SimpleJobLauncherTests.java index fe31d7ae6..a3e126451 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/launch/SimpleJobLauncherTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/launch/SimpleJobLauncherTests.java @@ -30,6 +30,7 @@ import java.util.List; import org.junit.Before; import org.junit.Test; +import org.springframework.batch.core.BatchStatus; import org.springframework.batch.core.Job; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.JobInstance; @@ -75,8 +76,6 @@ public class SimpleJobLauncherTests { JobExecution jobExecution = new JobExecution(null, null); - // expect(jobRepository.isJobInstanceExists(job.getName(), - // jobParameters)).andReturn(false); expect(jobRepository.getLastJobExecution(job.getName(), jobParameters)).andReturn(null); expect(jobRepository.createJobExecution(job.getName(), jobParameters)).andReturn(jobExecution); replay(jobRepository); @@ -110,7 +109,6 @@ public class SimpleJobLauncherTests { testRun(); try { reset(jobRepository); -// expect(jobRepository.isJobInstanceExists(job.getName(), jobParameters)).andReturn(true); expect(jobRepository.getLastJobExecution(job.getName(), jobParameters)).andReturn( new JobExecution(new JobInstance(1L, jobParameters, job.getName()))); replay(jobRepository); @@ -189,6 +187,24 @@ public class SimpleJobLauncherTests { jobLauncher.setJobRepository(jobRepository); jobLauncher.afterPropertiesSet(); // no error } + + /** + * Same execution is used if the last found has PAUSED status. + */ + @Test + public void testResumePausedInstance() throws Exception { + long id = 9; + JobExecution jobExecution = new JobExecution(null, id); + jobExecution.setStatus(BatchStatus.PAUSED); + expect(jobRepository.getLastJobExecution(job.getName(), jobParameters)).andReturn(jobExecution); + replay(jobRepository); + + jobLauncher.afterPropertiesSet(); + JobExecution returned = jobLauncher.run(job, jobParameters); + assertEquals(jobExecution, returned); + + verify(jobRepository); + } private boolean contains(String str, String searchStr) { return str.indexOf(searchStr) != -1;