1

my goal is passing some value from a tasklet to another step which is consist of itemreader, processor and writer. based on the reference, i should use ExecutionContextPromotionListener. however, for some reason @BeforeStep is not being called. this is what I have.

Tasklet

@Component
public class RequestTasklet implements Tasklet {

@Autowired
private HistoryRepository historyRepository;

@Override
public RepeatStatus execute(StepContribution sc, ChunkContext cc) throws Exception {

    List<History> requests
            = historyRepository.findHistory();

    ExecutionContext stepContext = cc.getStepContext().getStepExecution().getJobExecution().getExecutionContext();
    stepContext.put("someKey", requests);
    return RepeatStatus.FINISHED;
}

}

ItemReader

@Component
public class RequestReader implements ItemReader<History> {

private List<History> requests;

@Override
public History read() throws UnexpectedInputException,
        ParseException,
        NonTransientResourceException {
    System.out.println("requests====>" + requests);
    if (CollectionUtils.isNotEmpty(requests)) {
        History request = requests.remove(0);
        return request;
    }
    return null;
}

@BeforeStep
public void beforeStep(StepExecution stepExecution) {
    System.out.println("====================here======================");
    JobExecution jobExecution = stepExecution.getJobExecution();
    ExecutionContext jobContext = jobExecution.getExecutionContext();
    this.requests = (List<History>) jobContext.get("someKey");
}

}

Configuration

    @Bean(name = "update-job")
public Job updateUserAttributes(
        JobBuilderFactory jbf,
        StepBuilderFactory sbf,
        ExecutionContextPromotionListener promoListener,
        HistoryProcessor processor,
        RequestReader reader,
        HistoryWriter writer,
        RequestTasklet loadRequestTasklet) {

    Step preStep = sbf.get("load-request-tasklet")
            .tasklet(loadRequestTasklet)
            .listener(promoListener)
            .build();

    Step step = sbf.get("update-step")
            .<History, History>chunk(2)
            .reader(reader)
            .processor(processor)
            .writer(writer)
            .taskExecutor(taskExecutor())
            .build();

    return jbf.get("update-job")
            .incrementer(new RunIdIncrementer())
            .start(preStep).next(step).
            build();
}

    @Bean
public ExecutionContextPromotionListener promoListener() {
    ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener();
    listener.setKeys(new String[]{
        "someKey",
    });
    return listener;
}

I also tried to extend StepExecutionListenerSupport in ItemReader but got the same result.

I googled around and looked at this question answered due to spring proxy which is not my case beforestep issue.

little more information as i am testing. I set listener.setStrict(Boolean.TRUE); to see if keys are set. but i am getting

  java.lang.IllegalArgumentException: The key [someKey] was not found in the Step's ExecutionContext.
at org.springframework.batch.core.listener.ExecutionContextPromotionListener.afterStep(ExecutionContextPromotionListener.java:61) ~[spring-batch-core-4.0.0.M1.jar:4.0.0.M1]

appreciate any help.

Joseph
  • 97
  • 2
  • 15
  • 1
    How is possible that RequestReader#beforeStep() has been marked with @Override? ItemReader doesn't own a beforeStep() method? – Luca Basso Ricci Jun 20 '17 at 06:39
  • oh. it just happened to be left there since i tried the option of overriding StepExecutionListenerSupport. I changed it to AT BeforeStep. @LucaBassoRicci – Joseph Jun 20 '17 at 18:30

0 Answers0