In my Spring batch configuration, I'm trying to setup a partitioned step, which accesses values from JobParameters as follows :
@Bean
@Qualifier("partitionJob")
public Job partitionJob() throws Exception {
return jobBuilderFactory
.get("partitionJob")
.incrementer(new RunIdIncrementer())
.start(partitionStep(null))
.build();
}
@Bean
@StepScope //I'm getting exception here - > Error creating bean
public Step partitionStep(
@Value("#{jobParameters[gridSize]}") String gridSize)
throws Exception {
return stepBuilderFactory
.get("partitionStep")
.partitioner("slaveStep", partitioner())
.gridSize(
StringUtils.isEmpty(gridSize) ? 10 : Integer
.parseInt(gridSize))
.step(slaveStep(50000))
.taskExecutor(threadPoolTaskExecutor()).build();
}
@Bean
@StepScope
public Step slaveStep(int chunkSize) throws Exception {
return stepBuilderFactory
.get("slaveStep")
.<Person,Person> chunk(chunkSize)
.reader(jdbcPagingItemReader()),
.writer(csvFileWriterParts())
.listener(stepExecutionListener()).build();
}
I have added @EnableBatchProcessing annotation to my SpringBoot application.
Since I wanted to access JobParameters while constructing a step, I used @StepScope. I have an example that works fine, without @StepScope annotation, but in that case I'm not accessing any JobParameters or anything from context.
But If I use StepScope annotation on partitionStep, I'm getting
Error creating bean with name 'scopedTarget.partitionStep': 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
but If I change it to JobScope, then it is failing at slaveStep() with same error message.
What is the correct scope to be used in such cases and how to resolve this issue I'm getting ?
What is the better way of accessing JobParameters while configuring spring beans ?
Exception stack is as below
2018-05-25 21:07:32,075 ERROR [main] org.springframework.batch.core.job.AbstractJob : Encountered fatal error executing job org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.partitionStep': 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:361) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:192) at com.sun.proxy.$Proxy55.getName(Unknown Source) at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:115) at org.springframework.batch.core.job.AbstractJob.handleStep(AbstractJob.java:392) at org.springframework.batch.core.job.SimpleJob.doExecute(SimpleJob.java:135) at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:306) at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:135) at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50) at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:128) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at org.springframework.batch.core.configuration.annotation.SimpleBatchConfiguration$PassthruAdvice.invoke(SimpleBatchConfiguration.java:127) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) at com.sun.proxy.$Proxy54.run(Unknown Source) at com.sample.main(ExtractApplication.java:58) 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:346) ... 23 common frames omitted
If I modify to JobScope, I get exception on slaveStep, which is similar to the above exception.