OPEN - issue BATCH-753: Listener exception handling

Add new exception types.
This commit is contained in:
dsyer
2008-08-05 21:52:36 +00:00
parent 4b07e29b09
commit ac8cf4539e
5 changed files with 246 additions and 21 deletions

View File

@@ -89,7 +89,12 @@ public class MulticasterBatchListener implements StepExecutionListener, ChunkLis
* @see org.springframework.batch.core.listener.CompositeStepExecutionListener#afterStep(StepExecution)
*/
public ExitStatus afterStep(StepExecution stepExecution) {
return stepListener.afterStep(stepExecution);
try {
return stepListener.afterStep(stepExecution);
}
catch (RuntimeException e) {
throw new StepListenerFailedException("Error in afterStep.", e);
}
}
/**
@@ -97,15 +102,26 @@ public class MulticasterBatchListener implements StepExecutionListener, ChunkLis
* @see org.springframework.batch.core.listener.CompositeStepExecutionListener#beforeStep(org.springframework.batch.core.StepExecution)
*/
public void beforeStep(StepExecution stepExecution) {
stepListener.beforeStep(stepExecution);
try {
stepListener.beforeStep(stepExecution);
}
catch (RuntimeException e) {
throw new StepListenerFailedException("Error in beforeStep.", e);
}
}
/**
* @param e
* @see org.springframework.batch.core.listener.CompositeStepExecutionListener#onErrorInStep(StepExecution, Throwable)
* @param t
* @see org.springframework.batch.core.listener.CompositeStepExecutionListener#onErrorInStep(StepExecution,
* Throwable)
*/
public ExitStatus onErrorInStep(StepExecution stepExecution, Throwable e) {
return stepListener.onErrorInStep(stepExecution, e);
public ExitStatus onErrorInStep(StepExecution stepExecution, Throwable t) {
try {
return stepListener.onErrorInStep(stepExecution, t);
}
catch (RuntimeException e) {
throw new StepListenerFailedException("Error in onErrorInStep.", t, e);
}
}
/**
@@ -113,7 +129,12 @@ public class MulticasterBatchListener implements StepExecutionListener, ChunkLis
* @see org.springframework.batch.core.listener.CompositeChunkListener#afterChunk()
*/
public void afterChunk() {
chunkListener.afterChunk();
try {
chunkListener.afterChunk();
}
catch (RuntimeException e) {
throw new StepListenerFailedException("Error in afterChunk.", e);
}
}
/**
@@ -121,7 +142,12 @@ public class MulticasterBatchListener implements StepExecutionListener, ChunkLis
* @see org.springframework.batch.core.listener.CompositeChunkListener#beforeChunk()
*/
public void beforeChunk() {
chunkListener.beforeChunk();
try {
chunkListener.beforeChunk();
}
catch (RuntimeException e) {
throw new StepListenerFailedException("Error in beforeChunk.", e);
}
}
/**
@@ -129,7 +155,12 @@ public class MulticasterBatchListener implements StepExecutionListener, ChunkLis
* @see org.springframework.batch.core.listener.CompositeItemReadListener#afterRead(java.lang.Object)
*/
public void afterRead(Object item) {
itemReadListener.afterRead(item);
try {
itemReadListener.afterRead(item);
}
catch (RuntimeException e) {
throw new StepListenerFailedException("Error in afterRead.", e);
}
}
/**
@@ -137,7 +168,12 @@ public class MulticasterBatchListener implements StepExecutionListener, ChunkLis
* @see org.springframework.batch.core.listener.CompositeItemReadListener#beforeRead()
*/
public void beforeRead() {
itemReadListener.beforeRead();
try {
itemReadListener.beforeRead();
}
catch (RuntimeException e) {
throw new StepListenerFailedException("Error in beforeRead.", e);
}
}
/**
@@ -145,7 +181,12 @@ public class MulticasterBatchListener implements StepExecutionListener, ChunkLis
* @see org.springframework.batch.core.listener.CompositeItemReadListener#onReadError(java.lang.Exception)
*/
public void onReadError(Exception ex) {
itemReadListener.onReadError(ex);
try {
itemReadListener.onReadError(ex);
}
catch (RuntimeException e) {
throw new StepListenerFailedException("Error in onReadError.", ex, e);
}
}
/**
@@ -153,7 +194,12 @@ public class MulticasterBatchListener implements StepExecutionListener, ChunkLis
* @see org.springframework.batch.core.listener.CompositeItemWriteListener#afterWrite(Object)
*/
public void afterWrite(Object item) {
itemWriteListener.afterWrite(item);
try {
itemWriteListener.afterWrite(item);
}
catch (RuntimeException e) {
throw new StepListenerFailedException("Error in afterWrite.", e);
}
}
/**
@@ -161,7 +207,12 @@ public class MulticasterBatchListener implements StepExecutionListener, ChunkLis
* @see org.springframework.batch.core.listener.CompositeItemWriteListener#beforeWrite(java.lang.Object)
*/
public void beforeWrite(Object item) {
itemWriteListener.beforeWrite(item);
try {
itemWriteListener.beforeWrite(item);
}
catch (RuntimeException e) {
throw new StepListenerFailedException("Error in beforeWrite.", e);
}
}
/**
@@ -171,7 +222,12 @@ public class MulticasterBatchListener implements StepExecutionListener, ChunkLis
* java.lang.Object)
*/
public void onWriteError(Exception ex, Object item) {
itemWriteListener.onWriteError(ex, item);
try {
itemWriteListener.onWriteError(ex, item);
}
catch (RuntimeException e) {
throw new StepListenerFailedException("Error in onWriteError.", ex, e);
}
}
/**
@@ -179,16 +235,27 @@ public class MulticasterBatchListener implements StepExecutionListener, ChunkLis
* @see org.springframework.batch.core.listener.CompositeSkipListener#onSkipInRead(java.lang.Throwable)
*/
public void onSkipInRead(Throwable t) {
skipListener.onSkipInRead(t);
try {
skipListener.onSkipInRead(t);
}
catch (RuntimeException e) {
throw new StepListenerFailedException("Error in onSkipInRead.", t, e);
}
}
/**
* @param item
* @param t
* @see org.springframework.batch.core.listener.CompositeSkipListener#onSkipInWrite(java.lang.Object, java.lang.Throwable)
* @see org.springframework.batch.core.listener.CompositeSkipListener#onSkipInWrite(java.lang.Object,
* java.lang.Throwable)
*/
public void onSkipInWrite(Object item, Throwable t) {
skipListener.onSkipInWrite(item, t);
try {
skipListener.onSkipInWrite(item, t);
}
catch (RuntimeException e) {
throw new StepListenerFailedException("Error in onSkipInWrite.", t, e);
}
}
}

