Spring Batch Job Running in Infinite loop
Solution 1
A step will run until your ItemReader
returns null. In your case, your ItemReader
never does (it always returns a new Person
) so it will never end.
Solution 2
Add a flag to resist the reader to run in infinite loop.
Reader:
public class PersonReader implements ItemReader<Person> {
private boolean batchJobState = false;
@Override
public Person read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
if(!batchJobState){
Person person = new Person();
System.out.println("In PersonReader");
batchJobState=true;
return person;
}
return null;
}
}
Solution 3
Is someone came here with the same error, but using FlatFileItemReader
(what is a Reader
implementation), see if you have more than one step
with the same name.
I had two steps on my Spring Batch project with the same name. The last step among this two executed caused a infinite loop.
Solution 4
Use the interface StepExecutionListener. This will provide two methods
Use a variable boolean FLAG at instance level.
public class PersonReader implements ItemReader,StepExecutionListener { private boolean jobState = false;
@Override
public Person read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
if(!**jobState**){
Person person = new Person();
System.out.println("In PersonReader");
jobState=true;
return person;
}
return null;
}
}
@Override public void beforeStep(StepExecution stepExecution) { }
@Override public ExitStatus afterStep(StepExecution stepExecution) {
**jobState** = false;
return stepExecution.getExitStatus();
}
}
- before read() method execution beforeStep method executes.
- read() method set a flag to true.
- after read() method execution, afterStep method will executes and set the flag as false.
- Whenever your scheduler start the job after 10 minutes the value will be false initially.
Comments
-
MRX almost 2 years
I am working on simple Spring Batch Job. When I launch job its running in infinite loop. It doesn't stop. According to my scheduler time it should run after every 10 seconds. But when job starts it doesn't stop. Its just keeps printing sysouts from reader, processor and writer respectively. I am creating job with reader, processor and writer. And I am doing all configuration by annotations. Not by xml.
Here is Batch Configuration
@Configuration @EnableBatchProcessing @EnableScheduling public class BatchJobConfig { @Autowired private JobBuilderFactory jobBuilderFactory; @Autowired private StepBuilderFactory stepBuilderFactory; @Autowired private SimpleJobLauncher jobLauncher; @Scheduled(cron="*/10 * * * * *") public void perform() throws Exception { Job job = job(step1()); JobParameters jobParameters = new JobParameters(); jobLauncher.run(job, jobParameters); } @Bean public Step step1() { return stepBuilderFactory.get("step1").<Person, Person> chunk(1) .reader(reader()).processor(processor()).writer(writer()) .build(); } @Bean public Job job(Step step1) throws Exception { return jobBuilderFactory.get("job") .incrementer(new RunIdIncrementer()).flow(step1()) .end().build(); } @Bean public DataSource dataSource() { EmbeddedDatabaseBuilder embeddedDatabaseBuilder = new EmbeddedDatabaseBuilder(); return embeddedDatabaseBuilder.addScript("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql") .addScript("classpath:org/springframework/batch/core/schema-hsqldb.sql") .setType(EmbeddedDatabaseType.HSQL) .build(); } @Bean public PersonReader reader() { return new PersonReader(); } @Bean public PersonWriter writer() { return new PersonWriter(); } @Bean public PersonProcessor processor() { return new PersonProcessor(); } @Bean public MapJobRepositoryFactoryBean mapJobRepositoryFactory(ResourcelessTransactionManager txManager) throws Exception { MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean(txManager); factory.afterPropertiesSet(); return factory; } @Bean public JobRepository jobRepository(MapJobRepositoryFactoryBean factory) throws Exception { return factory.getObject(); } @Bean public SimpleJobLauncher jobLauncher(JobRepository jobRepository) { SimpleJobLauncher launcher = new SimpleJobLauncher(); launcher.setJobRepository(jobRepository); return launcher; } @Bean public ResourcelessTransactionManager transactionManager() { return new ResourcelessTransactionManager(); } }
PersonReader.java
public class PersonReader implements ItemReader<Person> { @Override public Person read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException { Person person = new Person(); System.out.println("In PersonReader"); return person; } }
PersonWriter.java
public class PersonWriter implements ItemWriter<Person> { @Override public void write(List<? extends Person> arg0) throws Exception { System.out.println("IN PersonWriter"); } }
PersonProcessor.java
public class PersonProcessor implements ItemProcessor<Person, Person> { @Override public Person process(Person arg0) throws Exception { System.out.println("In PersonProcessor"); return arg0; } }