diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/JobExecution.java b/spring-batch-core/src/main/java/org/springframework/batch/core/JobExecution.java index 7207d344b..4b77e786f 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/JobExecution.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/JobExecution.java @@ -16,6 +16,8 @@ package org.springframework.batch.core; +import java.io.IOException; +import java.io.ObjectInputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Date; @@ -51,7 +53,7 @@ public class JobExecution extends Entity { private volatile ExecutionContext executionContext = new ExecutionContext(); - private volatile List failureExceptions = new ArrayList(); + private transient volatile List failureExceptions = new ArrayList(); /** * Because a JobExecution isn't valid unless the job is set, this @@ -158,14 +160,6 @@ public class JobExecution extends Entity { return stepExecution; } - /* - * (non-Javadoc) - * @see org.springframework.batch.core.domain.Entity#toString() - */ - public String toString() { - return super.toString() + ", startTime=" + startTime + ", endTime=" + endTime + ", job=[" + jobInstance + "]"; - } - /** * Test if this {@link JobExecution} indicates that it is running. It should * be noted that this does not necessarily mean that it has been persisted @@ -261,17 +255,6 @@ public class JobExecution extends Entity { return failureExceptions; } - /** - * Set the list of failure causing exceptions for this JobExecution. It - * should be noted that the exceptions should only be for the job execution - * not step executions. - * - * @param failureExceptions - */ - public void setFailureExceptions(List failureExceptions) { - this.failureExceptions = failureExceptions; - } - /** * Add the provided throwable to the failure exception list. * @@ -297,4 +280,21 @@ public class JobExecution extends Entity { return allExceptions; } + + /** + * Deserialise and ensure transient fields are re-instantiated when read back + */ + private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + failureExceptions = new ArrayList(); + } + + /* + * (non-Javadoc) + * @see org.springframework.batch.core.domain.Entity#toString() + */ + public String toString() { + return super.toString() + String.format(", startTime=%s, endTime=%s, lastUpdated=%s, status=%s, exitStatus=%s, job=[%s]",startTime,endTime,lastUpdated,status,exitStatus,jobInstance); + } + } \ No newline at end of file diff --git a/spring-batch-core/src/main/java/org/springframework/batch/core/StepExecution.java b/spring-batch-core/src/main/java/org/springframework/batch/core/StepExecution.java index 7ba558f92..77ef97477 100644 --- a/spring-batch-core/src/main/java/org/springframework/batch/core/StepExecution.java +++ b/spring-batch-core/src/main/java/org/springframework/batch/core/StepExecution.java @@ -16,6 +16,8 @@ package org.springframework.batch.core; +import java.io.IOException; +import java.io.ObjectInputStream; import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -467,6 +469,14 @@ public class StepExecution extends Entity { return stepName.equals(other.getStepName()) && (jobExecutionId.equals(other.getJobExecutionId())); } + /** + * Deserialise and ensure transient fields are re-instantiated when read back + */ + private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { + stream.defaultReadObject(); + failureExceptions = new ArrayList(); + } + /* * (non-Javadoc) * @@ -480,8 +490,8 @@ public class StepExecution extends Entity { public String toString() { return super.toString() - + String.format(", name=%s, readCount=%d, filterCount=%d, writeCount=%d readSkipCount=%d, writeSkipCount=%d" - + ", commitCount=%d, rollbackCount=%d", stepName, readCount, filterCount, writeCount, readSkipCount, writeSkipCount, + + String.format(", name=%s, status=%s, exitStatus=%s, readCount=%d, filterCount=%d, writeCount=%d readSkipCount=%d, writeSkipCount=%d" + + ", commitCount=%d, rollbackCount=%d", stepName, status, exitStatus, readCount, filterCount, writeCount, readSkipCount, writeSkipCount, commitCount, rollbackCount); } diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/JobExecutionTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/JobExecutionTests.java index f396edc4d..ee1cc1beb 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/JobExecutionTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/JobExecutionTests.java @@ -172,6 +172,7 @@ public class JobExecutionTests { JobExecution deserialize = (JobExecution) SerializationUtils.deserialize(serialized); assertEquals(execution, deserialize); assertNotNull(deserialize.createStepExecution("foo")); + assertNotNull(deserialize.getFailureExceptions()); } public void testFailureExceptions(){ diff --git a/spring-batch-core/src/test/java/org/springframework/batch/core/StepExecutionTests.java b/spring-batch-core/src/test/java/org/springframework/batch/core/StepExecutionTests.java index d41c1daab..7ac5711f2 100644 --- a/spring-batch-core/src/test/java/org/springframework/batch/core/StepExecutionTests.java +++ b/spring-batch-core/src/test/java/org/springframework/batch/core/StepExecutionTests.java @@ -263,6 +263,7 @@ public class StepExecutionTests { assertEquals(execution, deserialized); assertEquals(status, deserialized.getExitStatus()); + assertNotNull(deserialized.getFailureExceptions()); } @Test diff --git a/spring-batch-samples/src/main/java/org/springframework/batch/sample/common/InfiniteLoopWriter.java b/spring-batch-samples/src/main/java/org/springframework/batch/sample/common/InfiniteLoopWriter.java index 8f3cbdb13..feae9acc0 100644 --- a/spring-batch-samples/src/main/java/org/springframework/batch/sample/common/InfiniteLoopWriter.java +++ b/spring-batch-samples/src/main/java/org/springframework/batch/sample/common/InfiniteLoopWriter.java @@ -21,6 +21,7 @@ import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.batch.core.StepExecution; +import org.springframework.batch.core.StepExecutionListener; import org.springframework.batch.core.listener.StepExecutionListenerSupport; import org.springframework.batch.item.ItemWriter; @@ -32,13 +33,21 @@ import org.springframework.batch.item.ItemWriter; * @author Lucas Ward * */ -public class InfiniteLoopWriter extends StepExecutionListenerSupport implements - ItemWriter { +public class InfiniteLoopWriter extends StepExecutionListenerSupport implements ItemWriter { private StepExecution stepExecution; + private int count = 0; - private static final Log logger = LogFactory - .getLog(InfiniteLoopWriter.class); + + private static final Log logger = LogFactory.getLog(InfiniteLoopWriter.class); + + /** + * @see StepExecutionListener#beforeStep(StepExecution) + */ + @Override + public void beforeStep(StepExecution stepExecution) { + this.stepExecution = stepExecution; + } /** * @@ -50,7 +59,8 @@ public class InfiniteLoopWriter extends StepExecutionListenerSupport implements public void write(List items) throws Exception { try { Thread.sleep(500); - } catch (InterruptedException e) { + } + catch (InterruptedException e) { Thread.currentThread().interrupt(); throw new RuntimeException("Job interrupted."); }