2013-05-15 23 views
5

için adım adım içeriğe geçme Bir MultiResourcePartitioner kullanarak birden çok giriş dosyasını paralel olarak işleyen bir Spring Batch iş geliştiriyorum. ItemProcessor'da mevcut giriş dosyasındaki kayıt sayısını almam gerekir. Ben adım bağlamdan mevcut dosya adını almak ve dosyadaki satır sayısını okumak:Spring Batch: Bölümlenmiş adım

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")); 

tüm görünüyor bu işe ama işlemci parçacığı adım bağlamı erişirken İstisna alıyorum:

2013-05-15 11:44:35,178 DEBUG [org.springframework.batch.core.step.tasklet.TaskletStep] <taskExecutor-3> - 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] <taskExecutor-3> - Returning JDBC Connection to DataSource 
2013-05-15 11:44:35,194 DEBUG [org.springframework.batch.repeat.support.RepeatTemplate] <taskExecutor-3> - 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] <taskExecutor-3> - 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] <taskExecutor-3> - 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 

Geçerli girdi dosyası adını bölümlenmiş bir işin işlemcisinden almanın bir yolu var mı?

<batch:job id="acct"> 
    <batch:step id="init" parent="abstractStep" next="processStep"> 
     <batch:tasklet ref="fileDeleteTasklet" /> 
    </batch:step> 
    <batch:step id="processStep"> 
     <batch:partition step="processInput" partitioner="partitioner"> 
      <batch:handler grid-size="2" task-executor="taskExecutor" /> 
     </batch:partition> 
    </batch:step> 
</batch:job> 

<batch:step id="processInput"> 
    <batch:tasklet> 
     <batch:chunk reader="reader" processor="processor" writer="writer" commit-interval="3"> 
      <batch:streams> 
       <batch:stream ref="reader"/> 
       <batch:stream ref="flatFileItemWriter"/> 
      </batch:streams> 
     </batch:chunk> 
    </batch:tasklet> 
</batch:step> 

<bean id="partitioner" class="org.springframework.batch.core.partition.support.MultiResourcePartitioner" scope="step"> 
    <property name="keyName" value="fileName"/> 
    <property name="resources" value="file:#{jobParameters['inputFilePattern']}"/> 
</bean> 

<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> 
    <property name="corePoolSize" value="5"/> 
    <property name="maxPoolSize" value="5"/> 
</bean> 

<bean id="reader" class="org.springframework.batch.item.file.FlatFileItemReader" scope="step"> 
    <property name="resource" value="#{stepExecutionContext[fileName]}" /> 
    <property name="lineMapper"> 
     <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper"> 
      <property name="lineTokenizer"> 
       <bean class="org.springframework.batch.item.file.transform.FixedLengthTokenizer"> 
        <property name="names" value="recordType,reserved,aCode,bCode,acctNumber,idType,cCode" /> 
        <property name="columns" value="1,2,3-6,7-9,10-15,16,17-19" /> 
        <property name="strict" value="false" /> 
       </bean> 
      </property> 
      <property name="fieldSetMapper"> 
       <bean class="com.example.batch.acct.AcctInputFieldSetMapper" /> 
      </property> 
     </bean> 
    </property> 
</bean> 

<bean id="processor" class="com.example.batch.acct.AcctProcessor" scope="step"> 
    <property name="soapClient" ref="soapClient" /> 
    <property name="maxNumIds" value="${batch.soap.numberOfIds}" /> 
    <aop:scoped-proxy /> 
</bean> 
+0

türünde bir Spring ve Spring Batch sürümünü kullanıyor musunuz? – Cygnusx1

+0

Spring 3.0.6 ve Spring Batch 2.1.9 kullanıyorum. – iguanodon

cevap

1

Spring Batch forum üzerine Yanıtlanmış: kendiniz enjekte gerekir böylece

ItemProcessor arayüzü, StepContext erişmek için bir yol göstermiyor İşte

ilgili yapılandırma geçerli:

<bean id="itemProcessor" class="com.myApp.MyItemProcessor" scope="step"> 
    <property name="stepContext" value="#{stepExecutionContext}"/> 
</bean> 

Pro küratör sınıfı, stepContext adlı açıkta bulunan bir özelliğe sahiptir.

-Michael Minella, stepContexorg.springframework.batch.core.scope.context.StepContext türüdür Bu durumda Spring Batch Lead

+1

Cevabınızı kabul etmek isteyebilirsiniz. Http://stackoverflow.com/help/self-answer adresini okuyun – falsarella

0
<bean id="itemProcessor" class="com.myApp.MyItemProcessor" scope="step"> 
    <property name="stepContext" value="#{stepExecutionContext}"/> 
</bean> 

, nasıl, ben bu özelliğin adı alıyorum önerir istisnalar:

org .springframework.beans.factory.BeanCreationException: adında adı ile fasulye oluşturma hatası pedTarget.itemProcessor ' sınıf yolu kaynağında tanımlandı [META-INF/jobs/Job.xml]: Çekirdeğin başlatılması başarısız oldu; İç içe istisna org.springframework.beans.ConversionNotSupportedException geçerli: Çeşidi dönüştürmek mülk değerine 'java.util.Collections $ UnmodifiableMap' gerekli tipine 'org.springframework.batch.core.scope.context.StepContext' için başarısız oldu özelliği 'stepContext'; İç içe istisna java.lang.IllegalStateException geçerli: özelliği için 'org.springframework.batch.core.scope.context.StepContext' Gerekli tipine tip 'java.util.Collections $ UnmodifiableMap' değerini dönüştürülemez 'stepContext' :

bulundu eşleşen editörler veya dönüştürme stratejisi ben ItemProcessor içeride jobExecutionId erişmek için gereken, bu yüzden bu yapılandırmayı değişti:

<bean id="itemProcessor" class="com.myApp.MyItemProcessor" scope="step"> 
    <property name="stepExecution" value="#{stepExecution}"/> 
</bean> 

Mülkiyet "stepExecution", org.springframework.batch.core.StepExecution

İlgili konular