29

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.

MohanaRao SV
  • 1,117
  • 1
  • 8
  • 22
Smita
  • 309
  • 1
  • 3
  • 4
  • 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 '13 at 05: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. – Karthick Meenakshi Sundaram Mar 18 '19 at 00:26
  • If your requirement was to have the writer as a StepExecutionListener and also stepScoped, this is the solution.. and this worked for me. https://stackoverflow.com/a/21941127/3004747 – Karthick Meenakshi Sundaram Mar 18 '19 at 00:28

4 Answers4

24

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.

Adrian Shum
  • 38,812
  • 10
  • 83
  • 131
  • 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: , then 2) in the bean: private JobExecutionContext context; (no need for @Value) Is there anything missing or wrong? Thanks very much – user1052610 Apr 30 '14 at 19:35
  • 1. you need the bean being step scope, 2. you need setter for "context" property. – Adrian Shum Sep 16 '14 at 02:27
  • How does it behave when executing many jobs at once? any thread safe problems? – rayman Apr 21 '15 at 15:06
  • 1
    Step scope is going to make a new instance for each step execution. – Adrian Shum Apr 21 '15 at 15:18
  • @Adrain If we are passing data through jobExecutionContext then is it necessary to configure ExecutionContextPromotionListener with the keys ? – user1919581 May 19 '15 at 04:58
  • @user1919581 You may. However it has nothing to do with this question. – Adrian Shum May 28 '15 at 10:20
  • 1
    Making my itemWriter StepScope gives a null pointer exception – Derrops Jan 23 '19 at 12:56
22

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();
    }
}
alturkovic
  • 990
  • 8
  • 31
yuturi river
  • 221
  • 2
  • 2
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;
manash
  • 6,985
  • 12
  • 65
  • 125
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.

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