現象
以下のようなbean定義をしたところエラーになり実行できなかった。
やろうとした事としては https://docs.spring.io/spring-batch/docs/current/reference/html/scalability.html#partitioning の、spring-batchのPartitioningを試している。partitioningの情報(fileName
)がstepExecutionContext
に入るため、beanを@StepScope
にしている。
@StepScope
@Bean
public ItemReader<String> itemReader(@Value("#{stepExecutionContext['fileName']}")
Resource resource) throws IOException {
エラー内容は以下のとおり。
org.springframework.batch.item.ReaderNotOpenException: Reader must be open before it can be read.
at org.springframework.batch.item.file.FlatFileItemReader.readLine(FlatFileItemReader.java:201) ~[spring-batch-infrastructure-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.batch.item.file.FlatFileItemReader.doRead(FlatFileItemReader.java:178) ~[spring-batch-infrastructure-4.2.1.RELEASE.jar:4.2.1.RELEASE]
対策
戻り値型のItemReader
をFlatFileItemReader
に変更する。または、この場合はItemStreamReader
でも良い。
@StepScope
@Bean
public FlatFileItemReader<String> itemReader(@Value("#{stepExecutionContext['fileName']}")
Resource resource) throws IOException {
理由
@StepScope
により戻り値をAOPでプロキシするため。
@StepScope
の中身を見るとproxyMode = ScopedProxyMode.TARGET_CLASS
であり、いま、戻り値型がItemReader
なのでこのインタフェースに対するプロキシが作られる。そして、このインタフェースには(ItemStream
の)open
は無いので、当然open
は呼ばれない。実際のインスタンスはFlatFileItemReader
でこれはopenせずにreadは出来ないため、Reader must be open before it can be read
という例外になる。そういわけで戻り値型をFlatFileItemReader
か、ItemStreamReader
に変えれば正常に動作する。