am currently reading csv files with spring batch into objects where i have to save total lines as well as rejected/skipped lines of that current file ,and using StepExecutionListener didn't work since i need to get it before the step ends and not after the step . is there a way i can get them to be saved in itemProcessor or itemWriter without having to add another step?
Asked
Active
Viewed 471 times
1 Answers
0
i need to get it before the step ends and not after the step
You can't get the total number of lines without going until the end of the step (ie reading the entire file).
using StepExecutionListener didn't work
Using a step execution listener is the way to go. You did not share your code to see why this didn't work for you, but here is a quick example:
import java.util.Arrays;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.StepExecutionListener;
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.ItemProcessor;
import org.springframework.batch.item.support.ListItemReader;
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 MyJobConfiguration {
@Bean
public Job job(JobBuilderFactory jobs, StepBuilderFactory steps) {
return jobs.get("myJob")
.start(steps.get("myStep")
.<Integer, Integer>chunk(2)
.reader(new ListItemReader<>(Arrays.asList(1, 2, 3, 4)))
.processor((ItemProcessor<Integer, Integer>) item -> {
if (item % 2 != 0) {
throw new Exception("No odd numbers here!");
}
return item;
})
.writer(items -> items.forEach(System.out::println))
.faultTolerant()
.skip(Exception.class)
.skipLimit(5)
.listener(new StepExecutionListener() {
@Override
public void beforeStep(StepExecution stepExecution) {
System.out.println("Starting step " + stepExecution.getStepName());
}
@Override
public ExitStatus afterStep(StepExecution stepExecution) {
System.out.println("Step "+ stepExecution.getStepName() + " is complete");
System.out.println("read.count = " + stepExecution.getReadCount());
System.out.println("write.count = " + stepExecution.getWriteCount());
System.out.println("skip.count = " + stepExecution.getSkipCount());
return stepExecution.getExitStatus();
}
})
.build())
.build();
}
public static void main(String[] args) throws Exception {
ApplicationContext context = new AnnotationConfigApplicationContext(MyJobConfiguration.class);
JobLauncher jobLauncher = context.getBean(JobLauncher.class);
Job job = context.getBean(Job.class);
jobLauncher.run(job, new JobParameters());
}
}
This prints:
Starting step myStep
2
4
Step myStep is complete
read.count = 4
write.count = 2
skip.count = 2

Mahmoud Ben Hassine
- 28,519
- 3
- 32
- 50
-
well am able to read them but only in the step listner is there a way i can read the total read lines and skipped lines in item processor – rbm May 07 '21 at 09:26
-
Yes, but that would be the *current* total (ie partial accumulation) of items until the *current* chunk. For that, you can inject the step execution in the processor, see https://stackoverflow.com/questions/14949985/how-to-get-jobparameter-and-jobexecutioncontext-in-the-itemwriter. – Mahmoud Ben Hassine May 07 '21 at 10:08
-
how can i inject it in the processor class ? – rbm May 07 '21 at 10:33
-
The link I shared contains an example: https://stackoverflow.com/a/29836035/5019386. See also https://stackoverflow.com/questions/14263583/how-do-i-get-spring-batch-job-contextid-in-itemprocessor-or-itemwriter – Mahmoud Ben Hassine May 07 '21 at 10:45
-
using `@BeforeStep` provides info before reading any chunks/items i am still not able to get the current total read lines i tried `@BeforeProcess` because i thought it would be logical to get it before processing but obviously i was wrong – rbm May 07 '21 at 15:19