У меня есть весенняя пакетная программа.
Предел пропуска установлен на 5, а размер блока - 1000.
У меня есть работа, состоящая из двух этапов, как показано ниже:
<step id="myFileGenerator" next="myReportGenerator">
<tasklet transaction-manager="jobRepository-transactionManager">
<chunk reader="myItemReader" processor="myItemProcessor" writer="myItemWriter" commit-interval="1000" skip-policy="skipPolicy"/>
</tasklet>
<listeners>
<listener ref="mySkipListener"/>
</listeners>
</step>
<step id="myReportGenerator">
<tasklet ref="myReportTasklet" transaction-manager="jobRepository-transactionManager"/>
</step>
Политика пропуска приведена ниже:
<beans:bean id="skipPolicy" class="com.myPackage.util.Skip_Policy">
<beans:property name="skipLimit" value="5"/>
</beans:bean>
Класс SkipPolicy выглядит следующим образом:
public class Skip_Policy implements SkipPolicy {
private int skipLimit;
public void setSkipLimit(final int skipLimit) {
this.skipLimit = skipLimit;
}
public boolean shouldSkip(final Throwable t, final int skipCount) throws SkipLimitExceededException {
if (skipCount < this.skipLimit) {
return true;
}
return false;
}
}
Таким образом, для любой ошибки, возникающей до того, как будет достигнут предел пропуска, политика пропуска проигнорирует ошибку (вернет истину). Задание завершится ошибкой из-за любой ошибки после достижения предела пропусков.
Класс mySkipListener выглядит следующим образом:
public class mySkipListener implements SkipListener<MyItem, MyItem> {
public void onSkipInProcess(final MyItem item, final Throwable t) {
// TODO Auto-generated method stub
System.out.println("Skipped details during PROCESS is: " + t.getMessage());
}
public void onSkipInRead(final Throwable t) {
System.out.println("Skipped details during READ is: " + t.getMessage());
}
public void onSkipInWrite(final MyItem item, final Throwable t) {
// TODO Auto-generated method stub
System.out.println("Skipped details during WRITE is: " + t.getMessage());
}
}
Теперь в myItemProcessor у меня есть блок кода ниже:
if (item.getTheNumber().charAt(4) == '-') {
item.setProductNumber(item.getTheNumber().substring(0, 3));
} else {
item.setProductNumber("55");
}
Для некоторых элементов полеNumber имеет значение NULL, поэтому приведенный выше блок кода вызывает исключение StringIndexOutofBounds.
Но я наблюдаю странное поведение и не понимаю, почему это происходит.
Всего есть 6 элементов, у которых есть ошибка, то есть поле Number имеет значение NULL.
Если предел пропуска превышает количество ошибок (т. Е.> 6), вызываются системные выходы в классе прослушивателя пропуска, и сообщается о пропущенных ошибках.
Однако, если предел пропуска меньше (скажем, 5, как в моем примере), системные выходы в классе пропуска слушателя вообще не вызываются, и я напрямую получаю следующий дамп исключения на консоли:
org.springframework.batch.retry.RetryException: Non-skippable exception in recoverer while processing; nested exception is java.lang.StringIndexOutOfBoundsException
at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor$2.recover(FaultTolerantChunkProcessor.java:282)
at org.springframework.batch.retry.support.RetryTemplate.handleRetryExhausted(RetryTemplate.java:416)
at org.springframework.batch.retry.support.RetryTemplate.doExecute(RetryTemplate.java:285)
at org.springframework.batch.retry.support.RetryTemplate.execute(RetryTemplate.java:187)
В чем причина такого поведения? Что мне делать, чтобы решить эту проблему?
Спасибо за прочтение!