0
votes

I defined simple job. tasklet and then step.

I am trying to pass filePath between those two.

When I reach to the stem the reader is invoked and over there the filePath remain null.

What am I missing?

Job configuration:

@Bean
    public Job processFileJob() throws Exception {
          return this.jobs.get("processFileJob").start(downloadFileStep()).next(processor()).build();//.next(pushToKafkaStep()).build();

    }



public Step downloadFileStep() {
        return this.steps.get("downloadFileTaskletStep").tasklet(downloadFileTasklet()).build();
    }


    @Bean
    protected Tasklet downloadFileTasklet() {
        return new DownloadFileTasklet();
    }




@Bean
public Step processor() {
         return stepBuilderFactory.get("processor")
      .<PushItemDTO, PushItemDTO>chunk(1) 
                        .reader(reader(OVERRIDDEN_BY_EXPRESSION))
                        ...
                        .build();
            }



                           //here filePath always null!!
@Bean
    @Scope(value = "step", proxyMode = ScopedProxyMode.INTERFACES)
    public ItemStreamReader<PushItemDTO> reader(@Value("#{jobParameters[filePath]}") String filePath) {
        FlatFileItemReader<PushItemDTO> itemReader = new FlatFileItemReader<PushItemDTO>();
        itemReader.setLineMapper(lineMapper());
        itemReader.setLinesToSkip(1);
        itemReader.setResource(new FileSystemResource(filePath));
        return itemReader;
    }

DownloadFileTasklet:

public class DownloadFileTasklet implements Tasklet, StepExecutionListener {

   String filePath;

    @Override
    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {

        filePath="someurl";        
        return RepeatStatus.FINISHED;
    }



    @Override
    public void beforeStep(StepExecution stepExecution) {

    }

    @Override
    public ExitStatus afterStep(StepExecution stepExecution) {
        JobParameters jobParameters = stepExecution.getJobExecution().getJobParameters();
       // jobParameters.ad
        stepExecution.getExecutionContext().putString("filePath", filePath);
        //Return null to leave the old value unchanged.
        return null;
    }

I managed to pass params directly from the jobLauncher while calling this job but when I try to define new param inside the tasklet and wishing to have it in the next step then I get it as null

Thanks you.

As recommened I should use ExecutionContextPromotionListener.

So I added to my java config this:

@Bean
    public ExecutionContextPromotionListener executionContextPromotionListener()
    {
        ExecutionContextPromotionListener executionContextPromotionListener=new ExecutionContextPromotionListener();
        executionContextPromotionListener.setKeys(new String[]{"filePath"});
        return new ExecutionContextPromotionListener();
    }

However I get exception:

Caused by: java.lang.IllegalArgumentException: The 'keys' property must be provided

I fixed it by changing into return executionContextPromotionListener;

However filePath is still null.

I also tried to modify my Step declaration this way:

*added the executionContextPromotionListener

public Step downloadFileStep() {
    return this.steps.get("downloadFileTaskletStep").tasklet(downloadFileTasklet()).listener(executionContextPromotionListener()).build();
}

still null in filePath param

1
return new ExecutionContextPromotionListener(); You are returning a new ExecutionContextPromotionListener instead of the one you just configured. - Jimmy Praet
I fixed it. not getting that error. but filePath Is till null. - rayman

1 Answers

1
votes

Adding a value to the step's ExecutionContext makes it available only to that step. To make it so that another step can access it, you need to promote that key to the job's ExecutionContext. To do that, take a look at the ExecutionContextPromotionListener. It will promote whatever keys you've configured it to from the current step's ExecutionContext to the job's ExecutionContext so that they can be accessed from other steps.

You can read more about the ExecutionContextPromotionListener in the documentation here: http://docs.spring.io/spring-batch/apidocs/org/springframework/batch/core/listener/ExecutionContextPromotionListener.html