title: Spring Batch: Getting step context in processor for partitioned step
body: <p>I'm developing a Spring Batch job that processes multiple input files in parallel using a MultiResourcePartitioner.  In the ItemProcessor I need to get the number of records in the current input file.  I get the current file name from the step context and read the number of lines in the file:</p>
  
  <pre><code>StepSynchronizationManager.register(stepExecution);
  StepContext stepContext = StepSynchronizationManager.getContext();
  StepSynchronizationManager.close();
  log.trace("stepContext: " + stepContext.getStepExecution().getExecutionContext().entrySet().toString());
  ...
  UrlResource currentFile = new UrlResource(stepContext.getStepExecution().getExecutionContext().getString("fileName"));
  </code></pre>
  
  <p>This all seems to work but I'm getting exceptions when accessing the step context from the processor threads:</p>
  
  <pre><code>2013-05-15 11:44:35,178 DEBUG [org.springframework.batch.core.step.tasklet.TaskletStep] &lt;taskExecutor-3&gt; - Rollback for RuntimeException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.processor': 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
  2013-05-15 11:44:35,194 DEBUG [org.springframework.jdbc.datasource.DataSourceUtils] &lt;taskExecutor-3&gt; - Returning JDBC Connection to DataSource
  2013-05-15 11:44:35,194 DEBUG [org.springframework.batch.repeat.support.RepeatTemplate] &lt;taskExecutor-3&gt; - Handling exception: org.springframework.beans.factory.BeanCreationException, caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.processor': 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
  2013-05-15 11:44:35,194 DEBUG [org.springframework.batch.repeat.support.RepeatTemplate] &lt;taskExecutor-3&gt; - Handling fatal exception explicitly (rethrowing first of 1): org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.processor': 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
  2013-05-15 11:44:35,210 ERROR [org.springframework.batch.core.step.AbstractStep] &lt;taskExecutor-3&gt; - Encountered an error executing the step
  org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.processor': 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:192)
      at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:33)
      at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:182)
      at $Proxy14.process(Unknown Source)
      at org.springframework.batch.core.step.item.SimpleChunkProcessor.doProcess(SimpleChunkProcessor.java:125)
      at org.springframework.batch.core.step.item.SimpleChunkProcessor.transform(SimpleChunkProcessor.java:291)
      at org.springframework.batch.core.step.item.SimpleChunkProcessor.process(SimpleChunkProcessor.java:190)
      at org.springframework.batch.core.step.item.ChunkOrientedTasklet.execute(ChunkOrientedTasklet.java:74)
      at org.springframework.batch.core.step.tasklet.TaskletStep$ChunkTransactionCallback.doInTransaction(TaskletStep.java:386)
      at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:130)
      at org.springframework.batch.core.step.tasklet.TaskletStep$2.doInChunkContext(TaskletStep.java:264)
      at org.springframework.batch.core.scope.context.StepContextRepeatCallback.doInIteration(StepContextRepeatCallback.java:76)
      at org.springframework.batch.repeat.support.RepeatTemplate.getNextResult(RepeatTemplate.java:367)
      at org.springframework.batch.repeat.support.RepeatTemplate.executeInternal(RepeatTemplate.java:214)
      at org.springframework.batch.repeat.support.RepeatTemplate.iterate(RepeatTemplate.java:143)
      at org.springframework.batch.core.step.tasklet.TaskletStep.doExecute(TaskletStep.java:250)
      at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:195)
      at org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler$1.call(TaskExecutorPartitionHandler.java:120)
      at org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler$1.call(TaskExecutorPartitionHandler.java:118)
      at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334)
      at java.util.concurrent.FutureTask.run(FutureTask.java:166)
      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
      at java.lang.Thread.run(Thread.java:722)
  Caused by: java.lang.IllegalStateException: No context holder available for step scope
      at org.springframework.batch.core.scope.StepScope.getContext(StepScope.java:197)
      at org.springframework.batch.core.scope.StepScope.get(StepScope.java:139)
      at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:327)
      ... 24 more
  </code></pre>
  
  <p>Is there a way to get the current input file name from the processor of a partitioned job?  </p>
  
  <p>Here is the relevant config:</p>
  
  <pre><code>&lt;batch:job id="acct"&gt;
      &lt;batch:step id="init" parent="abstractStep" next="processStep"&gt;
          &lt;batch:tasklet ref="fileDeleteTasklet" /&gt;
      &lt;/batch:step&gt;
      &lt;batch:step id="processStep"&gt;
          &lt;batch:partition step="processInput" partitioner="partitioner"&gt;
              &lt;batch:handler grid-size="2" task-executor="taskExecutor" /&gt;
          &lt;/batch:partition&gt;
      &lt;/batch:step&gt;
  &lt;/batch:job&gt;
  
  &lt;batch:step id="processInput"&gt;
      &lt;batch:tasklet&gt;
          &lt;batch:chunk reader="reader" processor="processor" writer="writer" commit-interval="3"&gt;
              &lt;batch:streams&gt;
                  &lt;batch:stream ref="reader"/&gt;
                  &lt;batch:stream ref="flatFileItemWriter"/&gt;
              &lt;/batch:streams&gt;
          &lt;/batch:chunk&gt;
      &lt;/batch:tasklet&gt;
  &lt;/batch:step&gt;
  
  &lt;bean id="partitioner" class="org.springframework.batch.core.partition.support.MultiResourcePartitioner" scope="step"&gt;
      &lt;property name="keyName" value="fileName"/&gt;
      &lt;property name="resources" value="file:#{jobParameters['inputFilePattern']}"/&gt;
  &lt;/bean&gt;
  
  &lt;bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"&gt;
      &lt;property name="corePoolSize" value="5"/&gt;
      &lt;property name="maxPoolSize" value="5"/&gt;
  &lt;/bean&gt;
  
  &lt;bean id="reader" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step"&gt;
      &lt;property name="resource" value="#{stepExecutionContext[fileName]}" /&gt; 
      &lt;property name="lineMapper"&gt;
          &lt;bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper"&gt;
              &lt;property name="lineTokenizer"&gt;
                  &lt;bean class="org.springframework.batch.item.file.transform.FixedLengthTokenizer"&gt;
                      &lt;property name="names" value="recordType,reserved,aCode,bCode,acctNumber,idType,cCode" /&gt;
                      &lt;property name="columns" value="1,2,3-6,7-9,10-15,16,17-19" /&gt;
                      &lt;property name="strict" value="false" /&gt;
                  &lt;/bean&gt;
              &lt;/property&gt;
              &lt;property name="fieldSetMapper"&gt;
                  &lt;bean class="com.example.batch.acct.AcctInputFieldSetMapper" /&gt;
              &lt;/property&gt;
          &lt;/bean&gt;
      &lt;/property&gt;
  &lt;/bean&gt;
  
  &lt;bean id="processor" class="com.example.batch.acct.AcctProcessor" scope="step"&gt;
      &lt;property name="soapClient"  ref="soapClient" /&gt;
      &lt;property name="maxNumIds"   value="${batch.soap.numberOfIds}" /&gt;
      &lt;aop:scoped-proxy /&gt;
  &lt;/bean&gt;
  </code></pre>