简体   繁体   中英

Spring batch doesn't seem to be closing item writers properly

I have a job that writes each item in one separated file. In order to do this, the job uses a ClassifierCompositeItemWriter whose the ClassifierCompositeItemWriter returns a new FlatFileItemWriter for each item (code bellow).

    @Bean
    @StepScope
    public ClassifierCompositeItemWriter<ProcessorResult> writer(@Value("#{jobParameters['outputPath']}") String outputPath) {

        ClassifierCompositeItemWriter<MyItem> compositeItemWriter = new ClassifierCompositeItemWriter<>();
        
        compositeItemWriter.setClassifier((item) -> {
            
            String filePath = outputPath + "/" + item.getFileName();
            
            BeanWrapperFieldExtractor<MyItem> fieldExtractor = new BeanWrapperFieldExtractor<>();
            fieldExtractor.setNames(new String[]{"content"});
            
            DelimitedLineAggregator<MyItem> lineAggregator = new DelimitedLineAggregator<>();
            lineAggregator.setFieldExtractor(fieldExtractor);

            FlatFileItemWriter<MyItem> itemWriter = new FlatFileItemWriter<>();
            itemWriter.setResource(new FileSystemResource(filePath));
            itemWriter.setLineAggregator(lineAggregator);
            itemWriter.setShouldDeleteIfEmpty(true);
            itemWriter.setShouldDeleteIfExists(true);

            itemWriter.open(new ExecutionContext());
            return itemWriter;
            
        });
        
        return compositeItemWriter;

    }

Here's how the job is configured:

    @Bean
    public Step step1() {
        return stepBuilderFactory
                .get("step1")
                .<String, MyItem>chunk(1)
                .reader(reader(null))
                .processor(processor(null, null, null))
                .writer(writer(null))
                .build();
    }

    @Bean
    public Job job() {
        return jobBuilderFactory
                .get("job")
                .incrementer(new RunIdIncrementer())
                .flow(step1())
                .end()
                .build();
    }

Everything works perfectly. All the files are generated as I expected. However, one of the file cannot be deleted. Just one. If I try to delete it, I get a message saying that "OpenJDK Platform binary" is using it. If I increase the chunk to a size bigger that the amount of files I'm generating, none of the files can be deleted. Seems like there's an issue to delete the files generated in the last chunk, like if the respective writer is not being closed properly by the Spring Batch lifecycle or something.

If I kill the application process, I can delete the file.

Any I idea why this could be happening? Thanks in advance!

PS: I'm calling this "itemWriter.open(new ExecutionContext());" because if I don't, I get a "org.springframework.batch.item.WriterNotOpenException: Writer must be open before it can be written to".

EDIT:

If someone is facing a similar problem, I suggest reading the Mahmoud's answer to this question Spring batch: ClassifierCompositeItemWriter footer not getting called .

Probably you are using the itemwriter outside of the step scope when doing this:

 itemWriter.open(new ExecutionContext());

Please check this question , hope that this helps you.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM