31

I want to retrieve JobParameter and JobExecutionContext object in my ItemWriter class. How to proceed?

I tried implementing StepExecutionListener through which I am just calling the parent class methods. But it is not succeeding.

Thanks in advance.

3
  • 1
    I have solved the above problem by extending StepExecutionListenerSupport class.After that override parent class method that is'beforeStep' public void beforeStep(StepExecution stepExecution) { // TODO Auto-generated method stub this.stepExecution = stepExecution; }
    – Smita
    Feb 19, 2013 at 5:00
  • I faced the same problem and tried your solution by extending StepExecutionListenerSupport class, and the afterStep and beforeStep methods were not called. Was your ItemWriter a StepScoped Bean? I faced the same problem when my ItemWriter was a stepscoped bean. On changing back to singleton bean, the beforeStep and after methods were called. Mar 18, 2019 at 0:26
  • If your requirement was to have the writer as a StepExecutionListener and also stepScoped, this is the solution.. and this worked for me. stackoverflow.com/a/21941127/3004747 Mar 18, 2019 at 0:28

4 Answers 4

25

Implementing StepExecutionListener is one way. In fact that's the only way in Spring Batch 1.x.

Starting from Spring Batch 2, you have another choice: You can inject whatever entries in Job Parameters and Job Execution Context to your item writer. Make your item writer with step scope, then make use of expression like #{jobParameters['theKeyYouWant']} or #{jobExecutionContext['someOtherKey']} for value injecting to you item writer.

7
  • 2
    Adrian, can you clarify this is the correct way to inject the JobExecutionContext into an item reader, writer, or processor: 1) in config, inject into the bean: <property name="context" value"#{jobExecutionContext}"/>, then 2) in the bean: private JobExecutionContext context; (no need for @Value) Is there anything missing or wrong? Thanks very much Apr 30, 2014 at 19:35
  • 1. you need the bean being step scope, 2. you need setter for "context" property. Sep 16, 2014 at 2:27
  • How does it behave when executing many jobs at once? any thread safe problems?
    – rayman
    Apr 21, 2015 at 15:06
  • 1
    Step scope is going to make a new instance for each step execution. Apr 21, 2015 at 15:18
  • 1
    Making my itemWriter StepScope gives a null pointer exception
    – Derrops
    Jan 23, 2019 at 12:56
23

Use the @BeforeStep annotation to call a method before step processing.

//From the StepExecution get the current running JobExecution object.
public class MyDataProcessor implements ItemProcessor<MyDataRow, MyDataRow> {
    private JobExecution jobExecution;

    @BeforeStep
    public void beforeStep(StepExecution stepExecution) {
        jobExecution = stepExecution.getJobExecution();
    }
}
12

To add to Adrian Shum's answer, if you want to avoid each job parameter to be injected as a class property, you can directly inject the Map of JobParameters as follows:

@Value("#{jobParameters}")
private Map<String, JobParameter> jobParameters;
6

If you are using Spring Configuration file, you can access the StepExecution object with:

<bean id="aaaReader" class="com.AAAReader" scope="step">
    <property name="stepExecution" value="#{stepExecution}" />
</bean>

In AAAReader class you need to create the proper field and a setter:

private StepExecution stepExecution;

public void setStepExecution(final StepExecution stepExecution) {
    this.stepExecution = stepExecution;
}

Same for Processor and Writer classes.

2
  • 1
    Wondering why did I got a down vote on this - without a comment?
    – razvanone
    Nov 15, 2018 at 9:59
  • is it possible to use your solution to access step execution from a listener. more precisely a class that implement ItemProcessorListener
    – Abenamor
    Mar 2, 2023 at 10:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.