2017-03-27 21 views
0

DBからアイテムを読み取り、処理し、その結果をcsvに書き込む単純なシングルステップSpringバッチジョブを作成しました。SpringバッチWriterNotOpenException

@Configuration 
@EnableBatchProcessing 
@EnableAutoConfiguration 
public class CleanEmailJob { 

@Autowired 
private JobBuilderFactory jobBuilderFactory; 

@Autowired 
private StepBuilderFactory stepBuilderFactory; 

@Autowired 
public DataSource dataSource; 

@Bean 
public ResourcelessTransactionManager transactionManager() { 
    return new ResourcelessTransactionManager(); 
} 

@Bean 
public MapJobRepositoryFactoryBean mapJobRepositoryFactory(ResourcelessTransactionManager txManager) 
     throws Exception { 
    MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean(txManager); 
    factory.afterPropertiesSet(); 
    return factory; 
} 

@Bean 
public JobRepository jobRepository(MapJobRepositoryFactoryBean factory) throws Exception { 
    return factory.getObject(); 
} 

@Bean 
public JobExplorer jobExplorer(MapJobRepositoryFactoryBean factory) { 
    return new SimpleJobExplorer(factory.getJobInstanceDao(), factory.getJobExecutionDao(), 
      factory.getStepExecutionDao(), factory.getExecutionContextDao()); 
} 

@Bean 
public SimpleJobLauncher jobLauncher(JobRepository jobRepository) { 
    SimpleJobLauncher launcher = new SimpleJobLauncher(); 
    launcher.setJobRepository(jobRepository); 
    return launcher; 
} 


@Bean 
public Job cleanEmailAddressesJob() throws Exception { 
    return jobBuilderFactory.get("cleanEmailAddresses") 
      .incrementer(new RunIdIncrementer()) 
      .start(processEmailAddresses()) 
      .build(); 
} 

@Bean 
public Step processEmailAddresses() throws UnexpectedInputException, ParseException, Exception { 
    return stepBuilderFactory.get("processAffiliates") 
      .<AffiliateEmailAddress, VerifiedAffiliateEmailAddress> chunk(10) 
      .reader(reader()) 
      .processor(processor())  
      .writer(report()) 
      .build(); 
} 

@Bean 
public ItemWriter<VerifiedAffiliateEmailAddress> report(){ 
    FlatFileItemWriter<VerifiedAffiliateEmailAddress> reportWriter = new FlatFileItemWriter<VerifiedAffiliateEmailAddress>(); 
    reportWriter.setResource(new ClassPathResource("report.csv")); 
    DelimitedLineAggregator<VerifiedAffiliateEmailAddress> delLineAgg = new DelimitedLineAggregator<VerifiedAffiliateEmailAddress>(); 
    delLineAgg.setDelimiter(","); 
    BeanWrapperFieldExtractor<VerifiedAffiliateEmailAddress> fieldExtractor = new BeanWrapperFieldExtractor<VerifiedAffiliateEmailAddress>(); 
    fieldExtractor.setNames(new String[] {"uniekNr", "reason"}); 
    delLineAgg.setFieldExtractor(fieldExtractor); 
    reportWriter.setLineAggregator(delLineAgg); 
    reportWriter.setShouldDeleteIfExists(true); 
    return reportWriter; 
} 

文書で説明したように、私はライフサイクルイベントを(オープン、クローズ)自動的に私は以来の世話をしている期待: は、実行時に私は

org.springframework.batch.item.WriterNotOpenException: Writer must be open before it can be written to 

に関連するコードを終わりますシングルスレッドとシングルライターの仕事で?

+1

'report'メソッドの戻り値の型を' FlatFileItemWriter 'に変更します。 –

+0

スニペットの代わりに完全なスタックトレースを追加します。 –

答えて

0

最後にバッチアプリケーションに干渉するSpring Dev Toolsが判明しました。 ... report.txtというレポートファイルに書き込む私のクラスパスにある、春の開発ツールは、私のクラスパスの変化を検出し、report.txtというリソースを起こしたアプリケーションのリロードが閉鎖されているトリガー

spring.devtools.restart.enabled=false 

私のapplication.propertiesの中で再び動作させました

0

左のコメントを詳しく説明すると、Spring Batchはステップを開始すると自動的に開かれるように、ItemStreamの実装を自動的に登録します。 Javaの設定を使用する場合、Springは戻り値の型を知っています。 ItemReaderが返されているため、実装でもItemStreamが実装されていることはわかりません。 Javaの設定を使用する場合は、通常は(インタフェースではなく)既知の実装を返すことをお勧めします。そうすれば、Springは完全にそれをイントロスペクトすることができます。この例では、ItemReaderの代わりにFlatFileItemReaderを返すことで問題が解決されます。

関連する問題