Hi,
Based on the PartitionStep example, I'm now trying to set up a partitionstep that should execute a flow containing 3 steps.
For every file in a given directory, this should perform the following:
- do some processing on the file
- depending on the result of 1) call one of two clean up steps (move to error/move to succes).
The job and step definitions look like this:
Code:
<b:job id="partitionJob">
<b:step id="processAllBanstas" parent="bansta:master" />
</b:job>
<!-- master step for partitioning: pick all files in partitionTest/ subdirectory. -->
<bean name="bansta:master" class="org.springframework.batch.core.partition.support.PartitionStep">
<property name="jobRepository" ref="jobRepository" />
<!-- how to split: one step per file in input directory. -->
<property name="stepExecutionSplitter">
<bean class="org.springframework.batch.core.partition.support.SimpleStepExecutionSplitter">
<constructor-arg ref="jobRepository" />
<constructor-arg ref="completeStep" />
<constructor-arg>
<bean class="....rcm.partitioner.MultiFileResourcePartitioner">
<property name="resources" value="partitionTest/*" />
</bean>
</constructor-arg>
</bean>
</property>
<!-- partition handler: how to handle the separate partitions -->
<property name="partitionHandler">
<bean class="org.springframework.batch.core.partition.support.TaskExecutorPartitionHandler">
<property name="taskExecutor">
<bean class="org.springframework.core.task.SyncTaskExecutor" />
<!--
<bean class="org.springframework.core.task.SimpleAsyncTaskExecutor"></bean>
-->
</property>
<property name="step" ref="completeStep" />
</bean>
</property>
</bean>
So the PartitionStep is partitioning a FlowStep which is defined as follows:
Code:
<bean id="completeStep" class="org.springframework.batch.core.job.flow.FlowStep">
<property name="flow" ref="processOneFile"/>
<property name="jobRepository" ref="jobRepository" />
</bean>
<b:flow id="processOneFile">
<b:step id="banstaProcessing" >
<b:tasklet>
<b:chunk reader="segmentgroupreader" processor="segmentGroupProcessor" writer="segmentGroupWriter" commit-interval="1"/>
</b:tasklet>
<b:next on="FAILED" to="failure"/>
<b:next on="*" to="success"/>
</b:step>
<b:step id="success">
<b:tasklet ref="successMover"/>
</b:step>
<b:step id="failure">
<b:tasklet ref="errorMover" />
</b:step>
</b:flow>
The segmentgroupreader and ***mover tasklets are set up with step scope:
Code:
<!-- set up flat file reader which passes through fieldsets -->
<bean id="delegateReader" class="org.springframework.batch.item.file.FlatFileItemReader" autowire-candidate="false" scope="step">
<property name="lineMapper" ref="mapper" />
<property name="recordSeparatorPolicy" ref="policy" />
<property name="resource" value="#{stepExecutionContext[fileName]}" />
<property name="bufferedReaderFactory">
<bean class="org.springframework.batch.item.file.SimpleBinaryBufferedReaderFactory">
<property name="lineEnding" value="'" />
</bean>
</property>
</bean>
<!-- set up BanstaSegmentGroupReader which uses this as a delegate -->
<bean id="segmentgroupreader" class="....rcm.reader.BanstaSegmentGroupReader" autowire-candidate="false" scope="step">
<property name="delegateItemreader" ref="delegateReader" />
</bean>
<bean id="successMover" class="....rcm.tasklet.ResourceLogTasklet" scope="step">
<property name="targetDirectory" value="successDirectory"/>
<property name="fileToMove" value="#{stepExecutionContext[fileName]}" />
</bean>
<bean id="errorMover" class="....rcm.tasklet.ResourceLogTasklet" scope="step">
<property name="targetDirectory" value="errorDirectory"/>
<property name="fileToMove" value="#{stepExecutionContext[fileName]}" />
</bean>
However when I run this, it fails, complaining that it can't open the reader. I'm pretty sure that this has something to do with the
addition of the flow, as this was running fine inside a PartitionStep by itself (exact same reader definitions). So the difference is
the fact that it's now wrapped in a FlowStep which is inside a PartitionStep.
I've been googling for answers, read the reference manual, and looked at the samples in the distribution but I don't see this particular
setup, and I don't see any (obvious) errors in this configuration. Does anybody have an idea on how to get this to work?
Here is (part of) the stacktrace:
Code:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'lazyBindingProxy.delegateReader#sysinit' defined in class path resource [partitionedFlowJob.xml]: Initialization of bean failed; nested exception is java.lang.IllegalStateException: Cannot bind to placeholder: stepExecutionContext[fileName]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:480)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
at java.security.AccessController.doPrivileged(Native Method)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
at org.springframework.beans.factory.support.AbstractBeanFactory$2.getObject(AbstractBeanFactory.java:302)
at org.springframework.batch.core.scope.StepScope.get(StepScope.java:150)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
at org.springframework.batch.core.scope.util.PlaceholderTargetSource.getTarget(PlaceholderTargetSource.java:185)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:184)
at $Proxy3.open(Unknown Source)
at ....rcm.reader.BanstaSegmentGroupReader.open(BanstaSegmentGroupReader.java:110)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
...
Caused by: java.lang.IllegalStateException: Cannot bind to placeholder: stepExecutionContext[fileName]
at org.springframework.batch.core.scope.util.PlaceholderTargetSource$1.convertIfNecessary(PlaceholderTargetSource.java:140)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1294)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1250)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1010)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:472)
... 76 more
2010-04-20 15:45:45,464 ERROR [org.springframework.batch.core.step.AbstractStep] - <Exception while closing step execution resources>
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'lazyBindingProxy.delegateReader#sysinit' defined in class path resource [partitionedFlowJob.xml]: Initialization of bean failed; nested exception is java.lang.IllegalStateException: Cannot bind to placeholder: stepExecutionContext[fileName]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:480)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory$1.run(AbstractAutowireCapableBeanFactory.java:409)
at java.security.AccessController.doPrivileged(Native Method)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:380)
at org.springframework.beans.factory.support.AbstractBeanFactory$2.getObject(AbstractBeanFactory.java:302)
at org.springframework.batch.core.scope.StepScope.get(StepScope.java:150)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:185)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:164)
at org.springframework.batch.core.scope.util.PlaceholderTargetSource.getTarget(PlaceholderTargetSource.java:185)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:184)
at $Proxy3.close(Unknown Source)
at ....rcm.reader.BanstaSegmentGroupReader.close(BanstaSegmentGroupReader.java:101)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
Sorry for the long post, I'm trying to provide all relevant information here...