diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/StepExecutionListenerSupport.java b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/StepExecutionListenerSupport.java index b89cff776..327a4cdc7 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/listener/StepExecutionListenerSupport.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/listener/StepExecutionListenerSupport.java @@ -38,10 +38,4 @@ public class StepExecutionListenerSupport implements StepExecutionListener { public void beforeStep(StepExecution stepExecution) { } - /* (non-Javadoc) - * @see org.springframework.batch.core.domain.StepListener#onError(java.lang.Throwable) - */ - public ExitStatus onErrorInStep(StepExecution stepExecution, Throwable e) { - return null; - } } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/TaskletStepExceptionTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/TaskletStepExceptionTests.java index 88678e050..c1c68e7c1 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/TaskletStepExceptionTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/item/TaskletStepExceptionTests.java @@ -36,227 +36,232 @@ import org.springframework.transaction.support.DefaultTransactionStatus; * Tests for the behavior of TaskletStep in a failure scenario. * * @author Lucas Ward - * + * */ public class TaskletStepExceptionTests { TaskletStep taskletStep; + StepExecution stepExecution; + UpdateCountingJobRepository jobRepository; + static RuntimeException taskletException = new RuntimeException(); + static JobInterruptedException interruptedException = new JobInterruptedException(""); - + @Before - public void init(){ + public void init() { taskletStep = new TaskletStep(); taskletStep.setTasklet(new ExceptionTasklet()); jobRepository = new UpdateCountingJobRepository(); taskletStep.setJobRepository(jobRepository); taskletStep.setTransactionManager(new ResourcelessTransactionManager()); - - JobInstance jobInstance = new JobInstance(1L, new JobParameters(), "testJob" ); + + JobInstance jobInstance = new JobInstance(1L, new JobParameters(), "testJob"); JobExecution jobExecution = new JobExecution(jobInstance); stepExecution = new StepExecution("testStep", jobExecution); } - + @Test - public void testApplicationException() throws Exception{ - + public void testApplicationException() throws Exception { + taskletStep.execute(stepExecution); assertEquals(FAILED, stepExecution.getStatus()); } - + @Test - public void testInterrupted() throws Exception{ - taskletStep.setStepExecutionListeners(new StepExecutionListener[]{new InterruptionListener()}); + public void testInterrupted() throws Exception { + taskletStep.setStepExecutionListeners(new StepExecutionListener[] { new InterruptionListener() }); taskletStep.execute(stepExecution); assertEquals(STOPPED, stepExecution.getStatus()); } - + @Test - public void testOpenFailure() throws Exception{ + public void testOpenFailure() throws Exception { final RuntimeException exception = new RuntimeException(); - taskletStep.setStreams(new ItemStream[]{new ItemStreamSupport(){ + taskletStep.setStreams(new ItemStream[] { new ItemStreamSupport() { @Override - public void open(ExecutionContext executionContext) - throws ItemStreamException { + public void open(ExecutionContext executionContext) throws ItemStreamException { throw exception; } - }}); - + } }); + taskletStep.execute(stepExecution); assertEquals(FAILED, stepExecution.getStatus()); assertTrue(stepExecution.getFailureExceptions().contains(exception)); - assertEquals(1,jobRepository.getUpdateCount()); + assertEquals(1, jobRepository.getUpdateCount()); } - + @Test - public void testBeforeStepFailure() throws Exception{ - + public void testBeforeStepFailure() throws Exception { + final RuntimeException exception = new RuntimeException(); - taskletStep.setStepExecutionListeners(new StepExecutionListenerSupport[]{new StepExecutionListenerSupport(){ + taskletStep.setStepExecutionListeners(new StepExecutionListenerSupport[] { new StepExecutionListenerSupport() { @Override public void beforeStep(StepExecution stepExecution) { throw exception; } - }}); + } }); taskletStep.execute(stepExecution); assertEquals(FAILED, stepExecution.getStatus()); assertTrue(stepExecution.getFailureExceptions().contains(exception)); - assertEquals(1,jobRepository.getUpdateCount()); + assertEquals(1, jobRepository.getUpdateCount()); } - + @Test - public void testAfterStepFailure() throws Exception{ - + public void testAfterStepFailure() throws Exception { + final RuntimeException exception = new RuntimeException(); - taskletStep.setStepExecutionListeners(new StepExecutionListenerSupport[]{new StepExecutionListenerSupport(){ + taskletStep.setStepExecutionListeners(new StepExecutionListenerSupport[] { new StepExecutionListenerSupport() { @Override public ExitStatus afterStep(StepExecution stepExecution) { throw exception; } - }}); - taskletStep.setTasklet(new Tasklet(){ + } }); + taskletStep.setTasklet(new Tasklet() { - public ExitStatus execute(StepContribution contribution, - AttributeAccessor attributes) throws Exception { + public ExitStatus execute(StepContribution contribution, AttributeAccessor attributes) throws Exception { return ExitStatus.FINISHED; } - + }); taskletStep.execute(stepExecution); - assertEquals(FAILED, stepExecution.getStatus()); - assertTrue(stepExecution.getFailureExceptions().contains(exception)); - assertEquals(2,jobRepository.getUpdateCount()); + assertEquals(COMPLETED, stepExecution.getStatus()); + assertFalse(stepExecution.getFailureExceptions().contains(exception)); + assertEquals(3, jobRepository.getUpdateCount()); } - + @Test - public void testOnErrorInStepFAilure() throws Exception{ - + /** + * Exception in afterStep is ignored (only logged). + */ + public void testAfterStepFAilure() throws Exception { + final RuntimeException exception = new RuntimeException(); - taskletStep.setStepExecutionListeners(new StepExecutionListenerSupport[]{new StepExecutionListenerSupport(){ + taskletStep.setStepExecutionListeners(new StepExecutionListenerSupport[] { new StepExecutionListenerSupport() { @Override - public ExitStatus onErrorInStep(StepExecution stepExecution, - Throwable e) { + public ExitStatus afterStep(StepExecution stepExecution) { throw exception; } - }}); + } }); + taskletStep.execute(stepExecution); + assertEquals(FAILED, stepExecution.getStatus()); + assertTrue(stepExecution.getFailureExceptions().contains(taskletException)); + assertFalse(stepExecution.getFailureExceptions().contains(exception)); + assertEquals(1, jobRepository.getUpdateCount()); + } + + @Test + public void testCloseError() throws Exception { + + final RuntimeException exception = new RuntimeException(); + taskletStep.setStreams(new ItemStream[] { new ItemStreamSupport() { + @Override + public void close(ExecutionContext executionContext) throws ItemStreamException { + throw exception; + } + } }); + taskletStep.execute(stepExecution); assertEquals(FAILED, stepExecution.getStatus()); assertTrue(stepExecution.getFailureExceptions().contains(taskletException)); assertTrue(stepExecution.getFailureExceptions().contains(exception)); - assertEquals(1,jobRepository.getUpdateCount()); + assertEquals(1, jobRepository.getUpdateCount()); } - + @Test - public void testCloseError() throws Exception{ - + public void testCommitError() throws Exception { + final RuntimeException exception = new RuntimeException(); - taskletStep.setStreams(new ItemStream[]{new ItemStreamSupport(){ + taskletStep.setTransactionManager(new ResourcelessTransactionManager() { @Override - public void close(ExecutionContext executionContext) - throws ItemStreamException { - throw exception; - } - }}); - - taskletStep.execute(stepExecution); - assertEquals(FAILED, stepExecution.getStatus()); - assertTrue(stepExecution.getFailureExceptions().contains(taskletException)); - assertTrue(stepExecution.getFailureExceptions().contains(exception)); - assertEquals(1,jobRepository.getUpdateCount()); - } - - @Test - public void testCommitError() throws Exception{ - - final RuntimeException exception = new RuntimeException(); - taskletStep.setTransactionManager(new ResourcelessTransactionManager(){ - @Override - protected void doCommit(DefaultTransactionStatus status) - throws TransactionException { + protected void doCommit(DefaultTransactionStatus status) throws TransactionException { throw exception; } }); - - taskletStep.setTasklet(new Tasklet(){ - public ExitStatus execute(StepContribution contribution, - AttributeAccessor attributes) throws Exception { + taskletStep.setTasklet(new Tasklet() { + + public ExitStatus execute(StepContribution contribution, AttributeAccessor attributes) throws Exception { return ExitStatus.FINISHED; } - + }); - + taskletStep.execute(stepExecution); assertEquals(UNKNOWN, stepExecution.getStatus()); Throwable e = stepExecution.getFailureExceptions().get(0); assertEquals(exception, e.getCause()); } - + @Test - public void testUpdateError() throws Exception{ - + public void testUpdateError() throws Exception { + final RuntimeException exception = new RuntimeException(); - taskletStep.setJobRepository(new UpdateCountingJobRepository(){ + taskletStep.setJobRepository(new UpdateCountingJobRepository() { @Override public void update(StepExecution arg0) { throw exception; } }); - + taskletStep.execute(stepExecution); assertEquals(UNKNOWN, stepExecution.getStatus()); assertTrue(stepExecution.getFailureExceptions().contains(taskletException)); assertTrue(stepExecution.getFailureExceptions().contains(exception)); } - - private static class ExceptionTasklet implements Tasklet{ - public ExitStatus execute(StepContribution contribution, - AttributeAccessor attributes) throws Exception { + private static class ExceptionTasklet implements Tasklet { + + public ExitStatus execute(StepContribution contribution, AttributeAccessor attributes) throws Exception { throw taskletException; } } - - private static class InterruptionListener extends StepExecutionListenerSupport{ - + + private static class InterruptionListener extends StepExecutionListenerSupport { + @Override public void beforeStep(StepExecution stepExecution) { stepExecution.setTerminateOnly(); } } - - private static class UpdateCountingJobRepository implements JobRepository{ + + private static class UpdateCountingJobRepository implements JobRepository { private int updateCount = 0; - - public void add(StepExecution stepExecution) { } - public JobExecution createJobExecution(String jobName, - JobParameters jobParameters) - throws JobExecutionAlreadyRunningException, - JobRestartException, JobInstanceAlreadyCompleteException { - return null;} + public void add(StepExecution stepExecution) { + } - public StepExecution getLastStepExecution(JobInstance jobInstance, - String stepName) {return null;} + public JobExecution createJobExecution(String jobName, JobParameters jobParameters) + throws JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException { + return null; + } - public int getStepExecutionCount(JobInstance jobInstance, - String stepName) {return 0; } + public StepExecution getLastStepExecution(JobInstance jobInstance, String stepName) { + return null; + } - public boolean isJobInstanceExists(String jobName, - JobParameters jobParameters) {return false;} + public int getStepExecutionCount(JobInstance jobInstance, String stepName) { + return 0; + } - public void update(JobExecution jobExecution) { } + public boolean isJobInstanceExists(String jobName, JobParameters jobParameters) { + return false; + } + + public void update(JobExecution jobExecution) { + } public void update(StepExecution stepExecution) { updateCount++; } - public void updateExecutionContext(StepExecution stepExecution) { } - + public void updateExecutionContext(StepExecution stepExecution) { + } + public int getUpdateCount() { return updateCount; } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/TaskletStepTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/TaskletStepTests.java index 875ae491c..a3d599b3e 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/TaskletStepTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/step/tasklet/TaskletStepTests.java @@ -254,7 +254,8 @@ public class TaskletStepTests { step.setTasklet(new TestingChunkOrientedTasklet(itemReader, itemWriter)); step.registerStepExecutionListener(new StepExecutionListenerSupport() { - public ExitStatus onErrorInStep(StepExecution stepExecution, Throwable e) { + @Override + public ExitStatus afterStep(StepExecution stepExecution) { return ExitStatus.FAILED.addExitDescription("FOO"); } }); @@ -475,8 +476,8 @@ public class TaskletStepTests { @Test public void testDirectlyInjectedListenerOnError() throws Exception { step.registerStepExecutionListener(new StepExecutionListenerSupport() { - public ExitStatus onErrorInStep(StepExecution stepExecution, Throwable e) { - list.add(e); + public ExitStatus afterStep(StepExecution stepExecution) { + list.add("exception"); return null; } }); @@ -755,7 +756,7 @@ public class TaskletStepTests { /** * Exception in {@link StepExecutionListener#afterStep(StepExecution)} - * causes step to fail. + * doesn't cause step failure. * @throws JobInterruptedException */ @Test @@ -769,9 +770,7 @@ public class TaskletStepTests { StepExecution stepExecution = new StepExecution(step.getName(), new JobExecution(jobInstance)); step.execute(stepExecution); - Throwable expected = stepExecution.getFailureExceptions().get(0); - assertEquals("exception thrown in afterStep to signal failure", expected.getMessage()); - assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); + assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); }