2

I'd like to create a generic StepExecutionListener. It should log the item count processed by a Tasklet step.

Problem: the count is not updated automatically. So I probably have to do this somewhere in Tasklet.execute(). But how?

    @Bean
    @JobScope
    public Tasklet myTasklet() {
        return new Tasklet() {
            @Override
            public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
                int count = dao.deleteByName(name);
                //TODO how to set the count into the stepExecution context?
                return RepeatStatus.FINISHED;
            }
        };
    }

    @Bean
    public Step myStep() {
        return getStepBuilderFactory().get("myStep")
                .listener(new StepListener())
                .tasklet(myTasklet())
                .build();
    }


public class StepListener extends StepExecutionListenerSupport {
    @Override
    public ExitStatus afterStep(StepExecution stepExecution) {
        long items = stepExecution.getWriteCount();
        logger.info("items processed in tasklet: " + items);
        return super.afterStep(stepExecution);
    }
}
membersound
  • 81,582
  • 193
  • 585
  • 1,120
  • What do you mean by `stepExecution.getWriteCount()` is not updated automatically ? What result does it gives you ? – Asoub Oct 06 '16 at 09:06
  • It gives `0` no matter how many items I process within the tasklet itself. Of course this is due to the fact that no item count or whatsoever is returned to the spring batch process from the tasklet. – membersound Oct 06 '16 at 11:01

2 Answers2

2

contribution.incrementWriteCount() is probably the way to go

@Bean
@JobScope
public Tasklet myTasklet() {
    return new Tasklet() {
        @Override
        public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
            int count = dao.deleteByName(name);
            contribution.incrementWriteCount(count); // <--
            return RepeatStatus.FINISHED;
        }
    };
}
membersound
  • 81,582
  • 193
  • 585
  • 1,120
1

You can get the StepExecution from your execute() with stepExecution = chunkContext.getStepContext().getStepExecution(). You should set the stepExecutionContext in your Tasklet to prevent making the get method on every execute (this might be costly as I don't think these are simple getters).

You can now manipulate the stepExecution's inners variables in your execute() with stepExecution.setLong("yourWriteCount", count) and same to get it. (it doesn't matter if it's a custom tasklet, the same rules applies).

In the listener, you can get yourWriteCount with the executionContext parameter, the same way.

Normally the executionContext is the same through the whole step.

Asoub
  • 2,273
  • 1
  • 20
  • 33