TheNorthWes
TheNorthWes

Reputation: 2739

Spring Batch context holder null

Sorry for inundating the spring batch SO queue.

I moved on from the Job Scope pattern, since that appears to not work in XML configuration for 3.0.6. I could very well just be confused though.

I tried moving on to the step scope since that seems to work. This is my app-context.xml configuration header for my beans. This enables the scope="step" option.

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:batch="http://www.springframework.org/schema/batch"
   xmlns:util="http://www.springframework.org/schema/util"
   xmlns:p="http://www.springframework.org/schema/p"
   xsi:schemaLocation="
    http://www.springframework.org/schema/batch
    http://www.springframework.org/schema/batch/spring-batch-3.0.xsd
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/util
    http://www.springframework.org/schema/util/spring-util.xsd
    http://www.springframework.org/schema/cache
    http://www.springframework.org/schema/cache/spring-cache.xsd">

However, creating of those beans fails. Importantly, these are REST Easy client proxied beans. Which i am defining like so:

<bean id="rootServiceBean" scope="step"
      class="com.myorg.ServiceProxyFactoryBean"
      p:baseUri="${rest.base.uri}"
      p:ticket="#{jobExecutionContext['jobSecrets']}" abstract="true"/>

and then on my instances:

<bean id="someServiceObject"
      parent="rootServiceBean"
      p:serviceInterface="com.myOrg.someServiceRest"/>

But I get errors cascading down from My top level job, its children jobs, its children steps, and those steps beans, which finally are caused by...

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'someService': 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:341) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191) at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328) ... 79 more 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:327) ... 81 more

Is there some context I need to initialize on my jobs? Or is spring-batch colliding with the proxy that rest easy client is leveraging?

Upvotes: 0

Views: 2258

Answers (1)

Artefacto
Artefacto

Reputation: 97835

First, you shouldn't just give up on the job scope because of some putative bug, let alone “move to the step scope”; both are important and serve different purposes. The mosty obvious difference is that a job scoped bean lives for the duration of a job and step scoped bean for the duration of a single step.

If there is indeed a bug, you can register the job scope the same way you register any other Spring context; actually, even easier because Spring Batch's scope implementation also takes care of registering itself and of automatically creating singleton proxy beans (if you leave the autoProxy property set to true, which is the default). All you need is to include a bean of the type org.springframework.batch.core.scope.JobScope.

As for your error, you don't provide enough information. There may be many causes; all we know is that Spring tried to instantiate a step scoped bean without any job step running, at least as far as the thread that tried to get the bean is concerned. So your first step is to determine what triggered the bean to be instantiated. This can be 1) failing to create a singleton proxy (shouldn't be a problem if you have the default autoproxying setup; note that in that case the bean name you specify is the one given to the singleton proxy, the actually step scoped bean to which it delegates is renamed stepScopedTarget.<original bean name>) or, more likely if you have the basics working, 2) calling a method on the singleton proxy prematurely, i.e., before there is a step active. If you using several threads for the same job, you may also have to propagate the step scope to it using StepSynchronizationManager::register/JobSynchronizationManager::close.

Upvotes: 1

Related Questions