Spring Batch - Pass parameter from Writer to Listener for afterJob(JobExecution jobExecution)











up vote
0
down vote

favorite












I have a writer from which I have a dynamic value that needs to be passed to JobExecutionListener's afterJob(JobExecution jobExecution). Would appreciate some advice. Thank you.



<beans:bean>
<job id="GoodJob">
<step id="XXX"
allow-start-if-complete="true"
parent="XXX">
<tasklet transaction-manager="XXX">
<chunk reader="READER"
writer="WRITER"
commit-interval="100"/>
</tasklet>
</step>

<listener>
<beans:bean class="class that implements JobExecutionListener">
<beans:constructor-arg name="value"
value="DEFAULT IS FALSE DURING INITIALIZATION/MIGHT GET CHANGED IN WRITER, GET THIS VALUE FROM WRITER"/>
</beans:bean>
</listener>
</job>
</beans:beans>









share|improve this question


















  • 1




    See here to get access to the execution context from the writer to put a value. Then get the value from the execution context in the afterJob()'s jobExecution parameter.
    – Andrew S
    Nov 9 at 19:07















up vote
0
down vote

favorite












I have a writer from which I have a dynamic value that needs to be passed to JobExecutionListener's afterJob(JobExecution jobExecution). Would appreciate some advice. Thank you.



<beans:bean>
<job id="GoodJob">
<step id="XXX"
allow-start-if-complete="true"
parent="XXX">
<tasklet transaction-manager="XXX">
<chunk reader="READER"
writer="WRITER"
commit-interval="100"/>
</tasklet>
</step>

<listener>
<beans:bean class="class that implements JobExecutionListener">
<beans:constructor-arg name="value"
value="DEFAULT IS FALSE DURING INITIALIZATION/MIGHT GET CHANGED IN WRITER, GET THIS VALUE FROM WRITER"/>
</beans:bean>
</listener>
</job>
</beans:beans>









share|improve this question


















  • 1




    See here to get access to the execution context from the writer to put a value. Then get the value from the execution context in the afterJob()'s jobExecution parameter.
    – Andrew S
    Nov 9 at 19:07













up vote
0
down vote

favorite









up vote
0
down vote

favorite











I have a writer from which I have a dynamic value that needs to be passed to JobExecutionListener's afterJob(JobExecution jobExecution). Would appreciate some advice. Thank you.



<beans:bean>
<job id="GoodJob">
<step id="XXX"
allow-start-if-complete="true"
parent="XXX">
<tasklet transaction-manager="XXX">
<chunk reader="READER"
writer="WRITER"
commit-interval="100"/>
</tasklet>
</step>

<listener>
<beans:bean class="class that implements JobExecutionListener">
<beans:constructor-arg name="value"
value="DEFAULT IS FALSE DURING INITIALIZATION/MIGHT GET CHANGED IN WRITER, GET THIS VALUE FROM WRITER"/>
</beans:bean>
</listener>
</job>
</beans:beans>









share|improve this question













I have a writer from which I have a dynamic value that needs to be passed to JobExecutionListener's afterJob(JobExecution jobExecution). Would appreciate some advice. Thank you.



<beans:bean>
<job id="GoodJob">
<step id="XXX"
allow-start-if-complete="true"
parent="XXX">
<tasklet transaction-manager="XXX">
<chunk reader="READER"
writer="WRITER"
commit-interval="100"/>
</tasklet>
</step>

<listener>
<beans:bean class="class that implements JobExecutionListener">
<beans:constructor-arg name="value"
value="DEFAULT IS FALSE DURING INITIALIZATION/MIGHT GET CHANGED IN WRITER, GET THIS VALUE FROM WRITER"/>
</beans:bean>
</listener>
</job>
</beans:beans>






java spring spring-batch






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 9 at 18:55









Anton Kim

323213




323213








  • 1




    See here to get access to the execution context from the writer to put a value. Then get the value from the execution context in the afterJob()'s jobExecution parameter.
    – Andrew S
    Nov 9 at 19:07














  • 1




    See here to get access to the execution context from the writer to put a value. Then get the value from the execution context in the afterJob()'s jobExecution parameter.
    – Andrew S
    Nov 9 at 19:07








1




1




See here to get access to the execution context from the writer to put a value. Then get the value from the execution context in the afterJob()'s jobExecution parameter.
– Andrew S
Nov 9 at 19:07




See here to get access to the execution context from the writer to put a value. Then get the value from the execution context in the afterJob()'s jobExecution parameter.
– Andrew S
Nov 9 at 19:07












1 Answer
1






active

oldest

votes

















up vote
1
down vote



accepted










You can pass data between these two components through the job execution context. This is detailed in the Passing Data to Future Steps section. Here is a quick example:



