/** * Return all failure causing exceptions for this JobExecution, including * step executions. * * @return List<Throwable> containing all exceptions causing failure for * this JobExecution. */ public synchronized List<Throwable> getAllFailureExceptions() { Set<Throwable> allExceptions = new HashSet<>(failureExceptions); for (StepExecution stepExecution : stepExecutions) { allExceptions.addAll(stepExecution.getFailureExceptions()); } return new ArrayList<>(allExceptions); }
@Test public void testAddException() throws Exception{ RuntimeException exception = new RuntimeException(); assertEquals(0, execution.getFailureExceptions().size()); execution.addFailureException(exception); assertEquals(1, execution.getFailureExceptions().size()); assertEquals(exception, execution.getFailureExceptions().get(0)); }
@Test public void testCloseError() throws Exception { final RuntimeException exception = new RuntimeException(); taskletStep.setStreams(new ItemStream[] { new ItemStreamSupport() { @Override public void close() throws ItemStreamException { super.close(); throw exception; } } }); taskletStep.execute(stepExecution); assertEquals(FAILED, stepExecution.getStatus()); assertTrue(stepExecution.getFailureExceptions().contains(taskletException)); assertTrue(stepExecution.getFailureExceptions().contains(exception)); assertEquals(2, jobRepository.getUpdateCount()); }
@Test /* * Exception in afterStep is ignored (only logged). */ public void testAfterStepFailureWhenTaskletFails() throws Exception { final RuntimeException exception = new RuntimeException(); taskletStep.setStepExecutionListeners(new StepExecutionListenerSupport[] { new StepExecutionListenerSupport() { @Override 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(2, jobRepository.getUpdateCount()); }
@Test public void testInterruptedAfterUnknownStatus() throws Exception { step1.setStartLimit(5); step2.setStartLimit(5); final JobInterruptedException exception = new JobInterruptedException("Interrupt!", BatchStatus.UNKNOWN); step1.setProcessException(exception); job.execute(jobExecution); assertEquals(1, jobExecution.getAllFailureExceptions().size()); assertEquals(exception, jobExecution.getStepExecutions().iterator().next().getFailureExceptions().get(0)); assertEquals(0, list.size()); checkRepository(BatchStatus.UNKNOWN, ExitStatus.STOPPED); }
@Test public void testRepositoryErrorOnUpdateStepExecution() throws Exception { taskletStep.setTasklet(new Tasklet() { @Override public RepeatStatus execute(StepContribution contribution, ChunkContext attributes) throws Exception { return RepeatStatus.FINISHED; } }); jobRepository.setFailOnUpdateStepExecution(2); taskletStep.execute(stepExecution); assertEquals(UNKNOWN, stepExecution.getStatus()); Throwable e = stepExecution.getFailureExceptions().get(0); assertEquals("Expected exception in step execution persistence", e.getMessage()); }
@Test public void testInterrupted() throws Exception { step1.setStartLimit(5); step2.setStartLimit(5); final JobInterruptedException exception = new JobInterruptedException("Interrupt!"); step1.setProcessException(exception); job.execute(jobExecution); assertEquals(1, jobExecution.getAllFailureExceptions().size()); assertEquals(exception, jobExecution.getStepExecutions().iterator().next().getFailureExceptions().get(0)); assertEquals(0, list.size()); checkRepository(BatchStatus.STOPPED, ExitStatus.STOPPED); }
@Test public void testExecuteException() throws Exception { step.setJob(new JobSupport("child") { @Override public void execute(JobExecution execution) throws UnexpectedJobExecutionException { throw new RuntimeException("FOO"); } }); step.afterPropertiesSet(); step.execute(stepExecution); assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); assertEquals("FOO", stepExecution.getFailureExceptions().get(0).getMessage()); }
@Test public void testRepositoryErrorOnExecutionContext() throws Exception { taskletStep.setTasklet(new Tasklet() { @Override public RepeatStatus execute(StepContribution contribution, ChunkContext attributes) throws Exception { return RepeatStatus.FINISHED; } }); jobRepository.setFailOnUpdateExecutionContext(true); taskletStep.execute(stepExecution); assertEquals(UNKNOWN, stepExecution.getStatus()); Throwable e = stepExecution.getFailureExceptions().get(0); assertEquals("Expected exception in step execution context persistence", e.getMessage()); }
@Test public void testRepositoryErrorOnFailure() throws Exception { taskletStep.setTasklet(new Tasklet() { @Override public RepeatStatus execute(StepContribution contribution, ChunkContext attributes) throws Exception { throw new RuntimeException("Tasklet exception"); } }); jobRepository.setFailOnUpdateExecutionContext(true); taskletStep.execute(stepExecution); assertEquals(UNKNOWN, stepExecution.getStatus()); Throwable e = stepExecution.getFailureExceptions().get(0); assertEquals("Expected exception in step execution context persistence", e.getMessage()); }
@Test public void testOpenFailure() throws Exception { final RuntimeException exception = new RuntimeException(); taskletStep.setStreams(new ItemStream[] { new ItemStreamSupport() { @Override public void open(ExecutionContext executionContext) throws ItemStreamException { throw exception; } } }); taskletStep.execute(stepExecution); assertEquals(FAILED, stepExecution.getStatus()); assertTrue(stepExecution.getFailureExceptions().contains(exception)); assertEquals(2, jobRepository.getUpdateCount()); }
@Test public void testBeforeStepFailure() throws Exception { final RuntimeException exception = new RuntimeException(); 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(2, jobRepository.getUpdateCount()); }
@Test public void testRepositoryErrorOnExecutionContextInTransaction() throws Exception { taskletStep.setTasklet(new Tasklet() { @Override public RepeatStatus execute(StepContribution contribution, ChunkContext attributes) throws Exception { return RepeatStatus.FINISHED; } }); jobRepository.setFailOnUpdateExecutionContext(true); jobRepository.setFailInTransaction(true); taskletStep.execute(stepExecution); assertEquals(FAILED, stepExecution.getStatus()); Throwable e = stepExecution.getFailureExceptions().get(0); assertEquals("JobRepository failure forcing rollback", e.getMessage()); }
@Test public void testRepositoryErrorOnUpdateStepExecutionInTransaction() throws Exception { taskletStep.setTasklet(new Tasklet() { @Override public RepeatStatus execute(StepContribution contribution, ChunkContext attributes) throws Exception { return RepeatStatus.FINISHED; } }); jobRepository.setFailOnUpdateStepExecution(1); jobRepository.setFailInTransaction(true); taskletStep.execute(stepExecution); assertEquals(FAILED, stepExecution.getStatus()); Throwable e = stepExecution.getFailureExceptions().get(0); assertEquals("JobRepository failure forcing rollback", e.getMessage()); }
@Test public void testAfterChunkListenerException() throws Exception{ factory.setListeners(new StepListener []{new ExceptionThrowingChunkListener(2)}); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(FAILED, stepExecution.getStatus()); assertEquals(FAILED.toString(), stepExecution.getExitStatus().getExitCode()); assertTrue(stepExecution.getCommitCount() > 0);//Make sure exception was thrown in after, not before Throwable e = stepExecution.getFailureExceptions().get(0); assertThat(e, instanceOf(FatalStepExecutionException.class)); assertThat(e.getCause(), instanceOf(IllegalArgumentException.class)); }
@Test public void testBeforeChunkListenerException() throws Exception{ factory.setListeners(new StepListener []{new ExceptionThrowingChunkListener(1)}); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(FAILED, stepExecution.getStatus()); assertEquals(FAILED.toString(), stepExecution.getExitStatus().getExitCode()); assertTrue(stepExecution.getCommitCount() == 0);//Make sure exception was thrown in after, not before Throwable e = stepExecution.getFailureExceptions().get(0); assertThat(e, instanceOf(FatalStepExecutionException.class)); assertThat(e.getCause(), instanceOf(IllegalArgumentException.class)); }
@Test public void testRepositoryErrorOnUpdateStepExecutionInTransactionRollbackFailed() throws Exception { taskletStep.setTasklet(new Tasklet() { @Override public RepeatStatus execute(StepContribution contribution, ChunkContext attributes) throws Exception { return RepeatStatus.FINISHED; } }); taskletStep.setTransactionManager(new FailingRollbackTransactionManager()); jobRepository.setFailOnUpdateStepExecution(1); jobRepository.setFailInTransaction(true); taskletStep.execute(stepExecution); assertEquals(UNKNOWN, stepExecution.getStatus()); Throwable e = stepExecution.getFailureExceptions().get(0); assertEquals("Expected exception in rollback", e.getMessage()); }
@Test public void testRepositoryErrorOnExecutionContextInTransactionRollbackFailed() throws Exception { taskletStep.setTasklet(new Tasklet() { @Override public RepeatStatus execute(StepContribution contribution, ChunkContext attributes) throws Exception { return RepeatStatus.FINISHED; } }); taskletStep.setTransactionManager(new FailingRollbackTransactionManager()); jobRepository.setFailOnUpdateExecutionContext(true); jobRepository.setFailInTransaction(true); taskletStep.execute(stepExecution); assertEquals(UNKNOWN, stepExecution.getStatus()); Throwable e = stepExecution.getFailureExceptions().get(0); assertEquals("Expected exception in rollback", e.getMessage()); }
@Test public void testSerialization() throws Exception { ExitStatus status = ExitStatus.NOOP; execution.setExitStatus(status); execution.setExecutionContext(foobarEc); byte[] serialized = SerializationUtils.serialize(execution); StepExecution deserialized = (StepExecution) SerializationUtils.deserialize(serialized); assertEquals(execution, deserialized); assertEquals(status, deserialized.getExitStatus()); assertNotNull(deserialized.getFailureExceptions()); }
@Test public void testStatusForFinalUpdateFailedException() throws Exception { step.setJobRepository(new JobRepositorySupport()); step.setStreams(new ItemStream[] { new ItemStreamSupport() { @Override public void close() throws ItemStreamException { super.close(); throw new RuntimeException("Bar"); } } }); JobExecution jobExecutionContext = new JobExecution(jobInstance, jobParameters); StepExecution stepExecution = new StepExecution(step.getName(), jobExecutionContext); step.execute(stepExecution); // The job actually completed, but the streams couldn't be closed. assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus()); String msg = stepExecution.getExitStatus().getExitDescription(); assertEquals("", msg); Throwable ex = stepExecution.getFailureExceptions().get(0); // The original rollback was caused by this one: assertEquals("Bar", ex.getMessage()); }