StaxEventItemWriter - 文件不可写问题

时间:2013-07-19 08:32:39

标签: java spring spring-batch

我有一个如下配置的项目编写器,它生成一个xml:

<beans:bean id="delegateItemWriter" class="org.springframework.batch.item.xml.StaxEventItemWriter" scope="step">
    <beans:property name="resource" value="file:#{jobParameters['OutputDirPath']}${myFileName}" /> 
    <beans:property name="overwriteOutput" value="true"/>
    <beans:property name="rootTagName" value="disclosure-feed" />
    <beans:property name="rootElementAttributes" >
        <beans:map>
            <beans:entry key="xmlns:xsi" value="http://www.w3.org/2001/XMLSchema-instance" />               
            <beans:entry key="xsi:noNamespaceSchemaLocation" value="XYZ.xsd"/>
        </beans:map>
    </beans:property>
    <beans:property name="marshaller" ref="xmlMarshaller" />  
</beans:bean>

即使每件事情看起来都是正确的,有时在修复上次运行失败后重新启动作业时,我会收到以下错误:

2013-07-19 02:14:34,921 [main] ERROR org.springframework.batch.core.step.AbstractStep  - Encountered an error executing the step
org.springframework.batch.item.ItemStreamException: File is not writable: [/myOutputDir/myOutput.xml]

当我从batch_ tables手动删除作业条目,以便作业从开始时重新开始,而不是从上次运行期间失败的位置开始,文件按预期生成。

这个问题的原因是什么? 怎么解决?是否有一些我缺少的配置?

感谢阅读!

3 个答案:

答案 0 :(得分:2)

看起来像org.springframework.batch.item.utilFileUtils.java中的一个错误,Spring批处理期望第一次运行时已经创建了该文件。

   if (!restarted) {
                if (file.exists()) {
                   ...
                }
                if (file.getParent() != null) {
                    new File(file.getParent()).mkdirs();
                }
                file.createNewFile();
   }

   if (!file.canWrite()) {
            throw new ItemStreamException("File is not writable...");
   }

如果是重启,则不会创建任何文件,因此您将获得异常。

答案 1 :(得分:0)

我遇到了同样的问题。我在Java Config类中创建了一个新文件来解决该问题。现在,无论何时执行Job,初始化配置时都会创建一个新文件。因此,在重新启动时,该文件也已创建。

FlatFileItemWriter<List<String>>  flatFileWriter= new FlatFileItemWriter<>();
DelimitedLineAggregator<List<String>> delimittedLineAggregator = new DelimitedLineAggregator<>();
delimittedLineAggregator.setDelimiter(System.lineSeparator());
Resource res = new FileSystemResource(file);
res.getFile().createNewFile();
flatFileWriter.setResource(res);

在为用例创建新文件时没有看到任何问题。

答案 2 :(得分:-1)

请在定义作业时调用jobBuilderFactory上的preventRestart()方法。每次作业运行时,重启属性都是正确的。因此,它期待文件存在。