1

In Spring Batch I have a custom ItemProcessor. I want to pass information from the afterStep to the process method. Here's the code

@Component
public class Clf010Processor implements ItemProcessor<Clf010Item, Clf010Item> {

    private StepExecution stepExecution;

    BatchProgram batch = new BatchProgram();

    @AfterStep
    public void afterStep(StepExecution stepExecution) {
        ExecutionContext je = stepExecution.getJobExecution().getExecutionContext();
        // Pass the counts up to the execution context.
        je.putLong("writeCount", stepExecution.getWriteCount());
        je.putLong("clfCount", stepExecution.getWriteCount());
    }

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

    @Override
    public Clf010Item process(Clf010Item item) throws Exception {
        batch.print("writeCount = ", stepExecution.getWriteCount());
        return item;
    }

}

I want to access writeCount and clfCount from after step in process. Like:

@Override
public Clf010Item process(Clf010Item item) throws Exception {
    batch.print("writecount = ", stepExecution.getWriteCount());
    return item;
}

Is this possible?

Ahmed Ashour
  • 5,179
  • 10
  • 35
  • 56
Josh
  • 341
  • 5
  • 26

3 Answers3

1

Yes. I think it is a common pattern to hand over infos via the StepExecution. In that case the StepExecution is held as a member variable in of the ItemProcessor and can be set via the beforeStep method. E.g:

public class Clf010Processor implements ItemProcessor<Clf010Item, Clf010Item> {

    private StepExecution stepExecution;

    @AfterStep
    public void afterStep(StepExecution stepExecution) {
        ExecutionContext je = stepExecution.getJobExecution().getExecutionContext();
        // Pass the counts up to the execution context.
        je.putLong("writeCount", stepExecution.getWriteCount());
        je.putLong("clfCount", stepExecution.getWriteCount());
    }

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

    @Override
    public Clf010Item process(Clf010Item item) throws Exception {
        JobExecution jobExecution = this.stepExecution.getJobExecution();
        ExecutionContext jobContext = jobExecution.getExecutionContext();
        long writeCount = jobContext.getLong("writeCount");
        batch.print("writecount = ", writeCount);
        return item;
    }
}
brass monkey
  • 5,841
  • 10
  • 36
  • 61
  • Well, "writeCount = " goes to my console where I want it, but there is no value being printed by `stepExecution.getWriteCount();` – Josh Aug 22 '18 at 21:19
  • Yes, you are right. I updated my answer to get the writeCount via `jobContext.getLong("writeCount")`. – brass monkey Aug 23 '18 at 08:17
  • Thanks for the help :) I'll choose a correct answer once I get things working. – Josh Aug 23 '18 at 14:16
1

I want to pass information from the afterStep to the process method

The method annotated with AfterStep will be executed after the entire step is finished (including reading, processing and writing), but the process method is executed while the step is running. So the information you are requesting in process (the writeCount) is not available yet at that moment.

Mahmoud Ben Hassine
  • 28,519
  • 3
  • 32
  • 50
0

In response to Mahmoud Ben Hassine's answer, here is my code:

@Component
public class Clf010Processor implements ItemProcessor<Clf010Item, Clf010Item> {

    BatchProgram batch = new BatchProgram();

    @AfterStep
    public void afterStep(StepExecution stepExecution) {
        ExecutionContext je = stepExecution.getJobExecution().getExecutionContext();
        // Pass the counts up to the execution context.
        je.putLong("writeCount", stepExecution.getWriteCount());
        je.putLong("clfCount", stepExecution.getWriteCount());
        je.putLong("readCount", stepExecution.getReadCount());
        // Log the program results
        batch.print("");
        batch.print("**********************************************************");
        batch.print("INPUT RECORDS READ =  " + stepExecution.getReadCount());
        batch.print("**********************************************************");
        batch.print("");
        batch.print("**********************************************************");
        batch.print("OUTPUT RECORDS WRITTEN =  " + stepExecution.getWriteCount());
        batch.print("**********************************************************");
        batch.print("");
    }

    @BeforeStep
    public void beforeStep(StepExecution stepExecution) {}

    @Override
    public Clf010Item process(Clf010Item item) throws Exception {
        return item;
    }

}
Josh
  • 341
  • 5
  • 26