Java Reference
In-Depth Information
What went wrong? All you really did was swap out the
CompositeItemWriter
you used in the previous
section with the new
ClassifierCompositeItemWriter
. The issue centers around the
ItemStream
interface.
The ItemStream Interface
The
ItemStream
interface serves as the contract to be able to periodically store and restore state.
Consisting of three methods,
open
,
update
, and
close
, the
ItemStream
interface is implemented by any
stateful ItemReader or ItemWriter. In cases, for example, where a file is involved in the input or output,
the
open
method opens the required file, and the
close
method closes the required file. The
update
method records the current state (number of records written, and so on) as each chunk is completed.
The reason for the difference between
CompositeItemWriter
and
ClassifierCompositeItemWriter
is
that
CompositeItemWriter
implements the
org.springframework.batch.item.ItemStream
interface. In
CompositeItemWriter
, the
open
method loops through the delegate ItemWriters and calls the
open
method on each of them as required. The
close
and
update
methods work the same way. However,
ClassifierCompositeItemWriter
doesn't implement the
ItemStream
method. Because of this, the XML
file is never opened or
XMLEventFactory
(or the underlying XML writing) created, throwing the exception
shown in Listing 9-79.
How do you fix this error? Spring Batch provides the ability to register
ItemStream
s to be handled in
a step manually. If an ItemReader or ItemWriter implements
ItemStream
, the methods are handled for
you. If they don't (as in the case of
ClassifierCompositeItemWriter
), you're required to register the
ItemReader or ItemWriter as a stream to be able to work with it if it maintains state. Listing 9-80 shows
the updated configuration for the job, registering the
xmlOutputWriter
as an ItemStream.
6
Listing 9-80.
Updated Configuration Registering the Appropriate
ItemStream
for Processing
...
<step id="formatFileStep">
<tasklet>
<chunk reader="customerFileReader" writer="classifierWriter"
commit-interval="10">
<streams>
<stream ref="xmlOutputWriter"/>
</streams>
</chunk>
</tasklet>
</step>
<job id="formatJob">
<step id="step1" parent="formatFileStep"/>
</job>
…
If you rebuild and rerun the job with the updated configuration, you see that all the records are
processed as expected.
6
You only need to register the
xmlOutputWriter
as a stream.
JdbcBatchItemWriter
doesn't implement the
ItemStream
interface because it doesn't maintain any state.