Reputation: 1395
I am trying to build a retry into my error-prone itemreader. I have set up a small POC to test if everything is working, but I am not able to get retries running. Here is what I did:
@Configuration
@EnableBatchProcessing
public static class TestConfiguration {
// other beans
@Bean
@Qualifier("importFullJob")
public Job importFullJob(ItemReader itemReader) {
TaskletStep mockStep = stepBuilderFactory.get("mockStep")
.chunk(1)
.faultTolerant()
.retry(RestClientException.class)
.retryLimit(10)
.reader(itemReader)
.processor(item -> "processed")
.writer(items -> {
})
.build();
return jobBuilderFactory.get("importFullJob").start(mockStep).build();
}
@Bean
@JobScope
public ItemReader itemReader() {
return new ItemReader() {
@Override
public Object read() throws Exception {
System.out.println("try read");
throw new RestClientException("booom");
}
};
}
}
I was expecting to get 10 calls to ItemReader.read() but instead I get only one call and this exception:
org.springframework.batch.core.step.skip.NonSkippableReadException: Non-skippable exception during read
at org.springframework.batch.core.step.item.FaultTolerantChunkProvider.read(FaultTolerantChunkProvider.java:105) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.step.item.SimpleChunkProvider$1.doInIteration(SimpleChunkProvider.java:116) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:374) ~[spring-batch-infrastructure-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) ~[spring-batch-infrastructure-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144) ~[spring-batch-infrastructure-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.step.item.SimpleChunkProvider.provide(SimpleChunkProvider.java:110) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:69) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:406) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:330) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133) ~[spring-tx-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:271) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:81) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:374) ~[spring-batch-infrastructure-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:215) ~[spring-batch-infrastructure-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:144) ~[spring-batch-infrastructure-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:257) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:200) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.job.AbstractJob.handleStep(AbstractJob.java:392) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.job.SimpleJob.doExecute(SimpleJob.java:135) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:306) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:135) [spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at java.lang.Thread.run(Thread.java:745) [?:1.8.0_72]
Caused by: org.springframework.web.client.RestClientException: buuuum
at org.woezelmann.batch.starter.FullImportStarterIT$TestConfiguration$1.read(FullImportStarterIT.java:256) ~[test-classes/:?]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_72]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:1.8.0_72]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_72]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_72]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302) ~[spring-aop-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) ~[spring-aop-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133) ~[spring-aop-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121) ~[spring-aop-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208) ~[spring-aop-4.2.7.RELEASE.jar:4.2.7.RELEASE]
at com.sun.proxy.$Proxy68.read(Unknown Source) ~[?:?]
at org.springframework.batch.core.step.item.SimpleChunkProvider.doRead(SimpleChunkProvider.java:91) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
at org.springframework.batch.core.step.item.FaultTolerantChunkProvider.read(FaultTolerantChunkProvider.java:87) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
... 22 more
I have also tried
.retryPolicy(new AlwaysRetryPolicy())
but I does not work neither.
Am I doing something wrong or is this a bug?
EDIT:
I have tried
.faultTolerant()
.skipPolicy(new AlwaysSkipItemSkipPolicy())
which works as expected.
Upvotes: 0
Views: 2919
Reputation: 438
"Am I doing something wrong or is this a bug?" seems like a bug. Oddly enough throwing the exception on write seems to be fine.
@Bean
public Job retrySample() {
return jobBuilderFactory.get("retrySample").start(mockStep()).build();
}
@Bean
public Step mockStep() {
return stepBuilderFactory.get("mockStep")
.<String, String>chunk(1)
.reader(itemReader())
.writer(itemWriter())
.faultTolerant()
.retry(Exception.class)
.retryLimit(10)
.build();
}
@Bean
@JobScope
public ItemReader<String> itemReader() {
return new ItemReader<String>() {
@Override
public String read() throws Exception {
return "dkafj";
}
};
}
@Bean
@JobScope
public ItemWriter<String> itemWriter() {
return new ItemWriter<String>() {
@Override
public void write(List<? extends String> items) throws Exception {
items.forEach(item -> {System.out.println("got" + item);});
throw new Exception("booom");
}
};
}
Logs:
2016-12-08 16:04:09.618 INFO 9040 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : Job: [SimpleJob: [name=retrySample]] launched with the following parameters: [{runId=Job}]
2016-12-08 16:04:09.651 INFO 9040 --- [ main] o.s.batch.core.job.SimpleStepHandler : Executing step: [mockStep]
gotdkafj
gotdkafj
gotdkafj
gotdkafj
gotdkafj
gotdkafj
gotdkafj
gotdkafj
gotdkafj
gotdkafj
2016-12-08 16:04:09.707 ERROR 9040 --- [ main] o.s.batch.core.step.AbstractStep : Encountered an error executing step mockStep in job retrySample
org.springframework.retry.ExhaustedRetryException: Retry exhausted after last attempt in recovery path, but exception is not skippable.; nested exception is java.lang.Exception: booom
at org.springframework.batch.core.step.item.FaultTolerantChunkProcessor$5.recover(FaultTolerantChunkProcessor.java:403) ~[spring-batch-core-3.0.7.RELEASE.jar:3.0.7.RELEASE]
Here is the link to the Spring Batch JIRA
Upvotes: 1