2014-05-24 8 views
13

Ho letto domande relative a SO ma le soluzioni non funzionano per me.Spring Batch: org.springframework.batch.item.ReaderNotOpenException: Reader deve essere aperto prima di poter essere letto

Ottengo l'eccezione org.springframework.batch.item.ReaderNotOpenException: Reader must be open before it can be read.

Qui di seguito è la mia configurazione:

@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 variabile inputZipFile è impostato correttamente e il file esiste sul disco. Ho controllato il codice FlatFileItemReader e l'eccezione ReaderNotOpenException si verifica quando il membro del lettore della classe del lettore non è impostato. Il membro del lettore è impostato nel metodo doOpen. Sembra che DoOpen non venga chiamato. La domanda è: perché?

+0

Ma FlatFileItemReader è in grado di leggere i file zip? –

+0

inputZipFile è un avanzo. Sto passando il file txt. – Luke

risposta

19

Il problema è scomparso quando cambio il tipo di ritorno del mio lettore di bean da Item a FlatFileItemReader. Non mi è ancora chiaro il motivo per cui questo è un problema poiché chunk(). Reader() accetta ItemReader come input. Presumo che ci sia un po 'di magia AOP sotto il cofano che fa l'init di FlatFileReader e corrisponde al tipo di ritorno.

+2

BTW Michael Minella ha spiegato questa magia AOP qui: http://stackoverflow.com/questions/21241683/spring-batch-beforestep-does-not-work-with-stepscope/21941127#21941127 – Luke

+0

Infatti @StepScope è definito come ' @Scope (value = "step", proxyMode = ScopedProxyMode.TARGET_CLASS) ' –

5

È perché ItemReader non ha il metodo aperto, utilizzando hte StepScope creerà una classe proxy in base al tipo restituito. E 'anche ok per tornare ItemStreamReader

10

Dal momento che si mette il lettore in StepScope, il tipo di ritorno di fagioli dovrebbe essere il tipo di attuazione FlatFileItemReader:

@Bean 
@StepScope 
public FlatFileItemReader<Player> reader(@Value("#{jobParameters[inputZipfile]}") String inputZipfile) { 
      ... 
      return reader; 
} 

Se si specifica l'interfaccia, il proxy Primavera ha accesso solo alle i metodi e le annotazioni specificati nell'interfaccia ItemReader e mancano annotazioni importanti. C'è anche un avvertimento (con un errore di battitura) nei registri:

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. 

Attualmente l'esempio di avvio batch primavera è anche la restituzione del ItemReader, quindi credo che le altre persone si lotta con gli stessi problemi.

0

Lo stesso problema qui. Cambiare tipo di ritorno di mio lettore per l'attuazione reale e aggiungendo al lettore

implements ItemStream 

ha fatto il trucco per me

1

penso che si dovrebbe aumentare la dimensione del pezzo in processPlayerStats() della classe fase di fagioli, vale a dire da pezzo (10) a pezzo (100/più può essere).

Problemi correlati