import java.util.Arrays;
import java.util.List;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobExecutionListener;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.annotation.BeforeStep;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableBatchProcessing
public class MyJob {

@Autowired
private JobBuilderFactory jobs;

@Autowired
private StepBuilderFactory steps;

@Bean
public ItemReader<Integer> itemReader() {
return new ListItemReader<>(Arrays.asList(1, 2, 3, 4));
}

@Bean
public ItemWriter<Integer> itemWriter() {
return new ItemWriter<Integer>() {

private StepExecution stepExecution;

@Override
public void write(List<? extends Integer> items) throws Exception {
for (Integer item : items) {
System.out.println("item = " + item);
}
stepExecution.getJobExecution().getExecutionContext().put("data", "foo");
}

@BeforeStep
public void saveStepExecution(StepExecution stepExecution) {
this.stepExecution = stepExecution;
}

};
}

@Bean
public Step step() {
return steps.get("step")
.<Integer, Integer>chunk(2)
.reader(itemReader())
.writer(itemWriter())
.build();
}

@Bean
public Job job() {
return jobs.get("job")
.start(step())
.listener(new JobExecutionListener() {
@Override
public void beforeJob(JobExecution jobExecution) {

}

@Override
public void afterJob(JobExecution jobExecution) {
ExecutionContext executionContext = jobExecution.getExecutionContext();
String data = executionContext.getString("data");
System.out.println("data from writer = " + data);
}
})
.build();
}

public static void main(String args) throws Exception {
ApplicationContext context = new AnnotationConfigApplicationContext(MyJob.class);
JobLauncher jobLauncher = context.getBean(JobLauncher.class);
Job job = context.getBean(Job.class);
jobLauncher.run(job, new JobParameters());
}

}


In this example, the writer writes the key data with value foo in the job execution context. Then, this key is retrieved from the execution context in the job listener.



Hope this helps.






