I’ve a SpringBatch Job where I skip all duplicate items write to a Flat file.
However the FlatFileItemWriter throws the below error whenever there’s a duplicate:
Writer must be open before it can be written to
Below is the Writer & SkipListener configuration –
@Bean(name = "duplicateItemWriter") public FlatFileItemWriter<InventoryFileItem> dupItemWriter(){ return new FlatFileItemWriterBuilder<InventoryFileItem>() .name("duplicateItemWriter") .resource(new FileSystemResource("duplicateItem.txt")) .lineAggregator(new PassThroughLineAggregator<>()) .append(true) .shouldDeleteIfExists(true) .build(); } public class StepSkipListener implements SkipListener<InventoryFileItem, InventoryItem> { private FlatFileItemWriter<InventoryFileItem> skippedItemsWriter; public StepSkipListener(FlatFileItemWriter<InventoryFileItem> skippedItemsWriter) { this.skippedItemsWriter = skippedItemsWriter; } @Override public void onSkipInProcess(InventoryFileItem item, Throwable t) { System.out.println(item.getBibNum() + " Process - " + t.getMessage()); try { skippedItemsWriter.write(Collections.singletonList(item)); } catch (Exception e) { System.out.println(e.getMessage()); } }
The overall Job is defined as below and I’m using the duplicateItemWriter from the SkipListener.
@Bean(name = "fileLoadJob") @Autowired public Job fileLoadJob(JobBuilderFactory jobs, StepBuilderFactory steps, FlatFileItemReader<inventoryFileItem> fileItemReader, CompositeItemProcessor compositeItemProcessor, @Qualifier(value = "itemWriter") ItemWriter<InventoryItem> itemWriter, StepSkipListener skipListener) { return jobs.get("libraryFileLoadJob") .start(steps.get("step").<InventoryFileItem, InventoryItem>chunk(chunkSize) .reader(FileItemReader) .processor(compositeItemProcessor) .writer(itemWriter) .faultTolerant() .skip(Exception.class) .skipLimit(Integer.parseInt(skipLimit)) .listener(skipListener) .build()) .build(); }
I’ve also tried to write all data to FlatFileItemWriter – that doesn’t work as well. However if write to a DB, then there’s no issue with it.
The Spring-Batch version I’m using is – 4.3.3 I’ve referred to the below threads as well:
- unit testing a FlatFileItemWriter outside of Spring – “Writer must be open before it can be written to” exception
- Spring Batch WriterNotOpenException
- FlatfileItemWriter with Compositewriter example
Advertisement
Answer
This was just gross oversight, I missed that the FlatFileItemWriter needs a stream. I’m somewhat disappointed to put up this question, but I’m posting the answer just in case it helps someone.
The solution was as simple as adding a stream(dupItemWriter)
to the Job Definition.
FlatfileItemWriter with Compositewriter example
@Bean(name = "fileLoadJob") @Autowired public Job fileLoadJob(JobBuilderFactory jobs, StepBuilderFactory steps, FlatFileItemReader<inventoryFileItem> fileItemReader, CompositeItemProcessor compositeItemProcessor, @Qualifier(value = "itemWriter") ItemWriter<InventoryItem> itemWriter, @Qualifier(value = "duplicateItemWriter")FlatFileItemWriter<InventoryFileItem> dupItemWriter, StepSkipListener skipListener) { return jobs.get("libraryFileLoadJob") .start(steps.get("step").<InventoryFileItem, InventoryItem>chunk(chunkSize) .reader(FileItemReader) .processor(compositeItemProcessor) .writer(itemWriter) .faultTolerant() .skip(Exception.class) .skipLimit(Integer.parseInt(skipLimit)) .listener(skipListener) .stream(dupItemWriter) .build()) .build(); }