Closed
Description
Bug description
I have a Job
that contains a Step
that is annotated with @JobScope
(to be able to inject job parameters).
Using JobOperator.stop()
from another thread to stop that job fails with the following exception:
org.springframework.beans.factory.support.ScopeNotActiveException: Error creating bean with name 'scopedTarget.step': Scope 'job' 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 job scope
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:383) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.6.jar:5.3.6]
at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35) ~[spring-aop-5.3.6.jar:5.3.6]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:195) ~[spring-aop-5.3.6.jar:5.3.6]
at com.sun.proxy.$Proxy48.getName(Unknown Source) ~[na:na]
at org.springframework.batch.core.job.SimpleJob.getStep(SimpleJob.java:109) ~[spring-batch-core-4.3.2.jar:4.3.2]
at org.springframework.batch.core.launch.support.SimpleJobOperator.stop(SimpleJobOperator.java:402) ~[spring-batch-core-4.3.2.jar:4.3.2]
at org.springframework.batch.core.launch.support.SimpleJobOperator$$FastClassBySpringCGLIB$$44ee6049.invoke(<generated>) ~[spring-batch-core-4.3.2.jar:4.3.2]
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218) ~[spring-core-5.3.6.jar:5.3.6]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:779) ~[spring-aop-5.3.6.jar:5.3.6]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.6.jar:5.3.6]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) ~[spring-aop-5.3.6.jar:5.3.6]
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-5.3.6.jar:5.3.6]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388) ~[spring-tx-5.3.6.jar:5.3.6]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-5.3.6.jar:5.3.6]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.6.jar:5.3.6]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:750) ~[spring-aop-5.3.6.jar:5.3.6]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:692) ~[spring-aop-5.3.6.jar:5.3.6]
at org.springframework.batch.core.launch.support.SimpleJobOperator$$EnhancerBySpringCGLIB$$2759e0b7.stop(<generated>) ~[spring-batch-core-4.3.2.jar:4.3.2]
at com.example.demo.DemoApplication.lambda$runner$0(DemoApplication.java:54) ~[classes/:na]
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:819) ~[spring-boot-2.4.5.jar:2.4.5]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:803) ~[spring-boot-2.4.5.jar:2.4.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:346) ~[spring-boot-2.4.5.jar:2.4.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1340) ~[spring-boot-2.4.5.jar:2.4.5]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1329) ~[spring-boot-2.4.5.jar:2.4.5]
at com.example.demo.DemoApplication.main(DemoApplication.java:91) ~[classes/:na]
Caused by: java.lang.IllegalStateException: No context holder available for job scope
at org.springframework.batch.core.scope.JobScope.getContext(JobScope.java:159) ~[spring-batch-core-4.3.2.jar:4.3.2]
at org.springframework.batch.core.scope.JobScope.get(JobScope.java:92) ~[spring-batch-core-4.3.2.jar:4.3.2]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:371) ~[spring-beans-5.3.6.jar:5.3.6]
... 25 common frames omitted
Environment
Spring Batch: 4.3.2
Steps to reproduce
- Configure job with job-scoped steps.
- Run job asynchronously (to get hold of the pending
JobExecution
). - Use
JobOperator.stop()
to stop that job.
Expected behavior
Stopping the job works, regardless of the scope of its steps.
Minimal Complete Reproducible example
Sample project:
demo.zip
The project contains a job-scoped step. A CommandLineRunner
creates a JobLauncher
that launches jobs asynchronously.
Then, the main thread waits two seconds before it calls JobOperator.stop()
.
- Unzip.
- Run
./mvnw spring-boot:run
- Two seconds after the job was started,
JobOperator.stop()
is called and fails with the exception above.