Spring Batch: java.io.IOException: exception de flux fermé lors de la combinaison de MultiResourceItemWriter et de FlatFileItemWriter

StackOverflow https://stackoverflow.com/questions/1804042

  •  05-07-2019
  •  | 
  •  

Question

J'ai un processus Spring Batch qui prend un ensemble de lignes dans la base de données et crée un certain nombre de fichiers plats à partir de ces lignes, 10 lignes par fichier. Pour ce faire, j'ai créé un processus Spring Batch, similaire à celui-ci:

<batch:job id="springTest" job-repository="jobRepository" restartable="true">
    <batch:step id="test">
        <batch:tasklet>
            <batch:chunk reader="itemReader" writer="multipleItemWriter" commit-interval="2" />
        </batch:tasklet>
    </batch:step>
</batch:job>

<bean id="itemReader" class="org.springframework.batch.item.file.FlatFileItemReader">
    <property name="resource" value="file:/temp/temp-input.txt" />
    <property name="lineMapper">
        <bean class="org.springframework.batch.item.file.mapping.PassThroughLineMapper" />
    </property>
</bean>

<bean id="multipleItemWriter" class="org.springframework.batch.item.file.MultiResourceItemWriter">
    <property name="resource" value="file:/temp/temp-out" />
    <property name="itemCountLimitPerResource" value="2" />
    <property name="delegate">
        <bean id="itemWriter" class="org.springframework.batch.item.file.FlatFileItemWriter">
            <property name="lineAggregator">
              <bean class="org.springframework.batch.item.file.transform.PassThroughLineAggregator" />
            </property>
            <property name="encoding" value="utf-8" />
            <property name="headerCallback" ref="headerFooter" />
            <property name="footerCallback" ref="headerFooter" />
        </bean>
   </property>
</bean>

<bean id="headerFooter" class="uk.co.farwell.spring.HeaderFooterCallback" />

L'exemple ci-dessus lit à partir d'un fichier plat et est exporté dans un fichier plat (pour montrer le problème). Notez que commit-interval = 2 dans le bloc et itemCountLimitPerResource = 2 dans MultiResourceItemWriter.

HeaderFooterCallback effectue les opérations suivantes:

public void writeHeader(Writer writer) throws IOException {
    writer.write("file header\n");
}

public void writeFooter(Writer writer) throws IOException {
    writer.write("file footer\n");
}

Je dois pouvoir spécifier exactement le nombre de lignes qui apparaissent dans le fichier.

Pour le fichier d'entrée suivant:

foo1
foo2
foo3

Je m'attendrais à deux fichiers en sortie,

out.1:

file header
foo1
foo2
file footer

out.2:

file header
foo3
file footer

Lorsque j'exécute avec commit-interval = 2, j'obtiens une exception:

2009-11-26 15:32:46,734 ERROR .support.TransactionSynchronizationUtils - TransactionSynchronization.afterCompletion threw exception
org.springframework.batch.support.transaction.FlushFailedException: Could not write to output buffer
    at org.springframework.batch.support.transaction.TransactionAwareBufferedWriter$1.afterCompletion(TransactionAwareBufferedWriter.java:71)
    at org.springframework.transaction.support.TransactionSynchronizationUtils.invokeAfterCompletion(TransactionSynchronizationUtils.java:157)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.invokeAfterCompletion(AbstractPlatformTransactionManager.java:974)
    .
    .
    .
Caused by: java.io.IOException: Stream closed
    at sun.nio.cs.StreamEncoder.ensureOpen(Unknown Source)
    at sun.nio.cs.StreamEncoder.write(Unknown Source)
    at sun.nio.cs.StreamEncoder.write(Unknown Source)
    at java.io.Writer.write(Unknown Source)
    at org.springframework.batch.support.transaction.TransactionAwareBufferedWriter$1.afterCompletion(TransactionAwareBufferedWriter.java:67).

Je pense que c'est un bug. Bizarrement, les fichiers sont les suivants:

out.1:

file header
foo1
foo2

out.2:

file footer

Si le fichier d'entrée contient deux lignes, tout fonctionne correctement, mais plus de deux ne fonctionnent pas. Si je modifie l'intervalle de validation à 200, le fichier contient trois lignes, ce qui n'est pas le comportement souhaité.

Si quelqu'un pouvait me dire si je fais quelque chose de mal ou sinon comment résoudre le problème, je vous en serais très reconnaissant.

Était-ce utile?

La solution

En fait, c'est un bug. Voir http://jira.springframework.org/browse/BATCH-1452 . / p>

La solution de contournement, selon Dave Syer , est la suivante:

  

L'exception IOException est méchante. Une partielle   La solution consiste à utiliser le nouveau   propriété transactionnelle dans   FlatFileItemWriter, en le définissant à   faux (BATCH-1449). Mais alors tu perds   possibilité de redémarrage (donc si ce n'est pas un   vous êtes prêt à partir). j'essaierai   et corrigez-le correctement pour 2.1.

     

Une autre solution consiste à poster un processus   les fichiers dans une étape séparée (et non   utilisez les rappels d’en-tête / pied de page).

     

Le problème de comptage (plus de 2 éléments   par fichier) est vraiment séparé - le   écrivain multi-ressources n'a jamais été   conçu pour garantir la précision   nombre d'éléments par fichier, uniquement pour   débordement si la limite est dépassée.   Vous pouvez ouvrir une JIRA pour une amélioration   si vous voulez, une solution consiste à utiliser   commit-interval = " 2 " dans votre exemple   (ou plus généralement un facteur de   taille de fichier souhaitée).

Autres conseils

Tenez compte du fait que vous essayez de lire les données de la base de données et de les écrire dans un fichier. Dans ce scénario, lorsque vous écrivez les données dans un fichier, vous devez utiliser un objet dans "HeaderFooterCallback". fichier. comment faites-vous cela?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top