0

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

rayman
  • 20,786
  • 45
  • 148
  • 246
  • return new ExecutionContextPromotionListener(); You are returning a new `ExecutionContextPromotionListener` instead of the one you just configured. – Jimmy Praet Jan 19 '15 at 17:42
  • I fixed it. not getting that error. but filePath Is till null. – rayman Jan 20 '15 at 08:20

1 Answers1

1

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

Michael Minella
  • 20,843
  • 4
  • 55
  • 67
  • I edited my question as you instructed please see the following error. thank you. – rayman Jan 19 '15 at 17:32
  • I think you need to return `executionContextPromotionListener`...not `new ExecutionContextPromotionListener()` ;) – Michael Minella Jan 19 '15 at 17:35
  • Sorry my bad. I fixed it. I dont get that error but I still get null in the filePath param. Maybe I am not defining the stepscope in the right place? ? – rayman Jan 20 '15 at 08:20
  • Can you check in the job repository if the value is getting into the execution context? – Michael Minella Jan 20 '15 at 15:53
  • I found it. the problem was that since i am passing it via execution Contexnt I needed in the reader configuration to change the spEL expression to: {jobExecutionContext[filePath]}". – rayman Jan 20 '15 at 16:19
  • Hi Michael, tried to reach u in some places.. but was hard.. seems like Iam having probs using this implementation while executing jobs in parallel. would be great if you could look at my new question at: http://stackoverflow.com/questions/29776901/how-to-safely-pass-params-from-tasklet-to-step-when-running-parallel-jobs – rayman Apr 21 '15 at 18:13