I have the below definition for FlatFileItemReader
in s simple spring batch job:
@Bean
public FlatFileItemReader<BookingInfo> bookingInfoReader() {
FlatFileItemReader<BookingInfo> itemReader = new FlatFileItemReader<>();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
BlobClient blobClient =
blobContainerClient.getBlobClient("path/file.csv");
blobClient.downloadStream(outputStream);
final byte[] bytes = outputStream.toByteArray();
ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
InputStreamResource resource = new InputStreamResource(inputStream);
itemReader.setResource(resource);
itemReader.setName("csvReader");
itemReader.setLinesToSkip(1);
itemReader.setLineMapper(lineMapper());
return itemReader;
}
But I get the error:
java.lang.IllegalStateException: InputStream has already been read - do not use InputStreamResource if a stream needs to be read multiple times
Now, I changed the above code to use ByteArrayResource
as shown below:
@Bean
public FlatFileItemReader<BookingInfo> bookingInfoReader {
FlatFileItemReader<BookingInfo> itemReader = new FlatFileItemReader<>();
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
BlobClient blobClient =
blobContainerClient.getBlobClient("path/file.csv");
blobClient.downloadStream(outputStream);
final byte[] bytes = outputStream.toByteArray();
ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
ByteArrayResource byteArrayResource = new ByteArrayResource(inputStream.readAllBytes());
itemReader.setResource(byteArrayResource);
itemReader.setName("csvReader");
itemReader.setLinesToSkip(1);
itemReader.setLineMapper(lineMapper());
return itemReader;
}
Now the mentioned error goes away. However, there is a strange issue. Even if I update the file content, it is not fetching dynamically when the job is triggered. Instead, it is using the same old content. It takes modified content only after pod restart. I believe it is due to the fact that reader bean is created once and using it everytime.
So, I need to go back to InputStreamResource
implementation by fixing the earlier mentioned issue. What is going wrong here?
I believe it is due to the fact that reader bean is created once and using it everytime.
Yes, the scope of the reader bean definition that you shared is singleton. Therefore, the same instance will be used for entire app lifetime and the file content will be the same.
You should make the reader step-scoped by adding @StepScope
on its bean definition method to create a new instance on each run.