diff --git a/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JdbcStepDao.java b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JdbcStepDao.java
index a1ae794e9..ea66de258 100644
--- a/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JdbcStepDao.java
+++ b/spring-batch-execution/src/main/java/org/springframework/batch/execution/repository/dao/JdbcStepDao.java
@@ -564,7 +564,7 @@ public class JdbcStepDao implements StepDao, InitializingBean {
// Avoid concurrent modifications...
if (count == 0) {
throw new OptimisticLockingFailureException("Attempt to update step execution id="
- + stepExecution.getId() + " with out of date version (" + stepExecution.getVersion() + ")");
+ + stepExecution.getId() + " with wrong version (" + stepExecution.getVersion() + ")");
}
stepExecution.incrementVersion();
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 8c1b898b5..9f789fc1b 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
@@ -19,7 +19,6 @@ 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.tasklet.Tasklet;
import org.springframework.batch.io.exception.BatchCriticalException;
import org.springframework.batch.repeat.RepeatOperations;
@@ -37,8 +36,6 @@ public class RepeatOperationsStep extends AbstractStep implements RepeatOperatio
private volatile RepeatOperations stepOperations;
- private volatile Tasklet tasklet;
-
/**
* Public accessor for the chunkOperations property.
*
@@ -56,11 +53,6 @@ public class RepeatOperationsStep extends AbstractStep implements RepeatOperatio
public void setChunkOperations(RepeatOperations chunkOperations) {
this.chunkOperations = chunkOperations;
}
-
-
- public void setTasklet(Tasklet tasklet) {
- this.tasklet = tasklet;
- }
/**
* Public accessor for the stepOperations property.
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 936530fbf..e74a437a5 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
@@ -28,32 +28,69 @@ import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.tasklet.Tasklet;
import org.springframework.batch.io.exception.BatchCriticalException;
import org.springframework.batch.repeat.ExitStatus;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.util.Assert;
/**
- * A {@link Step} that executes a {@link Tasklet} directly. This step does not manage transactions or any looping
- * functionality. The tasklet should do this on its own.
+ * A {@link Step} that executes a {@link Tasklet} directly. This step does not
+ * manage transactions or any looping functionality. The tasklet should do this
+ * on its own.
*
* @author Ben Hale
*/
-public class TaskletStep extends StepSupport {
+public class TaskletStep extends StepSupport implements InitializingBean {
private static final Log logger = LogFactory.getLog(TaskletStep.class);
- private final Tasklet tasklet;
+ private Tasklet tasklet;
- private final JobRepository jobRepository;
+ private JobRepository jobRepository;
+
+ /**
+ * Check mandatory properties.
+ * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
+ */
+ public void afterPropertiesSet() throws Exception {
+ Assert.notNull(jobRepository, "JobRepository is mandatory for TaskletStep");
+ Assert.notNull(tasklet, "Tasklet is mandatory for TaskletStep");
+ }
+
+ /**
+ * Default constructor is useful for XML configuration.
+ */
+ public TaskletStep() {
+ super();
+ }
/**
* Creates a new Step for executing a Tasklet
*
* @param tasklet The Tasklet to execute
- * @param jobRepository The JobRepository to use for persistence of incremental state
+ * @param jobRepository The JobRepository to use for
+ * persistence of incremental state
*/
public TaskletStep(Tasklet tasklet, JobRepository jobRepository) {
+ this();
this.tasklet = tasklet;
this.jobRepository = jobRepository;
}
+ /**
+ * Public setter for the {@link Tasklet}.
+ * @param tasklet the {@link Tasklet} to set
+ */
+ public void setTasklet(Tasklet tasklet) {
+ this.tasklet = tasklet;
+ }
+
+ /**
+ * Public setter for the {@link JobRepository}.
+ * @param jobRepository the {@link JobRepository} to set
+ */
+ public void setJobRepository(JobRepository jobRepository) {
+ this.jobRepository = jobRepository;
+ }
+
public void execute(StepExecution stepExecution) throws StepInterruptedException, BatchCriticalException {
stepExecution.setStartTime(new Date());
updateStatus(stepExecution, BatchStatus.STARTED);
@@ -62,11 +99,13 @@ public class TaskletStep extends StepSupport {
try {
exitStatus = tasklet.execute();
updateStatus(stepExecution, BatchStatus.COMPLETED);
- } catch (Exception e) {
+ }
+ catch (Exception e) {
logger.error("Encountered an error running the tasklet");
updateStatus(stepExecution, BatchStatus.FAILED);
throw new BatchCriticalException(e);
- } finally {
+ }
+ finally {
stepExecution.setExitStatus(exitStatus);
stepExecution.setEndTime(new Date());
jobRepository.saveOrUpdate(stepExecution);
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 3cfea6112..9c8dcfadd 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
@@ -30,7 +30,6 @@ 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.tasklet.Tasklet;
import org.springframework.batch.execution.repository.SimpleJobRepository;
import org.springframework.batch.execution.repository.dao.JobDao;
import org.springframework.batch.execution.repository.dao.MapJobDao;
@@ -38,6 +37,7 @@ import org.springframework.batch.execution.repository.dao.MapStepDao;
import org.springframework.batch.execution.repository.dao.StepDao;
import org.springframework.batch.execution.step.simple.SimpleStep;
import org.springframework.batch.io.exception.BatchCriticalException;
+import org.springframework.batch.item.reader.AbstractItemReader;
import org.springframework.batch.repeat.ExitStatus;
/**
@@ -136,17 +136,17 @@ public class SimpleJobTests extends TestCase {
job.setJobRepository(jobRepository);
// do not set StepExecutorFactory...
stepConfiguration1.setStartLimit(5);
- stepConfiguration1.setTasklet(new Tasklet() {
- public ExitStatus execute() throws Exception {
+ stepConfiguration1.setItemReader(new AbstractItemReader() {
+ public Object read() throws Exception {
list.add("1");
- return ExitStatus.FINISHED;
+ return null;
}
});
stepConfiguration2.setStartLimit(5);
- stepConfiguration2.setTasklet(new Tasklet() {
- public ExitStatus execute() throws Exception {
+ stepConfiguration2.setItemReader(new AbstractItemReader() {
+ public Object read() throws Exception {
list.add("2");
- return ExitStatus.FINISHED;
+ return null;
}
});
job.execute(jobExecution);
@@ -251,7 +251,6 @@ public class SimpleJobTests extends TestCase {
private Runnable runnable;
private Exception exception;
- private Tasklet tasklet;
/**
* @param string
@@ -266,13 +265,6 @@ public class SimpleJobTests extends TestCase {
public void setProcessException(Exception exception) {
this.exception = exception;
}
-
- /**
- * @param tasklet the tasklet to set
- */
- public void setTasklet(Tasklet tasklet) {
- this.tasklet = tasklet;
- }
/**
* @param runnable
diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/RepeatOperationsStepTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/RepeatOperationsStepTests.java
index 73ab8a013..28c5b6386 100644
--- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/RepeatOperationsStepTests.java
+++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/RepeatOperationsStepTests.java
@@ -25,12 +25,10 @@ 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.tasklet.Tasklet;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.reader.ItemReaderAdapter;
import org.springframework.batch.item.writer.ItemWriterAdapter;
-import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.repeat.RepeatContext;
import org.springframework.batch.repeat.interceptor.RepeatInterceptorAdapter;
import org.springframework.batch.repeat.policy.SimpleCompletionPolicy;
@@ -135,11 +133,6 @@ public class RepeatOperationsStepTests extends TestCase {
configuration.setStepOperations(stepTemplate);
configuration.setJobRepository(new JobRepositorySupport());
configuration.setTransactionManager(new ResourcelessTransactionManager());
- configuration.setTasklet(new Tasklet() {
- public ExitStatus execute() throws Exception {
- return ExitStatus.CONTINUABLE;
- }
- });
StepExecution stepExecution = new StepExecution(new StepInstance(
new Long(11)), new JobExecution(new JobInstance(new Long(0L), new JobParameters()),
new Long(12)));
diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleStepConfigurationTests.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleStepConfigurationTests.java
index eac86b34e..386b020ef 100644
--- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleStepConfigurationTests.java
+++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/simple/SimpleStepConfigurationTests.java
@@ -17,10 +17,8 @@ package org.springframework.batch.execution.step.simple;
import junit.framework.TestCase;
-import org.springframework.batch.core.tasklet.Tasklet;
import org.springframework.batch.item.reader.AbstractItemReader;
import org.springframework.batch.item.writer.AbstractItemWriter;
-import org.springframework.batch.repeat.ExitStatus;
import org.springframework.batch.repeat.exception.handler.DefaultExceptionHandler;
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
diff --git a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/tasklet/TaskletStepTest.java b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/tasklet/TaskletStepTests.java
similarity index 69%
rename from spring-batch-execution/src/test/java/org/springframework/batch/execution/step/tasklet/TaskletStepTest.java
rename to spring-batch-execution/src/test/java/org/springframework/batch/execution/step/tasklet/TaskletStepTests.java
index 7c104c2aa..9c159d968 100644
--- a/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/tasklet/TaskletStepTest.java
+++ b/spring-batch-execution/src/test/java/org/springframework/batch/execution/step/tasklet/TaskletStepTests.java
@@ -2,30 +2,51 @@ package org.springframework.batch.execution.step.tasklet;
import junit.framework.TestCase;
-import org.springframework.batch.core.domain.Job;
import org.springframework.batch.core.domain.JobExecution;
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.repository.JobExecutionAlreadyRunningException;
-import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.tasklet.Tasklet;
+import org.springframework.batch.execution.step.simple.JobRepositorySupport;
import org.springframework.batch.io.exception.BatchCriticalException;
import org.springframework.batch.repeat.ExitStatus;
-public class TaskletStepTest extends TestCase {
+public class TaskletStepTests extends TestCase {
private StepExecution stepExecution;
protected void setUp() throws Exception {
stepExecution = new StepExecution(new StepInstance(new Long(11)), new JobExecution(new JobInstance(
- new Long(0L), new JobParameters()), new Long(12)));
+ new Long(0L), new JobParameters()), new Long(12)));
+ }
+
+ public void testTaskletMandatory() throws Exception {
+ TaskletStep step = new TaskletStep();
+ step.setJobRepository(new JobRepositorySupport());
+ try {
+ step.afterPropertiesSet();
+ }
+ catch (IllegalArgumentException e) {
+ String message = e.getMessage();
+ assertTrue("Message should contain 'tasklet': " + message, message.toLowerCase().contains("tasklet"));
+ }
+ }
+
+ public void testRepositoryMandatory() throws Exception {
+ TaskletStep step = new TaskletStep();
+ try {
+ step.afterPropertiesSet();
+ }
+ catch (IllegalArgumentException e) {
+ String message = e.getMessage();
+ assertTrue("Message should contain 'tasklet': " + message, message.toLowerCase().contains("tasklet"));
+ }
}
public void testSuccessfulExecution() throws StepInterruptedException, BatchCriticalException {
- TaskletStep step = new TaskletStep(new StubTasklet(false, false), new StubJobRepository());
+ TaskletStep step = new TaskletStep(new StubTasklet(false, false), new JobRepositorySupport());
step.execute(stepExecution);
assertNotNull(stepExecution.getStartTime());
assertSame(ExitStatus.FINISHED, stepExecution.getExitStatus());
@@ -33,7 +54,7 @@ public class TaskletStepTest extends TestCase {
}
public void testFailureExecution() throws StepInterruptedException, BatchCriticalException {
- TaskletStep step = new TaskletStep(new StubTasklet(true, false), new StubJobRepository());
+ TaskletStep step = new TaskletStep(new StubTasklet(true, false), new JobRepositorySupport());
step.execute(stepExecution);
assertNotNull(stepExecution.getStartTime());
assertSame(ExitStatus.FAILED, stepExecution.getExitStatus());
@@ -41,11 +62,12 @@ public class TaskletStepTest extends TestCase {
}
public void testExceptionExecution() throws StepInterruptedException, BatchCriticalException {
- TaskletStep step = new TaskletStep(new StubTasklet(false, true), new StubJobRepository());
+ TaskletStep step = new TaskletStep(new StubTasklet(false, true), new JobRepositorySupport());
try {
step.execute(stepExecution);
fail();
- } catch (BatchCriticalException e) {
+ }
+ catch (BatchCriticalException e) {
assertNotNull(stepExecution.getStartTime());
assertSame(ExitStatus.FAILED, stepExecution.getExitStatus());
assertNotNull(stepExecution.getEndTime());
@@ -77,29 +99,4 @@ public class TaskletStepTest extends TestCase {
}
- private class StubJobRepository implements JobRepository {
-
- public JobExecution createJobExecution(Job job, JobParameters jobParameters)
- throws JobExecutionAlreadyRunningException {
- // TODO Auto-generated method stub
- return null;
- }
-
- public void saveOrUpdate(JobExecution jobExecution) {
- // TODO Auto-generated method stub
- }
-
- public void saveOrUpdate(StepExecution stepExecution) {
- // TODO Auto-generated method stub
- }
-
- public void update(JobInstance jobInstance) {
- // TODO Auto-generated method stub
- }
-
- public void update(StepInstance stepInstance) {
- // TODO Auto-generated method stub
- }
-
- }
}
diff --git a/spring-batch-samples/src/main/resources/jobs/infiniteLoopJob.xml b/spring-batch-samples/src/main/resources/jobs/infiniteLoopJob.xml
index 91b78b1ae..14b088b86 100644
--- a/spring-batch-samples/src/main/resources/jobs/infiniteLoopJob.xml
+++ b/spring-batch-samples/src/main/resources/jobs/infiniteLoopJob.xml
@@ -21,11 +21,10 @@
-
+
-
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 c2e8e804f..cb8b1ce67 100644
--- a/spring-batch-samples/src/main/resources/simple-container-definition.xml
+++ b/spring-batch-samples/src/main/resources/simple-container-definition.xml
@@ -83,15 +83,20 @@
-
+
-
+
+
+
+