share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53231769%2fspring-batch-pass-parameter-from-writer-to-listener-for-afterjobjobexecution%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    1
    down vote



    accepted










    You can pass data between these two components through the job execution context. This is detailed in the Passing Data to Future Steps section. Here is a quick example:



    import java.util.Arrays;
    import java.util.List;

    import org.springframework.batch.core.Job;
    import org.springframework.batch.core.JobExecution;
    import org.springframework.batch.core.JobExecutionListener;
    import org.springframework.batch.core.JobParameters;
    import org.springframework.batch.core.Step;
    import org.springframework.batch.core.StepExecution;
    import org.springframework.batch.core.annotation.BeforeStep;
    import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
    import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
    import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
    import org.springframework.batch.core.launch.JobLauncher;
    import org.springframework.batch.item.ExecutionContext;
    import org.springframework.batch.item.ItemReader;
    import org.springframework.batch.item.ItemWriter;
    import org.springframework.batch.item.support.ListItemReader;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;

    @Configuration
    @EnableBatchProcessing
    public class MyJob {

    @Autowired
    private JobBuilderFactory jobs;

    @Autowired
    private StepBuilderFactory steps;

    @Bean
    public ItemReader<Integer> itemReader() {
    return new ListItemReader<>(Arrays.asList(1, 2, 3, 4));
    }

    @Bean
    public ItemWriter<Integer> itemWriter() {
    return new ItemWriter<Integer>() {

    private StepExecution stepExecution;

    @Override
    public void write(List<? extends Integer> items) throws Exception {
    for (Integer item : items) {
    System.out.println("item = " + item);
    }
    stepExecution.getJobExecution().getExecutionContext().put("data", "foo");
    }

    @BeforeStep
    public void saveStepExecution(StepExecution stepExecution) {
    this.stepExecution = stepExecution;
    }

    };
    }

    @Bean
    public Step step() {
    return steps.get("step")
    .<Integer, Integer>chunk(2)
    .reader(itemReader())
    .writer(itemWriter())
    .build();
    }

    @Bean
    public Job job() {
    return jobs.get("job")
    .start(step())
    .listener(new JobExecutionListener() {
    @Override
    public void beforeJob(JobExecution jobExecution) {

    }

    @Override
    public void afterJob(JobExecution jobExecution) {
    ExecutionContext executionContext = jobExecution.getExecutionContext();
    String data = executionContext.getString("data");
    System.out.println("data from writer = " + data);
    }
    })
    .build();
    }

    public static void main(String args) throws Exception {
    ApplicationContext context = new AnnotationConfigApplicationContext(MyJob.class);
    JobLauncher jobLauncher = context.getBean(JobLauncher.class);
    Job job = context.getBean(Job.class);
    jobLauncher.run(job, new JobParameters());
    }

    }


    In this example, the writer writes the key data with value foo in the job execution context. Then, this key is retrieved from the execution context in the job listener.



    Hope this helps.






    share|improve this answer

























      up vote
      1
      down vote



      accepted










      You can pass data between these two components through the job execution context. This is detailed in the Passing Data to Future Steps section. Here is a quick example:



      import java.util.Arrays;
      import java.util.List;

      import org.springframework.batch.core.Job;
      import org.springframework.batch.core.JobExecution;
      import org.springframework.batch.core.JobExecutionListener;
      import org.springframework.batch.core.JobParameters;
      import org.springframework.batch.core.Step;
      import org.springframework.batch.core.StepExecution;
      import org.springframework.batch.core.annotation.BeforeStep;
      import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
      import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
      import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
      import org.springframework.batch.core.launch.JobLauncher;
      import org.springframework.batch.item.ExecutionContext;
      import org.springframework.batch.item.ItemReader;
      import org.springframework.batch.item.ItemWriter;
      import org.springframework.batch.item.support.ListItemReader;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.annotation.AnnotationConfigApplicationContext;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;

      @Configuration
      @EnableBatchProcessing
      public class MyJob {

      @Autowired
      private JobBuilderFactory jobs;

      @Autowired
      private StepBuilderFactory steps;

      @Bean
      public ItemReader<Integer> itemReader() {
      return new ListItemReader<>(Arrays.asList(1, 2, 3, 4));
      }

      @Bean
      public ItemWriter<Integer> itemWriter() {
      return new ItemWriter<Integer>() {

      private StepExecution stepExecution;

      @Override
      public void write(List<? extends Integer> items) throws Exception {
      for (Integer item : items) {
      System.out.println("item = " + item);
      }
      stepExecution.getJobExecution().getExecutionContext().put("data", "foo");
      }

      @BeforeStep
      public void saveStepExecution(StepExecution stepExecution) {
      this.stepExecution = stepExecution;
      }

      };
      }

      @Bean
      public Step step() {
      return steps.get("step")
      .<Integer, Integer>chunk(2)
      .reader(itemReader())
      .writer(itemWriter())
      .build();
      }

      @Bean
      public Job job() {
      return jobs.get("job")
      .start(step())
      .listener(new JobExecutionListener() {
      @Override
      public void beforeJob(JobExecution jobExecution) {

      }

      @Override
      public void afterJob(JobExecution jobExecution) {
      ExecutionContext executionContext = jobExecution.getExecutionContext();
      String data = executionContext.getString("data");
      System.out.println("data from writer = " + data);
      }
      })
      .build();
      }

      public static void main(String args) throws Exception {
      ApplicationContext context = new AnnotationConfigApplicationContext(MyJob.class);
      JobLauncher jobLauncher = context.getBean(JobLauncher.class);
      Job job = context.getBean(Job.class);
      jobLauncher.run(job, new JobParameters());
      }

      }


      In this example, the writer writes the key data with value foo in the job execution context. Then, this key is retrieved from the execution context in the job listener.



      Hope this helps.






      share|improve this answer























        up vote
        1
        down vote



        accepted







        up vote
        1
        down vote



        accepted






        You can pass data between these two components through the job execution context. This is detailed in the Passing Data to Future Steps section. Here is a quick example:



        import java.util.Arrays;
        import java.util.List;

        import org.springframework.batch.core.Job;
        import org.springframework.batch.core.JobExecution;
        import org.springframework.batch.core.JobExecutionListener;
        import org.springframework.batch.core.JobParameters;
        import org.springframework.batch.core.Step;
        import org.springframework.batch.core.StepExecution;
        import org.springframework.batch.core.annotation.BeforeStep;
        import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
        import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
        import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
        import org.springframework.batch.core.launch.JobLauncher;
        import org.springframework.batch.item.ExecutionContext;
        import org.springframework.batch.item.ItemReader;
        import org.springframework.batch.item.ItemWriter;
        import org.springframework.batch.item.support.ListItemReader;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.context.ApplicationContext;
        import org.springframework.context.annotation.AnnotationConfigApplicationContext;
        import org.springframework.context.annotation.Bean;
        import org.springframework.context.annotation.Configuration;

        @Configuration
        @EnableBatchProcessing
        public class MyJob {

        @Autowired
        private JobBuilderFactory jobs;

        @Autowired
        private StepBuilderFactory steps;

        @Bean
        public ItemReader<Integer> itemReader() {
        return new ListItemReader<>(Arrays.asList(1, 2, 3, 4));
        }

        @Bean
        public ItemWriter<Integer> itemWriter() {
        return new ItemWriter<Integer>() {

        private StepExecution stepExecution;

        @Override
        public void write(List<? extends Integer> items) throws Exception {
        for (Integer item : items) {
        System.out.println("item = " + item);
        }
        stepExecution.getJobExecution().getExecutionContext().put("data", "foo");
        }

        @BeforeStep
        public void saveStepExecution(StepExecution stepExecution) {
        this.stepExecution = stepExecution;
        }

        };
        }

        @Bean
        public Step step() {
        return steps.get("step")
        .<Integer, Integer>chunk(2)
        .reader(itemReader())
        .writer(itemWriter())
        .build();
        }

        @Bean
        public Job job() {
        return jobs.get("job")
        .start(step())
        .listener(new JobExecutionListener() {
        @Override
        public void beforeJob(JobExecution jobExecution) {

        }

        @Override
        public void afterJob(JobExecution jobExecution) {
        ExecutionContext executionContext = jobExecution.getExecutionContext();
        String data = executionContext.getString("data");
        System.out.println("data from writer = " + data);
        }
        })
        .build();
        }

        public static void main(String args) throws Exception {
        ApplicationContext context = new AnnotationConfigApplicationContext(MyJob.class);
        JobLauncher jobLauncher = context.getBean(JobLauncher.class);
        Job job = context.getBean(Job.class);
        jobLauncher.run(job, new JobParameters());
        }

        }


        In this example, the writer writes the key data with value foo in the job execution context. Then, this key is retrieved from the execution context in the job listener.



        Hope this helps.






        share|improve this answer












        You can pass data between these two components through the job execution context. This is detailed in the Passing Data to Future Steps section. Here is a quick example:



        import java.util.Arrays;
        import java.util.List;

        import org.springframework.batch.core.Job;
        import org.springframework.batch.core.JobExecution;
        import org.springframework.batch.core.JobExecutionListener;
        import org.springframework.batch.core.JobParameters;
        import org.springframework.batch.core.Step;
        import org.springframework.batch.core.StepExecution;
        import org.springframework.batch.core.annotation.BeforeStep;
        import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
        import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
        import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
        import org.springframework.batch.core.launch.JobLauncher;
        import org.springframework.batch.item.ExecutionContext;
        import org.springframework.batch.item.ItemReader;
        import org.springframework.batch.item.ItemWriter;
        import org.springframework.batch.item.support.ListItemReader;
        import org.springframework.beans.factory.annotation.Autowired;
        import org.springframework.context.ApplicationContext;
        import org.springframework.context.annotation.AnnotationConfigApplicationContext;
        import org.springframework.context.annotation.Bean;
        import org.springframework.context.annotation.Configuration;

        @Configuration
        @EnableBatchProcessing
        public class MyJob {

        @Autowired
        private JobBuilderFactory jobs;

        @Autowired
        private StepBuilderFactory steps;

        @Bean
        public ItemReader<Integer> itemReader() {
        return new ListItemReader<>(Arrays.asList(1, 2, 3, 4));
        }

        @Bean
        public ItemWriter<Integer> itemWriter() {
        return new ItemWriter<Integer>() {

        private StepExecution stepExecution;

        @Override
        public void write(List<? extends Integer> items) throws Exception {
        for (Integer item : items) {
        System.out.println("item = " + item);
        }
        stepExecution.getJobExecution().getExecutionContext().put("data", "foo");
        }

        @BeforeStep
        public void saveStepExecution(StepExecution stepExecution) {
        this.stepExecution = stepExecution;
        }

        };
        }

        @Bean
        public Step step() {
        return steps.get("step")
        .<Integer, Integer>chunk(2)
        .reader(itemReader())
        .writer(itemWriter())
        .build();
        }

        @Bean
        public Job job() {
        return jobs.get("job")
        .start(step())
        .listener(new JobExecutionListener() {
        @Override
        public void beforeJob(JobExecution jobExecution) {

        }

        @Override
        public void afterJob(JobExecution jobExecution) {
        ExecutionContext executionContext = jobExecution.getExecutionContext();
        String data = executionContext.getString("data");
        System.out.println("data from writer = " + data);
        }
        })
        .build();
        }

        public static void main(String args) throws Exception {
        ApplicationContext context = new AnnotationConfigApplicationContext(MyJob.class);
        JobLauncher jobLauncher = context.getBean(JobLauncher.class);
        Job job = context.getBean(Job.class);
        jobLauncher.run(job, new JobParameters());
        }

        }


        In this example, the writer writes the key data with value foo in the job execution context. Then, this key is retrieved from the execution context in the job listener.



        Hope this helps.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 9 at 19:06









        Mahmoud Ben Hassine

        3,4301714




        3,4301714






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53231769%2fspring-batch-pass-parameter-from-writer-to-listener-for-afterjobjobexecution%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Schultheiß

            Verwaltungsgliederung Dänemarks

            Liste der Kulturdenkmale in Wilsdruff