BATCH-1189: By default, all exceptions should be fatal

This commit is contained in:
dhgarrette
2009-04-01 21:22:43 +00:00
parent 3f7f2d8b4e
commit 3dc92be2ed
8 changed files with 132 additions and 43 deletions

View File

@@ -77,12 +77,6 @@ public class FaultTolerantStepFactoryBean<T, S> extends SimpleStepFactoryBean<T,
private Collection<Class<? extends Throwable>> retryableExceptionClasses = new HashSet<Class<? extends Throwable>>();
{
fatalExceptionClasses.add(Error.class);
skippableExceptionClasses.add(Exception.class);
retryableExceptionClasses.add(Exception.class);
}
private int cacheCapacity = 0;
private int retryLimit = 0;

View File

@@ -20,6 +20,7 @@ import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
@@ -63,7 +64,7 @@ public class FaultTolerantStepFactoryBeanRetryTests {
protected final Log logger = LogFactory.getLog(getClass());
private FaultTolerantStepFactoryBean<String, String> factory = new FaultTolerantStepFactoryBean<String, String>();
private FaultTolerantStepFactoryBean<String, String> factory;
private List<Object> recovered = new ArrayList<Object>();
@@ -88,11 +89,6 @@ public class FaultTolerantStepFactoryBeanRetryTests {
}
};
/*
* (non-Javadoc)
*
* @see junit.framework.TestCase#setUp()
*/
@Before
public void setUp() throws Exception {
@@ -100,6 +96,7 @@ public class FaultTolerantStepFactoryBeanRetryTests {
MapJobExecutionDao.clear();
MapStepExecutionDao.clear();
factory = new FaultTolerantStepFactoryBean<String, String>();
factory.setBeanName("step");
factory.setItemReader(new ListItemReader<String>(new ArrayList<String>()));
@@ -113,6 +110,11 @@ public class FaultTolerantStepFactoryBeanRetryTests {
});
factory.setCommitInterval(1); // trivial by default
@SuppressWarnings("unchecked")
Collection<Class<? extends Throwable>> skippableExceptions = Arrays
.<Class<? extends Throwable>> asList(Exception.class);
factory.setSkippableExceptionClasses(skippableExceptions);
JobParameters jobParameters = new JobParametersBuilder().addString("statefulTest", "make_this_unique")
.toJobParameters();
jobExecution = repository.createJobExecution("job", jobParameters);

View File

@@ -42,7 +42,7 @@ public class FaultTolerantStepFactoryBeanRollbackTests {
protected final Log logger = LogFactory.getLog(getClass());
private FaultTolerantStepFactoryBean<String, String> factory = new FaultTolerantStepFactoryBean<String, String>();
private FaultTolerantStepFactoryBean<String, String> factory;
private static Collection<String> NO_FAILURES = Collections.emptyList();
@@ -60,12 +60,19 @@ public class FaultTolerantStepFactoryBeanRollbackTests {
@Before
public void setUp() throws Exception {
factory = new FaultTolerantStepFactoryBean<String, String>();
factory.setBeanName("stepName");
factory.setTransactionManager(new ResourcelessTransactionManager());
factory.setCommitInterval(2);
factory.setItemReader(reader);
factory.setItemWriter(writer);
factory.setSkipLimit(2);
@SuppressWarnings("unchecked")
Collection<Class<? extends Throwable>> skippableExceptions = Arrays
.<Class<? extends Throwable>> asList(Exception.class);
factory.setSkippableExceptionClasses(skippableExceptions);
MapJobRepositoryFactoryBean.clear();
MapJobRepositoryFactoryBean repositoryFactory = new MapJobRepositoryFactoryBean();

View File

@@ -50,11 +50,7 @@ public class FaultTolerantStepFactoryBeanTests {
protected final Log logger = LogFactory.getLog(getClass());
private FaultTolerantStepFactoryBean<String, String> factory = new FaultTolerantStepFactoryBean<String, String>();
@SuppressWarnings("unchecked")
private Collection<Class<? extends Throwable>> skippableExceptions = Arrays.<Class<? extends Throwable>> asList(
SkippableException.class, SkippableRuntimeException.class);
private FaultTolerantStepFactoryBean<String, String> factory;
private SkipReaderStub reader = new SkipReaderStub();
@@ -78,14 +74,20 @@ public class FaultTolerantStepFactoryBeanTests {
@Before
public void setUp() throws Exception {
factory = new FaultTolerantStepFactoryBean<String, String>();
factory.setBeanName("stepName");
factory.setTransactionManager(new ResourcelessTransactionManager());
factory.setCommitInterval(2);
factory.setItemReader(reader);
factory.setItemWriter(writer);
factory.setSkippableExceptionClasses(skippableExceptions);
factory.setSkipLimit(2);
@SuppressWarnings("unchecked")
Collection<Class<? extends Throwable>> skippableExceptions = Arrays.<Class<? extends Throwable>> asList(
SkippableException.class, SkippableRuntimeException.class);
factory.setSkippableExceptionClasses(skippableExceptions);
MapJobRepositoryFactoryBean.clear();
MapJobRepositoryFactoryBean repositoryFactory = new MapJobRepositoryFactoryBean();
repositoryFactory.setTransactionManager(new ResourcelessTransactionManager());

View File

@@ -25,19 +25,20 @@ import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.springframework.batch.core.step.skip.LimitCheckingItemSkipPolicy;
import org.springframework.batch.core.step.skip.SkipLimitExceededException;
import org.springframework.batch.item.ItemWriterException;
import org.springframework.batch.item.WriteFailedException;
import org.springframework.batch.item.WriterNotOpenException;
import org.springframework.batch.item.file.FlatFileParseException;
/**
* @author Lucas Ward
* @author Dave Syer
*
*
*/
public class LimitCheckingItemSkipPolicyTests {
private LimitCheckingItemSkipPolicy failurePolicy;
@Before
public void setUp() throws Exception {
List<Class<? extends Throwable>> skippableExceptions = new ArrayList<Class<? extends Throwable>>();
@@ -45,26 +46,100 @@ public class LimitCheckingItemSkipPolicyTests {
List<Class<? extends Throwable>> fatalExceptions = new ArrayList<Class<? extends Throwable>>();
failurePolicy = new LimitCheckingItemSkipPolicy(1, skippableExceptions, fatalExceptions);
}
@Test
public void testLimitExceed(){
try{
public void testLimitExceed() {
try {
failurePolicy.shouldSkip(new FlatFileParseException("", ""), 2);
fail();
} catch (SkipLimitExceededException ex) {
// expected
}
catch(SkipLimitExceededException ex){
//expected
}
}
@Test
public void testNonSkippableException(){
assertFalse(failurePolicy.shouldSkip(new FileNotFoundException(), 2));
}
@Test
public void testSkip(){
assertTrue(failurePolicy.shouldSkip(new FlatFileParseException("",""), 0));
}
@Test
public void testNonSkippableException() {
assertFalse(failurePolicy.shouldSkip(new FileNotFoundException(), 2));
}
@Test
public void testSkip() {
assertTrue(failurePolicy.shouldSkip(new FlatFileParseException("", ""), 0));
}
private LimitCheckingItemSkipPolicy getSkippableSubsetFailurePolicy() {
List<Class<? extends Throwable>> skippableExceptions = new ArrayList<Class<? extends Throwable>>();
skippableExceptions.add(WriteFailedException.class);
List<Class<? extends Throwable>> fatalExceptions = new ArrayList<Class<? extends Throwable>>();
fatalExceptions.add(ItemWriterException.class);
return new LimitCheckingItemSkipPolicy(1, skippableExceptions, fatalExceptions);
}
/**
* condition: skippable < fatal; exception is unclassified
*
* expected: false; default classification
*/
@Test
public void testSkippableSubset_unclassified() {
assertFalse(getSkippableSubsetFailurePolicy().shouldSkip(new RuntimeException(), 0));
}
/**
* condition: skippable < fatal; exception is skippable
*
* expected: false; fatal overrides skippable
*/
@Test
public void testSkippableSubset_skippable() {
assertFalse(getSkippableSubsetFailurePolicy().shouldSkip(new WriteFailedException(""), 0));
}
/**
* condition: skippable < fatal; exception is fatal
*
* expected: false
*/
@Test
public void testSkippableSubset_fatal() {
assertFalse(getSkippableSubsetFailurePolicy().shouldSkip(new WriterNotOpenException(""), 0));
}
private LimitCheckingItemSkipPolicy getFatalSubsetFailurePolicy() {
List<Class<? extends Throwable>> skippableExceptions = new ArrayList<Class<? extends Throwable>>();
skippableExceptions.add(ItemWriterException.class);
List<Class<? extends Throwable>> fatalExceptions = new ArrayList<Class<? extends Throwable>>();
fatalExceptions.add(WriteFailedException.class);
return new LimitCheckingItemSkipPolicy(1, skippableExceptions, fatalExceptions);
}
/**
* condition: fatal < skippable; exception is unclassified
*
* expected: false; default classification
*/
@Test
public void testFatalSubset_unclassified() {
assertFalse(getFatalSubsetFailurePolicy().shouldSkip(new RuntimeException(), 0));
}
/**
* condition: fatal < skippable; exception is skippable
*
* expected: true
*/
@Test
public void testFatalSubset_skippable() {
assertTrue(getFatalSubsetFailurePolicy().shouldSkip(new WriterNotOpenException(""), 0));
}
/**
* condition: fatal < skippable; exception is fatal
*
* expected: false
*/
@Test
public void testFatalSubset_fatal() {
assertFalse(getFatalSubsetFailurePolicy().shouldSkip(new WriteFailedException(""), 0));
}
}

View File

@@ -27,6 +27,7 @@ import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemStreamException;
import org.springframework.batch.item.ItemStreamSupport;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.WriteFailedException;
import org.springframework.batch.sample.domain.trade.Trade;
import org.springframework.batch.sample.domain.trade.TradeDao;
import org.springframework.util.Assert;
@@ -58,7 +59,7 @@ public class TradeWriter extends ItemStreamSupport implements ItemWriter<Trade>
Assert.notNull(trade.getPrice()); // There must be a price to total
if (this.failingCustomers.contains(trade.getCustomer())) {
throw new RuntimeException("Something unexpected happened!");
throw new WriteFailedException("Something unexpected happened!");
}
}

View File

@@ -17,7 +17,11 @@
processor="creditIncreaseProcessor"
writer="hibernateCreditWriter"
skip-limit="5"
commit-interval="3"/>
commit-interval="3">
<skippable-exception-classes>
java.lang.RuntimeException
</skippable-exception-classes>
</chunk>
</tasklet>
</step>
</job>

View File

@@ -17,6 +17,10 @@
<tasklet>
<chunk reader="fileItemReader" processor="tradeProcessor" writer="tradeWriter"
commit-interval="3" skip-limit="10">
<skippable-exception-classes>
org.springframework.batch.item.file.FlatFileParseException
org.springframework.batch.item.WriteFailedException
</skippable-exception-classes>
</chunk>
</tasklet>
@@ -46,7 +50,7 @@
<tasklet>
<chunk writer="itemTrackingWriter">
<skippable-exception-classes merge="true">
java.lang.RuntimeException
org.springframework.batch.item.validator.ValidationException
</skippable-exception-classes>
</chunk>
</tasklet>
@@ -59,7 +63,7 @@
<chunk reader="tradeSqlItemReader" processor="tradeProcessor" writer="dummyWriter"
commit-interval="2" skip-limit="10">
<skippable-exception-classes>
org.springframework.batch.item.validator.ValidationException
java.lang.RuntimeException
</skippable-exception-classes>
</chunk>
</tasklet>