I've used FlatFileItemReader
with the Classifier
and ClassifierCompositeItemWriter
in my project where we read Tab delimited file and convert it into CSV as a output file by performing some validation, enrichment etc process and create four output file which the logic written onto the Classifier
implementation. So I am reading FlatFile and also creating another FlatFile.
Below us the snippet code
<bean id="classifier" class="com.XXXXXXXXX.SomeClassifier">
<constructor-arg index="0" ref="oneMultiResource"/>
<constructor-arg index="1" ref="twoMultiResource"/>
<constructor-arg index="2" ref="threeMultiResource"/>
<constructor-arg index="3" ref="fourMultiResource"/>
</bean>
<bean id="classifierCompositeItemWriter" class="org.springframework.batch.item.support.ClassifierCompositeItemWriter">
<property name="classifier" ref="classifier"/>
</bean>
<bean id="onetCvsWriter" class="org.springframework.batch.item.file.FlatFileItemWriter" scope="step" >
<property name="resource" value="file:${XXXXXXXXXXXXXXXXX}.#{jobParameters['year']}"/>
<property name="shouldDeleteIfExists" value="true"/>
<property name="shouldDeleteIfEmpty" value="true" />
<property name="appendAllowed" value="true" />
<property name="encoding" value="UTF-8"/>
<property name="lineAggregator" ref="abLineAggregator"/>
<property name="headerCallback" ref="headerCallback" />
</bean>
<bean id="oneMultiResource" class="org.springframework.batch.item.file.MultiResourceItemWriter" scope="step">
<property name="name" value="MultiResourceWriter" />
<property name="delegate" ref="onetCvsWriter" />
<property name="resource" value="file:${XXXXXXXXXXXXXXXXX}.#{jobParameters['year']}" />
<property name="itemCountLimitPerResource" value="500000" />
<property name="resourceSuffixCreator" ref="suffixCreator" />
</bean>
Error:
org.springframework.batch.item.WriterNotOpenException: Writer must be open before it can be written to
at org.springframework.batch.item.file.FlatFileItemWriter.write(FlatFileItemWriter.java:236) ~[spring-batch-infrastructure-2.1.8.RELEASE.jar:?]
at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) ~[?:?]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_202]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_202]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.21.jar:5.3.21]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) ~[spring-aop-5.3.21.jar:5.3.21]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.21.jar:5.3.21]
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:137) ~[spring-aop-5.3.21.jar:5.3.21]
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124) ~[spring-aop-5.3.21.jar:5.3.21]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.21.jar:5.3.21]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.21.jar:5.3.21]
at com.sun.proxy.$Proxy56.write(Unknown Source) ~[?:?]
at org.springframework.batch.item.file.MultiResourceItemWriter.write(MultiResourceItemWriter.java:82) ~[spring-batch-infrastructure-2.1.8.RELEASE.jar:?]
at sun.reflect.GeneratedMethodAccessor16.invoke(Unknown Source) ~[?:?]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_202]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_202]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.3.21.jar:5.3.21]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) ~[spring-aop-5.3.21.jar:5.3.21]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.3.21.jar:5.3.21]
at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:137) ~[spring-aop-5.3.21.jar:5.3.21]
at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:124) ~[spring-aop-5.3.21.jar:5.3.21]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.3.21.jar:5.3.21]
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:215) ~[spring-aop-5.3.21.jar:5.3.21]
at com.sun.proxy.$Proxy54.write(Unknown Source) ~[?:?]
As per suggestion from here: FlatFileItemWriter - Writer must be open before it can be written to, how can we call in below in XML configurations?
itemWriter.open(new ExecutionContext());
The FlatFileItemWriter
is not thread-safe as mentioned in its Javadocs, and therefore should not be used as such in a multi-threaded step. You can try to wrap it in a SynchronizedItemStreamWriter
.