java - job - Spring Batch: org.springframework.batch.item.ReaderNotOpenException: el lector debe estar abierto antes de poder leerlo
spring batch job (7)
Creo que deberías aumentar el tamaño de tu fragmento en la clase de bean de proceso processPlayerStats (), es decir, de chunk (10) a chunk (100 / más puede ser).
Leí preguntas relacionadas con SO, pero las soluciones no funcionan para mí.
Obtengo la org.springframework.batch.item.ReaderNotOpenException: Reader must be open before it can be read
.
A continuación se muestra mi configuración:
@Bean
@StepScope
public ItemReader<Player> reader(@Value("#{jobParameters[inputZipfile]}") String inputZipfile) {
final String [] header = { .. this part omitted for brevity ... };
FlatFileItemReader<Player> reader = new FlatFileItemReader<Player>();
System.out.println("/t/t/t/t/t"+inputZipfile);
reader.setResource(new ClassPathResource(inputZipfile));
reader.setLineMapper(new DefaultLineMapper<Player>() {{
setLineTokenizer(new DelimitedLineTokenizer() {{
setNames( header );
}});
setFieldSetMapper(new BeanWrapperFieldSetMapper<Player>() {{
setTargetType(Player.class);
}});
}});
reader.setComments( header );
return reader;
}
@Bean
@StepScope
public ItemProcessor<Player, PlayersStats> processor(@Value("#{jobParameters[statType]}") String statType,
@Value("#{jobParameters[season]}") String season){
PlayersStatsProcessor psp = new PlayersStatsProcessor();
psp.setStatisticType( StatisticType.valueOf(statType) );
psp.setSeason( season );
return psp;
}
@Bean
@StepScope
public ItemWriter<PlayersStats> writer(){
return new CustomWriter();
}
@Bean
public Job generateStatisticsJob() {
return this.jobs.get("generateStatisticsJob")
.incrementer(new RunIdIncrementer())
.start(processPlayerStats())
//.end()
.build();
}
@Bean
public Step processPlayerStats() {
return this.steps.get("processPlayerStats")
.<Player, PlayersStats> chunk(10)
.reader(reader(null))
.processor(processor(null,null))
.writer(writer())
.build();
}
La variable inputZipFile está configurada correctamente y el archivo existe en la unidad. Verifiqué el código FlatFileItemReader y la excepción ReaderNotOpenException ocurre cuando el miembro lector de la clase de lector no está configurado. El miembro lector está configurado en el método doOpen. Parece que doOpen no se llama. La pregunta es ¿por qué?
Desde que colocó el lector en StepScope
, el tipo de retorno de bean debe ser el tipo de implementación FlatFileItemReader
:
@Bean
@StepScope
public FlatFileItemReader<Player> reader(@Value("#{jobParameters[inputZipfile]}") String inputZipfile) {
...
return reader;
}
Si especifica la interfaz, el proxy Spring solo tiene acceso a los métodos y anotaciones especificados en el ItemReader
la interfaz y le faltan anotaciones importantes. También hay una advertencia (con un error tipográfico) en los registros:
2015-05-07 10:40:22,733 WARN [main] org.springframework.batch.item.ItemReader is an interface. The implementing class will not be queried for annotation based listener configurations. If using @StepScope on a @Bean method, be sure to return the implementing class so listner annotations can be used.
2015-05-07 10:40:22,748 WARN [main] org.springframework.batch.item.ItemReader is an interface. The implementing class will not be queried for annotation based listener configurations. If using @StepScope on a @Bean method, be sure to return the implementing class so listner annotations can be used.
Actualmente, el ejemplo de Spring Boot Batch también está devolviendo el ItemReader, así que supongo que otras personas tendrán problemas con los mismos problemas.
El método que he definido es como a continuación:
@Bean
@StepScope
public ItemReader<BP> BPReader(){
JdbcCursorItemReader<BP> itemReader = new JdbcCursorItemReader<BP>();
...
return itemReader;
}
El tipo que he definido en el método es ItemReader, que es una interfaz, el tipo de retorno es JdbcCursorItemReader, que es una subclase de este. Al cambiar la definición de tipo de retorno a JdbcCursorItemReader solucioné mi problema
El mismo problema aqui. Cambiar el tipo de retorno de mi lector a la implementación real y agregarlo al lector
implements ItemStream
Hizo el truco para mi
El problema desapareció cuando cambio el tipo de devolución de mi bean de lector de Item a FlatFileItemReader. Todavía no me queda claro por qué esto es un problema ya que chunk (). Reader () acepta ItemReader como entrada. Supongo que hay algo de magia de AOP bajo el capó que hace FlatFileReader init y coincide con el tipo de retorno.
Esto se debe a que ItemReader no tiene el método abierto, el uso de hte StepScope creará una clase proxy basada en el tipo de retorno. También está bien devolver ItemStreamReader
Lo he arreglado por:
reader.open(new ExecutionContext());