OPEN - issue BATCH-339: ItemStream.mark() and reset() should throw a checked exception
http://jira.springframework.org/browse/BATCH-339 Introduce MrakFailedException and ResetFailedException (unchecked for now). ResetFailedException has to be dealt with specially in the StepExecutor.
This commit is contained in:
@@ -57,7 +57,9 @@ public class BatchStatus implements Serializable {
|
||||
|
||||
public static final BatchStatus STOPPED = new BatchStatus("STOPPED");
|
||||
|
||||
private static final BatchStatus[] VALUES = { STARTING, STARTED, COMPLETED, FAILED, STOPPED };
|
||||
public static final BatchStatus UNKNOWN = new BatchStatus("UNKNOWN");
|
||||
|
||||
private static final BatchStatus[] VALUES = { STARTING, STARTED, COMPLETED, FAILED, STOPPED, UNKNOWN };
|
||||
|
||||
/**
|
||||
* Given a string representation of a status, return the appropriate BatchStatus.
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
*/
|
||||
|
||||
package org.springframework.batch.core.domain;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Batch domain entity representing a step which is sequentially executed by a
|
||||
|
||||
@@ -17,8 +17,6 @@ package org.springframework.batch.core.domain;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.item.ExecutionAttributes;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
|
||||
@@ -129,15 +129,23 @@ public class SimpleJob extends JobSupport {
|
||||
private boolean shouldStart(StepInstance stepInstance, Step step) {
|
||||
|
||||
BatchStatus stepStatus;
|
||||
//if the last execution is null, the step has never been executed.
|
||||
if(stepInstance.getLastExecution() == null){
|
||||
// if the last execution is null, the step has never been executed.
|
||||
if (stepInstance.getLastExecution() == null) {
|
||||
stepStatus = BatchStatus.STARTING;
|
||||
}
|
||||
else{
|
||||
else {
|
||||
stepStatus = stepInstance.getLastExecution().getStatus();
|
||||
}
|
||||
|
||||
if (stepStatus== BatchStatus.COMPLETED && step.isAllowStartIfComplete() == false) {
|
||||
|
||||
if (stepStatus == BatchStatus.UNKNOWN) {
|
||||
throw new BatchCriticalException(
|
||||
"Cannot restart step from UNKNOWN status. " +
|
||||
"The last execution ended with a failure that could not be rolled back, " +
|
||||
"so it may be dangerous to proceed. " +
|
||||
"Manual intervention is probably necessary.");
|
||||
}
|
||||
|
||||
if (stepStatus == BatchStatus.COMPLETED && step.isAllowStartIfComplete() == false) {
|
||||
// step is complete, false should be returned, indicating that the
|
||||
// step should not be started
|
||||
return false;
|
||||
|
||||
@@ -18,6 +18,8 @@ package org.springframework.batch.execution.step.simple;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.core.domain.BatchStatus;
|
||||
import org.springframework.batch.core.domain.Step;
|
||||
import org.springframework.batch.core.domain.StepContribution;
|
||||
@@ -33,8 +35,9 @@ import org.springframework.batch.execution.scope.StepScope;
|
||||
import org.springframework.batch.execution.scope.StepSynchronizationManager;
|
||||
import org.springframework.batch.io.Skippable;
|
||||
import org.springframework.batch.io.exception.BatchCriticalException;
|
||||
import org.springframework.batch.item.ItemStream;
|
||||
import org.springframework.batch.item.ExecutionAttributes;
|
||||
import org.springframework.batch.item.ItemStream;
|
||||
import org.springframework.batch.item.exception.ResetFailedException;
|
||||
import org.springframework.batch.item.stream.SimpleStreamManager;
|
||||
import org.springframework.batch.item.stream.StreamManager;
|
||||
import org.springframework.batch.repeat.ExitStatus;
|
||||
@@ -70,6 +73,8 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
public class SimpleStepExecutor {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(SimpleStepExecutor.class);
|
||||
|
||||
private RepeatOperations chunkOperations = new RepeatTemplate();
|
||||
|
||||
private RepeatOperations stepOperations = new RepeatTemplate();
|
||||
@@ -242,7 +247,22 @@ public class SimpleStepExecutor {
|
||||
synchronized (stepExecution) {
|
||||
stepExecution.rollback();
|
||||
}
|
||||
streamManager.rollback(transaction);
|
||||
try {
|
||||
streamManager.rollback(transaction);
|
||||
}
|
||||
catch (ResetFailedException e) {
|
||||
// The original Throwable cause is in danger of
|
||||
// being lost here, so we log the reset
|
||||
// failure and re-throw with cause of the rollback.
|
||||
logger.error("Encountered reset error on rollback: "
|
||||
+ "one of the streams may be in an inconsistent state, "
|
||||
+ "so this step should not proceed", e);
|
||||
throw new ResetFailedException(
|
||||
"Encountered reset error on rollback. " +
|
||||
"Consult logs for the cause of the reet failure. " +
|
||||
"The cause of the original rollback is incuded here.",
|
||||
t);
|
||||
}
|
||||
if (t instanceof RuntimeException) {
|
||||
throw (RuntimeException) t;
|
||||
}
|
||||
@@ -271,6 +291,10 @@ public class SimpleStepExecutor {
|
||||
updateStatus(stepExecution, BatchStatus.STOPPED);
|
||||
throw (StepInterruptedException) e.getCause();
|
||||
}
|
||||
else if (e instanceof ResetFailedException) {
|
||||
updateStatus(stepExecution, BatchStatus.UNKNOWN);
|
||||
throw (ResetFailedException) e;
|
||||
}
|
||||
else {
|
||||
updateStatus(stepExecution, BatchStatus.FAILED);
|
||||
throw e;
|
||||
|
||||
@@ -18,8 +18,6 @@ package org.springframework.batch.execution.repository.dao;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.batch.core.domain.BatchStatus;
|
||||
import org.springframework.batch.core.domain.Job;
|
||||
import org.springframework.batch.core.domain.JobExecution;
|
||||
|
||||
@@ -5,7 +5,6 @@ import java.util.List;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.easymock.MockControl;
|
||||
import org.springframework.batch.core.domain.BatchStatus;
|
||||
import org.springframework.batch.core.domain.JobExecution;
|
||||
import org.springframework.batch.core.domain.JobInstance;
|
||||
import org.springframework.batch.core.domain.JobParameters;
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.Map;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.core.domain.BatchStatus;
|
||||
import org.springframework.batch.core.domain.JobExecution;
|
||||
import org.springframework.batch.core.domain.JobInstance;
|
||||
import org.springframework.batch.core.domain.JobParameters;
|
||||
@@ -31,6 +32,7 @@ import org.springframework.batch.core.domain.JobSupport;
|
||||
import org.springframework.batch.core.domain.StepContribution;
|
||||
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.tasklet.Tasklet;
|
||||
import org.springframework.batch.execution.repository.SimpleJobRepository;
|
||||
import org.springframework.batch.execution.repository.dao.MapJobDao;
|
||||
@@ -38,10 +40,11 @@ import org.springframework.batch.execution.repository.dao.MapStepDao;
|
||||
import org.springframework.batch.execution.scope.StepScope;
|
||||
import org.springframework.batch.execution.scope.StepSynchronizationManager;
|
||||
import org.springframework.batch.execution.tasklet.ItemOrientedTasklet;
|
||||
import org.springframework.batch.item.ExecutionAttributes;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.ExecutionAttributes;
|
||||
import org.springframework.batch.item.StreamException;
|
||||
import org.springframework.batch.item.exception.ResetFailedException;
|
||||
import org.springframework.batch.item.exception.StreamException;
|
||||
import org.springframework.batch.item.reader.ListItemReader;
|
||||
import org.springframework.batch.item.stream.ItemStreamAdapter;
|
||||
import org.springframework.batch.item.stream.SimpleStreamManager;
|
||||
@@ -55,6 +58,7 @@ import org.springframework.batch.repeat.policy.SimpleCompletionPolicy;
|
||||
import org.springframework.batch.repeat.support.RepeatTemplate;
|
||||
import org.springframework.batch.support.PropertiesConverter;
|
||||
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
|
||||
public class SimpleStepExecutorTests extends TestCase {
|
||||
|
||||
@@ -74,6 +78,8 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
|
||||
private JobInstance jobInstance;
|
||||
|
||||
private ResourcelessTransactionManager transactionManager;
|
||||
|
||||
private ItemReader getReader(String[] args) {
|
||||
return new ListItemReader(Arrays.asList(args));
|
||||
}
|
||||
@@ -98,8 +104,7 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
*/
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
ResourcelessTransactionManager transactionManager = new ResourcelessTransactionManager();
|
||||
|
||||
transactionManager = new ResourcelessTransactionManager();
|
||||
stepConfiguration = new SimpleStep();
|
||||
stepConfiguration.setTasklet(getTasklet(new String[] { "foo", "bar", "spam" }));
|
||||
stepConfiguration.setJobRepository(new JobRepositorySupport());
|
||||
@@ -116,7 +121,7 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
|
||||
jobInstance = new JobInstance(new Long(0), new JobParameters());
|
||||
jobInstance.setJob(new JobSupport("FOO"));
|
||||
|
||||
|
||||
SimpleStreamManager streamManager = new SimpleStreamManager(transactionManager);
|
||||
streamManager.setUseClassNameAsPrefix(false);
|
||||
stepExecutor.setStreamManager(streamManager);
|
||||
@@ -312,9 +317,9 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
stepConfiguration.setSaveExecutionAttributes(true);
|
||||
JobExecution jobExecutionContext = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
|
||||
|
||||
stepExecution.setExecutionAttributes(
|
||||
new ExecutionAttributes(PropertiesConverter.stringToProperties("foo=bar")));
|
||||
|
||||
stepExecution
|
||||
.setExecutionAttributes(new ExecutionAttributes(PropertiesConverter.stringToProperties("foo=bar")));
|
||||
step.setLastExecution(stepExecution);
|
||||
stepExecutor.execute(stepExecution);
|
||||
|
||||
@@ -324,8 +329,9 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
}
|
||||
|
||||
/*
|
||||
* Test that a job that is being restarted, but has saveExecutionAttributes set to
|
||||
* false, doesn't have restore or getExecutionAttributes called on it.
|
||||
* Test that a job that is being restarted, but has saveExecutionAttributes
|
||||
* set to false, doesn't have restore or getExecutionAttributes called on
|
||||
* it.
|
||||
*/
|
||||
public void testNoSaveExecutionAttributesRestartableJob() {
|
||||
StepInstance step = new StepInstance(new Long(1));
|
||||
@@ -348,8 +354,9 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
}
|
||||
|
||||
/*
|
||||
* Even though the job is restarted, and saveExecutionAttributes is true, nothing
|
||||
* will be restored because the Tasklet does not implement Restartable.
|
||||
* Even though the job is restarted, and saveExecutionAttributes is true,
|
||||
* nothing will be restored because the Tasklet does not implement
|
||||
* Restartable.
|
||||
*/
|
||||
public void testRestartJobOnNonRestartableTasklet() throws Exception {
|
||||
StepInstance step = new StepInstance(new Long(1));
|
||||
@@ -479,41 +486,88 @@ public class SimpleStepExecutorTests extends TestCase {
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* StepExecutor will never pass StepInterruptedException to the
|
||||
* exceptionClassifier. This may or may not stay the same, so the test will
|
||||
* remain commented out for reference purposes.
|
||||
*/
|
||||
/*
|
||||
* public void testExitCodeInterruptedClassification(){
|
||||
*
|
||||
* StepInterruptionPolicy interruptionPolicy = new StepInterruptionPolicy(){
|
||||
*
|
||||
* public void checkInterrupted(RepeatContext context) throws
|
||||
* StepInterruptedException { throw new StepInterruptedException(""); } };
|
||||
*
|
||||
* stepExecutor.setInterruptionPolicy(interruptionPolicy);
|
||||
*
|
||||
* Tasklet tasklet = new Tasklet(){
|
||||
*
|
||||
* public ExitStatus execute() throws Exception { int counter = 0;
|
||||
* counter++;
|
||||
*
|
||||
* if(counter == 1){ throw new StepInterruptedException(""); }
|
||||
*
|
||||
* return ExitStatus.CONTINUABLE; } };
|
||||
*
|
||||
* StepInstance step = new StepInstance(new Long(1));
|
||||
* stepConfiguration.setTasklet(tasklet); JobExecutionContext
|
||||
* jobExecutionContext = new JobExecutionContext(new
|
||||
* SimpleJobIdentifier("FOO"), new JobInstance(new Long(3))); StepExecution
|
||||
* stepExecution = new StepExecution(step, jobExecutionContext);
|
||||
*
|
||||
* try{ stepExecutor.process(stepConfiguration, stepExecution); }
|
||||
* catch(Exception ex){
|
||||
* assertEquals(ExitCodeExceptionClassifier.STEP_INTERRUPTED,
|
||||
* step.getStepExecution().getExitCode() );
|
||||
* assertEquals(step.getStepExecution().getExitDescription(),
|
||||
* "java.lang.RuntimeException"); } }
|
||||
*/
|
||||
public void testStatusForInterruptedException() {
|
||||
|
||||
StepInterruptionPolicy interruptionPolicy = new StepInterruptionPolicy() {
|
||||
|
||||
public void checkInterrupted(RepeatContext context) throws StepInterruptedException {
|
||||
throw new StepInterruptedException("");
|
||||
}
|
||||
};
|
||||
|
||||
stepExecutor.setInterruptionPolicy(interruptionPolicy);
|
||||
|
||||
Tasklet tasklet = new Tasklet() {
|
||||
|
||||
public ExitStatus execute() throws Exception {
|
||||
int counter = 0;
|
||||
counter++;
|
||||
|
||||
if (counter == 1) {
|
||||
throw new StepInterruptedException("");
|
||||
}
|
||||
|
||||
return ExitStatus.CONTINUABLE;
|
||||
}
|
||||
};
|
||||
stepExecutor.setTasklet(tasklet);
|
||||
|
||||
StepInstance step = new StepInstance(new Long(1));
|
||||
JobExecution jobExecutionContext = new JobExecution(jobInstance);
|
||||
StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
|
||||
|
||||
stepExecution
|
||||
.setExecutionAttributes(new ExecutionAttributes(PropertiesConverter.stringToProperties("foo=bar")));
|
||||
step.setLastExecution(stepExecution);
|
||||
|
||||
try {
|
||||
stepExecutor.execute(stepExecution);
|
||||
fail("Expected StepInterruptedException");
|
||||
}
|
||||
catch (StepInterruptedException ex) {
|
||||
assertEquals(BatchStatus.STOPPED, stepExecution.getStatus());
|
||||
String msg = stepExecution.getExitStatus().getExitDescription();
|
||||
assertTrue("Message does not contain StepInterruptedException: " + msg, msg
|
||||
.contains("StepInterruptedException"));
|
||||
}
|
||||
}
|
||||
|
||||
public void testStatusForResetFailedException() throws Exception {
|
||||
|
||||
Tasklet tasklet = new Tasklet() {
|
||||
public ExitStatus execute() throws Exception {
|
||||
// Trigger a rollback
|
||||
throw new RuntimeException("Foo");
|
||||
}
|
||||
};
|
||||
stepExecutor.setTasklet(tasklet);
|
||||
stepExecutor.setStreamManager(new SimpleStreamManager(transactionManager) {
|
||||
public void rollback(TransactionStatus status) {
|
||||
super.rollback(status);
|
||||
// Simulate failure on rollback when stream resets
|
||||
throw new ResetFailedException("Bar");
|
||||
}
|
||||
});
|
||||
|
||||
StepInstance step = new StepInstance(new Long(1));
|
||||
JobExecution jobExecutionContext = jobInstance.createJobExecution();
|
||||
StepExecution stepExecution = new StepExecution(step, jobExecutionContext);
|
||||
|
||||
stepExecution
|
||||
.setExecutionAttributes(new ExecutionAttributes(PropertiesConverter.stringToProperties("foo=bar")));
|
||||
step.setLastExecution(stepExecution);
|
||||
|
||||
try {
|
||||
stepExecutor.execute(stepExecution);
|
||||
fail("Expected ResetFailedException");
|
||||
}
|
||||
catch (ResetFailedException ex) {
|
||||
assertEquals(BatchStatus.UNKNOWN, stepExecution.getStatus());
|
||||
String msg = stepExecution.getExitStatus().getExitDescription();
|
||||
assertTrue("Message does not contain ResetFailedException: " + msg, msg.contains("ResetFailedException"));
|
||||
// The original rollback was caused by this one:
|
||||
assertEquals("Foo", ex.getCause().getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemRecoverer;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.KeyedItemReader;
|
||||
import org.springframework.batch.item.StreamException;
|
||||
import org.springframework.batch.item.exception.StreamException;
|
||||
import org.springframework.batch.item.reader.AbstractItemReader;
|
||||
import org.springframework.batch.item.writer.AbstractItemWriter;
|
||||
import org.springframework.batch.repeat.context.RepeatContextSupport;
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.springframework.batch.io.Skippable;
|
||||
import org.springframework.batch.io.file.separator.LineReader;
|
||||
import org.springframework.batch.item.ItemStream;
|
||||
import org.springframework.batch.item.ExecutionAttributes;
|
||||
import org.springframework.batch.item.StreamException;
|
||||
import org.springframework.batch.item.exception.StreamException;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
||||
@@ -34,7 +34,7 @@ import org.springframework.batch.io.support.AbstractTransactionalIoSource;
|
||||
import org.springframework.batch.item.ExecutionAttributes;
|
||||
import org.springframework.batch.item.ItemStream;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.StreamException;
|
||||
import org.springframework.batch.item.exception.StreamException;
|
||||
import org.springframework.batch.item.writer.ItemTransformer;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
@@ -31,7 +31,7 @@ import org.springframework.batch.io.file.transform.AbstractLineTokenizer;
|
||||
import org.springframework.batch.io.file.transform.DelimitedLineTokenizer;
|
||||
import org.springframework.batch.io.file.transform.LineTokenizer;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.StreamException;
|
||||
import org.springframework.batch.item.exception.StreamException;
|
||||
import org.springframework.batch.item.reader.AbstractItemReader;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
@@ -28,6 +28,8 @@ import java.util.Iterator;
|
||||
import org.springframework.batch.io.exception.BatchEnvironmentException;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemStream;
|
||||
import org.springframework.batch.item.exception.MarkFailedException;
|
||||
import org.springframework.batch.item.exception.ResetFailedException;
|
||||
import org.springframework.batch.item.stream.ItemStreamAdapter;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -212,9 +214,9 @@ public class ResourceLineReader extends ItemStreamAdapter implements LineReader,
|
||||
*
|
||||
* @see #reset()
|
||||
*
|
||||
* @throws BatchEnvironmentException if the mark could not be set.
|
||||
* @throws MarkFailedException if the mark could not be set.
|
||||
*/
|
||||
public synchronized void mark() {
|
||||
public synchronized void mark() throws MarkFailedException {
|
||||
getState().mark();
|
||||
}
|
||||
|
||||
@@ -223,10 +225,10 @@ public class ResourceLineReader extends ItemStreamAdapter implements LineReader,
|
||||
*
|
||||
* @see #mark()
|
||||
*
|
||||
* @throws BatchEnvironmentException if the reset is unsuccessful, e.g. if
|
||||
* @throws ResetFailedException if the reset is unsuccessful, e.g. if
|
||||
* the read-ahead limit was breached.
|
||||
*/
|
||||
public synchronized void reset() {
|
||||
public synchronized void reset() throws ResetFailedException {
|
||||
getState().reset();
|
||||
}
|
||||
|
||||
@@ -318,13 +320,13 @@ public class ResourceLineReader extends ItemStreamAdapter implements LineReader,
|
||||
/**
|
||||
* Mark the underlying reader and set the line counters.
|
||||
*/
|
||||
public void mark() {
|
||||
public void mark() throws MarkFailedException {
|
||||
try {
|
||||
reader.mark(READ_AHEAD_LIMIT);
|
||||
markedLineCount = currentLineCount;
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new BatchEnvironmentException("Could not mark reader", e);
|
||||
throw new MarkFailedException("Could not mark reader", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,7 +334,7 @@ public class ResourceLineReader extends ItemStreamAdapter implements LineReader,
|
||||
* Reset the reader and line counters to the last marked position if
|
||||
* possible.
|
||||
*/
|
||||
public void reset() {
|
||||
public void reset() throws ResetFailedException {
|
||||
|
||||
if (markedLineCount < 0) {
|
||||
return;
|
||||
@@ -342,7 +344,7 @@ public class ResourceLineReader extends ItemStreamAdapter implements LineReader,
|
||||
currentLineCount = markedLineCount;
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new BatchEnvironmentException("Could not reset reader", e);
|
||||
throw new ResetFailedException("Could not reset reader", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import org.springframework.batch.io.xml.stax.NoStartEndDocumentStreamWriter;
|
||||
import org.springframework.batch.item.ExecutionAttributes;
|
||||
import org.springframework.batch.item.ItemStream;
|
||||
import org.springframework.batch.item.ItemWriter;
|
||||
import org.springframework.batch.item.StreamException;
|
||||
import org.springframework.batch.item.exception.StreamException;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.dao.DataAccessResourceFailureException;
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
|
||||
package org.springframework.batch.item;
|
||||
|
||||
import org.springframework.batch.item.exception.MarkFailedException;
|
||||
import org.springframework.batch.item.exception.ResetFailedException;
|
||||
import org.springframework.batch.item.exception.StreamException;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Marker interface defining a contract for periodically storing state and
|
||||
@@ -81,8 +85,11 @@ public interface ItemStream extends ExecutionAttributesProvider {
|
||||
* state from the current thread is saved.
|
||||
*
|
||||
* @throws UnsupportedOperationException if the operation is not supported
|
||||
* @throws MarkFailedException if there is a problem with the mark. If a
|
||||
* mark fails inside a transaction, it would be worrying, but not normally
|
||||
* fatal.
|
||||
*/
|
||||
void mark();
|
||||
void mark() throws MarkFailedException;
|
||||
|
||||
/**
|
||||
* Reset the stream to the last mark. After a reset the stream state will be
|
||||
@@ -93,6 +100,10 @@ public interface ItemStream extends ExecutionAttributesProvider {
|
||||
* state from the current thread is reset.
|
||||
*
|
||||
* @throws UnsupportedOperationException if the operation is not supported
|
||||
* @throws ResetFailedException if there is a problem with the reset. If a
|
||||
* reset fails inside a transaction, it would normally be fatal, and would
|
||||
* leave the stream in an inconsistent state. So while this is an unchecked
|
||||
* exception, it may be important for a client to catch it explicitly.
|
||||
*/
|
||||
void reset();
|
||||
void reset() throws ResetFailedException;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.batch.item;
|
||||
package org.springframework.batch.item.exception;
|
||||
|
||||
import org.springframework.batch.io.exception.BatchCriticalException;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.batch.item.exception;
|
||||
|
||||
|
||||
/**
|
||||
* Used to signal an unexpected end of an input or message stream. This is an
|
||||
* abnormal condition, not just the end of the data - e.g. if a resource becomes
|
||||
@@ -23,7 +24,7 @@ package org.springframework.batch.item.exception;
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class UnexpectedInputException extends RuntimeException {
|
||||
public class UnexpectedInputException extends StreamException {
|
||||
|
||||
/**
|
||||
* Generated serial UID.
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
package org.springframework.batch.item.reader;
|
||||
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.StreamException;
|
||||
import org.springframework.batch.item.exception.StreamException;
|
||||
|
||||
/**
|
||||
* Base class for {@link ItemReader} implementations.
|
||||
|
||||
@@ -20,7 +20,7 @@ import org.springframework.batch.io.Skippable;
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.ItemStream;
|
||||
import org.springframework.batch.item.ExecutionAttributes;
|
||||
import org.springframework.batch.item.StreamException;
|
||||
import org.springframework.batch.item.exception.StreamException;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
package org.springframework.batch.item.reader;
|
||||
|
||||
import org.springframework.batch.item.ItemReader;
|
||||
import org.springframework.batch.item.StreamException;
|
||||
import org.springframework.batch.item.exception.StreamException;
|
||||
import org.springframework.batch.support.AbstractMethodInvokingDelegator;
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,7 +17,7 @@ package org.springframework.batch.item.stream;
|
||||
|
||||
import org.springframework.batch.item.ItemStream;
|
||||
import org.springframework.batch.item.ExecutionAttributes;
|
||||
import org.springframework.batch.item.StreamException;
|
||||
import org.springframework.batch.item.exception.StreamException;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
|
||||
@@ -25,7 +25,7 @@ import java.util.Map.Entry;
|
||||
|
||||
import org.springframework.batch.item.ExecutionAttributes;
|
||||
import org.springframework.batch.item.ItemStream;
|
||||
import org.springframework.batch.item.StreamException;
|
||||
import org.springframework.batch.item.exception.StreamException;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
import org.springframework.transaction.support.DefaultTransactionDefinition;
|
||||
|
||||
@@ -17,7 +17,7 @@ package org.springframework.batch.item.stream;
|
||||
|
||||
import org.springframework.batch.item.ExecutionAttributes;
|
||||
import org.springframework.batch.item.ItemStream;
|
||||
import org.springframework.batch.item.StreamException;
|
||||
import org.springframework.batch.item.exception.StreamException;
|
||||
import org.springframework.transaction.TransactionStatus;
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.springframework.batch.io.file.mapping.FieldSet;
|
||||
import org.springframework.batch.io.file.mapping.FieldSetMapper;
|
||||
import org.springframework.batch.io.file.transform.LineTokenizer;
|
||||
import org.springframework.batch.item.ExecutionAttributes;
|
||||
import org.springframework.batch.item.StreamException;
|
||||
import org.springframework.batch.item.exception.StreamException;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.util.List;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.springframework.batch.item.ExecutionAttributes;
|
||||
import org.springframework.batch.item.StreamException;
|
||||
import org.springframework.batch.item.exception.StreamException;
|
||||
import org.springframework.batch.support.PropertiesConverter;
|
||||
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
|
||||
import org.springframework.transaction.TransactionException;
|
||||
|
||||
Reference in New Issue
Block a user