【问题标题】:Spring Batch - how to fail job when called from SpringApplicationBuilderSpring Batch - 从 SpringApplicationBuilder 调用时如何使作业失败
【发布时间】:2015-04-20 00:11:12
【问题描述】:

我需要能够让我的程序退出并显示错误代码,以便启动程序的调度程序可以知道它失败了。目前,我正在通过 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. 将正在处理的文件移动到特定文件夹。
  2. 让调度程序通过程序退出代码知道发生了错误。

现在,当发生未捕获的异常时,作业将退出,这部分是我想要的,但是 Spring 处理异常,记录它,然后优雅地退出回到我的 main 方法。那时,我不确定如何捕捉作业运行是否真正成功。

【问题讨论】:

  • 使用JobListener.afterJob()?
  • SpringApplication.exit()中还有一个SpringApplicationRunListener和一个公共静态实用方法
  • @DaveSyer 好的,所以我实现了SpringApplicationRunListener,并从完成的钩子中调用SpringApplication.exit(...) 方法。如何访问退出代码? run 方法在我的 main 方法中返回 ConfigurableApplicationContext,但我不知道如何使用它来获得任何退出状态。
  • 访问码是SpringApplication.exit(...)返回的in值。我觉得我们中的一个人缺少了一些东西。我想你会想用它打电话给System.exit()
  • @DaveSyer 所以你说基本上永远不要让它回到我开始调用 Spring 的主要方法。有趣的。这只是意味着我需要做的任何额外关闭逻辑都从我的 main 移动到侦听器中的 finished() 方法,以便我可以从那里退出。

标签: spring-boot spring-batch


【解决方案1】:

我遇到了同样的问题。我设法部分解决了这样的问题(Dave Sayer 已经在评论中概述了这个想法)。

首先我创建了这个创建的监听器:

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。

顺便说一句,我观察到springApplication.run(args) 调用中出现了一些错误,但不确定为什么不是全部。我也没有找到 Spring Boot 文档中提到的任何内容

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-09
    • 2012-11-24
    • 2014-12-24
    • 1970-01-01
    相关资源
    最近更新 更多