2014-05-24 4 views
13

Ich lese SO verwandte Fragen, aber die Lösungen funktionieren nicht für mich.Spring Batch: org.springframework.batch.item.ReaderNotOpenException: Reader muss geöffnet sein, bevor es gelesen werden kann

Ich bekomme die org.springframework.batch.item.ReaderNotOpenException: Reader must be open before it can be read Ausnahme.

Unten ist meine Konfiguration:

@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(); 
} 

Die inputZipFile Variable richtig eingestellt ist und die Datei vorhanden auf dem Laufwerk. Ich habe den FlatFileItemReader-Code eingecheckt und die ReaderNotOpenException tritt auf, wenn das Reader-Member der Reader-Klasse nicht gesetzt ist. Das Reader-Member wird in der doOpen-Methode festgelegt. Es sieht aus, dass doOpen nicht aufgerufen wird. Die Frage ist warum?

+0

Aber kann der FlatFileItemReader zip-Dateien lesen? –

+0

inputZipFile ist ein Rest. Ich übermittle TXT-Datei. – Luke

Antwort

19

Das Problem verschwand, wenn ich den Rückgabetyp meiner Leser Bean von Item zu FlatFileItemReader ändern. Es ist mir immer noch nicht klar, warum dies ein Problem ist, da chunk(). Reader() ItemReader als Eingabe akzeptiert. Ich nehme an, dass es einige AOP-Magie unter der Haube gibt, die FlatFileReader init tut und mit dem Rückgabetyp übereinstimmt.

+2

BTW Michael Minella hat diese AOP Magie hier erklärt: http://StackOverflow.com/Questions/21241683/spring-batch-beforestep-does-not-work-with-stecope/21941127#21941127 – Luke

+0

Tatsächlich @StepScope definiert als ' @Scope (Wert = "step", proxyMode = ScopedProxyMode.TARGET_CLASS) ' –

5

Es ist, weil ItemReader nicht die offene Methode haben, mit Hilfe von StepScope wird eine Proxy-Klasse basierend auf dem Rückgabetyp erstellen. Es ist auch ok ItemStreamReader

10

zurückzukehren Da Sie den Leser in StepScope setzen, sollte die Bohne Rückgabetyp der Umsetzung Typ FlatFileItemReader sein:

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

Wenn Sie die Schnittstelle angeben, wird der Frühling Proxy hat nur Zugriff auf die Methoden und Anmerkungen, die auf der Schnittstelle ItemReader angegeben sind und wichtige Anmerkungen fehlen. Es gibt auch eine Warnung (mit einem Tippfehler) in den Protokollen:

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. 

Derzeit ist das Frühjahr Boot-Batch Beispiel auch die ItemReader zurückkehrt, so dass ich denke, andere Leute mit den gleichen Problemen kämpfen hat.

0

Das gleiche Problem hier. Ändern Rückgabetyp meiner Leser auf die tatsächliche Umsetzung und zur Ergänzung der Leser

implements ItemStream 

hat den Trick für mich

1

Ich glaube, Sie Ihre Chunkgröße in processPlayerStats() Schritt Bean-Klasse erhöhen sollte, dh von Chunk (10) zu Chunk (100/mehr kann sein).