Hello,
I think I spotted an issue related to the StepBuilder. Depending on the order a developer build its step, the taskExecutor field will have different values.
Here is a minimal example to reproduce the issue:
step1 and step2 are exactly the same, except in one thing.
public class SpringBatchTest {
private PlatformTransactionManager transactionManager = mock(PlatformTransactionManager.class);
private JobRepository jobRepository = mock(JobRepository.class);
private ItemReader itemReader = mock(ItemReader.class);
private ItemProcessor itemProcessor = mock(ItemProcessor.class);
private ItemWriter itemWriter = mock(ItemWriter.class);
private SimpleAsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor();
@Test
void test_inconsistent_behavior() {
TaskletStep step1 = new StepBuilder("step-name", jobRepository)
.chunk(10, transactionManager)
.reader(itemReader)
.processor(itemProcessor)
.writer(itemWriter)
.faultTolerant()
.taskExecutor(taskExecutor)
.build();
TaskletStep step2 = new StepBuilder("step-name", jobRepository)
.chunk(10, transactionManager)
.taskExecutor(taskExecutor)// The task executor is set before faultTolerant()
.reader(itemReader)
.processor(itemProcessor)
.writer(itemWriter)
.faultTolerant()
.build();
RepeatTemplate stepOperations1 = (RepeatTemplate) ReflectionUtils
.readFieldValue(TaskletStep.class, "stepOperations", step1).get();// TaskExecutorRepeatTemplate
RepeatTemplate stepOperations2 = (RepeatTemplate) ReflectionUtils
.readFieldValue(TaskletStep.class, "stepOperations", step2).get();// RepeatTemplate
assertEquals(stepOperations1.getClass(), stepOperations2.getClass());// This fails
}
}
In this example, step2 will use the default task executor instead of the provided one.
Looking at the code, the taskExecutor value is lost after setting faultTolerant().
I did not go too deep into the solution, but I think the issue comes from this constructor (see link). The taskExecutor value could be kept from there.
|
public AbstractTaskletStepBuilder(StepBuilderHelper<?> parent) { |
Hello,
I think I spotted an issue related to the StepBuilder. Depending on the order a developer build its step, the
taskExecutorfield will have different values.Here is a minimal example to reproduce the issue:
step1andstep2are exactly the same, except in one thing.In this example,
step2will use the default task executor instead of the provided one.Looking at the code, the
taskExecutorvalue is lost after settingfaultTolerant().I did not go too deep into the solution, but I think the issue comes from this constructor (see link). The
taskExecutorvalue could be kept from there.spring-batch/spring-batch-core/src/main/java/org/springframework/batch/core/step/builder/AbstractTaskletStepBuilder.java
Line 73 in 75025a2