View File

@@ -0,0 +1,44 @@
/*
* Copyright 2006-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.listener;
/**
* Exception to indicate a problem in a step listener.
*
* @author Dave Syer
*
*/
public class StepListenerFailedException extends RuntimeException {
/**
* @param message describes the error to the user
* @param t the exception that was thrown by a listener
*/
public StepListenerFailedException(String message, Throwable t) {
super(message, t);
}
/**
* @param message describes the error to the user
* @param ex the exception that was thrown by a listener
* @param e the exception that caused the skip
*/
public StepListenerFailedException(String message, Throwable ex, RuntimeException e) {
super(message + "\n" + e.getClass().getName() + ": " + e.getMessage(), ex);
}
}

View File

@@ -191,13 +191,14 @@ public class SkipLimitStepFactoryBean<T> extends SimpleStepFactoryBean<T> {
if (retryLimit > 0 || skipLimit > 0 || retryPolicy != null) {
addFatalExceptionIfMissing(SkipLimitExceededException.class);
addFatalExceptionIfMissing(SkipListenerFailedException.class);
addFatalExceptionIfMissing(RetryException.class);
if (retryPolicy == null) {
SimpleRetryPolicy simpleRetryPolicy = new SimpleRetryPolicy(retryLimit);
if (retryableExceptionClasses.length > 0) { // otherwise we
// retry
// retry
// all exceptions
simpleRetryPolicy.setRetryableExceptionClasses(retryableExceptionClasses);
}
@@ -316,8 +317,9 @@ public class SkipLimitStepFactoryBean<T> extends SimpleStepFactoryBean<T> {
* @param retryTemplate
* @param itemKeyGenerator
*/
public StatefulRetryItemHandler(ItemReader<? extends T> itemReader, ItemWriter<? super T> itemWriter, RetryOperations retryTemplate,
ItemKeyGenerator itemKeyGenerator, ItemSkipPolicy readSkipPolicy, ItemSkipPolicy writeSkipPolicy) {
public StatefulRetryItemHandler(ItemReader<? extends T> itemReader, ItemWriter<? super T> itemWriter,
RetryOperations retryTemplate, ItemKeyGenerator itemKeyGenerator, ItemSkipPolicy readSkipPolicy,
ItemSkipPolicy writeSkipPolicy) {
super(itemReader, itemWriter);
this.retryOperations = retryTemplate;
this.itemKeyGenerator = itemKeyGenerator;
@@ -367,7 +369,12 @@ public class SkipLimitStepFactoryBean<T> extends SimpleStepFactoryBean<T> {
if (readSkipPolicy.shouldSkip(e, contribution.getStepSkipCount())) {
// increment skip count and try again
contribution.incrementTemporaryReadSkipCount();
listener.onSkipInRead(e);
try {
listener.onSkipInRead(e);
}
catch (RuntimeException ex) {
throw new SkipListenerFailedException("Fatal exception in SkipListener.", ex, e);
}
logger.debug("Skipping failed input", e);
}
else {

View File

@@ -0,0 +1,40 @@
/*
* Copyright 2006-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.batch.core.step.item;
import org.springframework.batch.core.SkipListener;
import org.springframework.batch.core.UnexpectedJobExecutionException;
/**
* Special exception to indicate a failure in a skip listener. These need
* special treatment in the framework in case a skip sends itself into an
* infinite loop.
*
* @author Dave Syer
*
*/
public class SkipListenerFailedException extends UnexpectedJobExecutionException {
/**
* @param message describes the error to the user
* @param ex the exception that was thrown by a {@link SkipListener}
* @param e the exception that caused the skip
*/
public SkipListenerFailedException(String message, RuntimeException ex, Exception e) {
super(message + "\n" + e.getClass().getName() + ": " + e.getMessage(), ex);
}
}