6
votes

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.

1
It's unlikely the exception is thrown inside this class. Show the full stacktrace dudeMạnh Quyết Nguyễn
I have updated my original post with exception stack.DBreaker
This might help you Scope step issueMạnh Quyết Nguyễn
Thanks for the link provided. I will try the optionDBreaker
I'm facing same problem with same use case, could you share the solution that worked for you.Prasanna

1 Answers

2
votes

Please try the option Spring batch scope issue while using spring boot, posted by Manh. I guess it solved the problem. Unfortunately I no longer have access to the code base, to confirm what I did for the fix.