I've a one class that I use to create two different Beans. These two Beans are then used to create two Steps and these two steps must be executed in sequence. I use one class to create two beans because the logic to be executed is the same. By passing different values in the constructor, the data to be fetched is different.
But when Spring-batch is running, an IllegalStateException exception is thrown: What causes this exception to be thrown ?
Caused by: org.springframework.beans.factory.support.ScopeNotActiveException: Error creating bean with name 'scopedTarget.stepBrussels': Scope 'step' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton; nested exception is java.lang.IllegalStateException: No context holder available for step scope
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:383)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:195)
at com.sun.proxy.$Proxy50.getName(Unknown Source)
at org.springframework.batch.core.job.flow.JobFlowExecutor.isStepRestart(JobFlowExecutor.java:86)
at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:67)
at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:68)
at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:169)
... 28 common frames omitted
Caused by: java.lang.IllegalStateException: No context holder available for step scope
at org.springframework.batch.core.scope.StepScope.getContext(StepScope.java:167)
at org.springframework.batch.core.scope.StepScope.get(StepScope.java:99)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:371)
@Configuration
@Slf4j
public class InstrumentReaderConfig {
@Value("${chartinvest.url.admin}")
private String adminUrl;
@Value("${eodHistoricalData.url.listOfTickers}")
private String listOfTickerslUrl;
@Bean
public ItemReader<TickerDto> itemReaderBr() throws JsonProcessingException {
return new InstrumentReader(adminUrl, listOfTickerslUrl, "XBRU", "BR", "BE");
}
@Bean
public ItemReader<TickerDto> itemReaderAs() throws JsonProcessingException {
return new InstrumentReader(adminUrl, listOfTickerslUrl, "XAMS", "AS", "NL");
}
}
@Configuration
public class StepConfig {
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Autowired
private ItemReader itemReaderBr;
@Autowired
private ItemReader itemReaderAs;
@Autowired
private ItemProcessor itemProcessorEodHistorical;
@Autowired
private ItemWriter<TickerDto> itemWriterEodHistorical;
@Bean
@StepScope
public Step stepBrussels() {
return stepBuilderFactory.get("Brussels").<TickerDto, TickerDto>chunk(1)
.reader(itemReaderBr)
.processor(itemProcessorEodHistorical)
.writer(itemWriterEodHistorical)
.build();
}
@Bean
@StepScope
public Step stepAmsterdam() {
return stepBuilderFactory.get("Amsterdam").<TickerDto, TickerDto>chunk(1)
.reader(itemReaderAs)
.processor(itemProcessorEodHistorical)
.writer(itemWriterEodHistorical)
.build();
}
}
@Configuration
public class JobConfig {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Bean
public Job processJob(Step stepBrussels, Step stepAmsterdam, JobExecutionListener listener) {
return jobBuilderFactory
.get("processJob")
.incrementer(new RunIdIncrementer())
.listener(listener)
.flow(stepBrussels)
.next(stepAmsterdam)
.end()
.build();
}
}
CodePudding user response:
Remove @StepScope from your step beans, @StepScope is only for beans used in steps, not steps themselves