2015-02-18 2 views
2

Мне нужно, чтобы моя программа выходила с кодом ошибки, чтобы планировщик, инициировавший программу, мог знать, что она не удалась. В настоящее время я выполняю свою работу через SpringApplicationBuilder.Spring Batch - как сменить работу при вызове из SpringApplicationBuilder

@SpringBootApplication 
@EnableBatchProcessing 
@Slf4j 
public class WeeklyImportApplication extends DefaultBatchConfigurer { 

... 

    public static void main(String[] args) { 
     handleArguments(args); 

     new SpringApplicationBuilder(WeeklyImportApplication.class).listeners(new CustomLoggingConfigurationApplicationListener(logConfigurer)).run(args); 

     finished(); 
    } 

    @Bean 
    public Job weeklyImport(JobBuilderFactory jobs, Step determineTableName, Step determineColumnNames, Step readAccessDb) { 
     return jobs.get("weeklyImport").incrementer(new RunIdIncrementer()).flow(determineTableName).next(determineColumnNames).next(readAccessDb).end().build(); 
    } 

    @Bean 
    public Step determineTableName(StepBuilderFactory stepBuilderFactory, ItemReader<String> tableNameReader, TableNameWriter tableNameWriter) { 
     return stepBuilderFactory.get("determineTableName").<String, String> chunk(100).reader(tableNameReader).writer(tableNameWriter).build(); 
    } 

    @Bean 
    public Step determineColumnNames(StepBuilderFactory stepBuilderFactory, ItemReader<String> columnNamesReader, ColumnNamesWriter columnNamesWriter) { 
     return stepBuilderFactory.get("determineColumnNames").<String, String> chunk(1000).reader(columnNamesReader).writer(columnNamesWriter).build(); 
    } 

    @Bean 
    public Step readAccessDb(StepBuilderFactory stepBuilderFactory, ItemReader<WeeklyStoreItem> importReader, ItemWriter<WeeklyStoreItem> weeklyStoreItemWriter, PlatformTransactionManager legacyTransactionManager) { 
     return stepBuilderFactory.get("readAccessDb").<WeeklyStoreItem, WeeklyStoreItem> chunk(chunkSize).reader(importReader).writer(weeklyStoreItemWriter).transactionManager(legacyTransactionManager).build(); 
    } 

... 

В любой момент выполнения задания, если какой-либо шаг терпит неудачу, я хочу, чтобы иметь возможность выйти и сделать две вещи:

  1. Переместить файл обрабатывается в specfic папку.
  2. Ознакомиться с планировщиком с помощью кода выхода программы, в котором произошла ошибка.

В настоящее время задание будет завершено, если произойдет неперехваченное исключение, что частично является тем, что я хочу, но Spring обрабатывает исключение, регистрирует его и затем изящно завершает свой основной метод. В этот момент я не уверен, как определить, действительно ли работа выполнена успешно.

+0

с помощью 'JobListener.afterJob()'? –

+0

В SpringApplication.exit() ' –

+0

@DaveSyer есть также' SpringApplicationRunListener' и общедоступный статический утилитный метод. Поэтому я реализовал 'SpringApplicationRunListener', и я вызываю метод SpringApplication.exit (...)' от готового крючка. Как получить доступ к коду выхода? Метод run возвращает «ConfigurableApplicationContext» в моем основном методе, но я не могу понять, как использовать его для получения любого статуса выхода. – IceBox13

ответ

0

У меня была та же проблема. Мне удалось частично решить эту проблему (Дэйв Сайер изложил эту идею уже в комментарии).

Сначала я создал этот созданный слушатель:

import org.springframework.batch.core.ExitStatus; 
import org.springframework.boot.autoconfigure.batch.JobExecutionEvent; 
import org.springframework.context.ApplicationListener; 

public class JobResultListener implements 
    ApplicationListener<JobExecutionEvent> { 
    private ExitStatus jobExitStatus; 

    public ExitStatus getJobExitStatus() { 
    return jobExitStatus; 
    } 

    @Override 
    public void onApplicationEvent(JobExecutionEvent event) { 
    jobExitStatus = event.getJobExecution().getExitStatus(); 
    } 
} 

чем я использовал его, чтобы получить статус выполнения задания таким образом:

@SpringBootApplication 
public class Application{ 

    public static void main(String[] args) { 
    SpringApplication springApplication = 
     new SpringApplication(Application.class); 

    JobResultListener jobResultListener = new JobResultListener(); 
    springApplication.addListeners(jobResultListener); 
    springApplication.run(args); 

    if (!ExitStatus.COMPLETED.equals(jobResultListener.getJobExitStatus())) { 
     throw new IllegalStateException("Job failed"); 
    } 
    } 
} 

Но по какой-то причине я не смог получить экземпляры исключения из введенного события. Но, как вы упомянули, ошибка регистрируется в журналах приложений, поэтому этого механизма было достаточно для того, чтобы я мог вызвать вызванный мой процесс об ошибке с кодом ошибки! = 0.

BTW, я заметил, что некоторая ошибка проникла из springApplication.run(args), но не знаю, почему не все. Также я не нашел ничего упомянутого в Spring Boot docs

Смежные вопросы