【问题标题】:Make a spring-batch job exit with non-zero code if an exception is thrown如果抛出异常,则使用非零代码退出 spring-batch 作业
【发布时间】:2016-11-04 16:31:29
【问题描述】:

我正在尝试修复从 shell 脚本启动的 spring-batch 作业。然后该脚本检查进程退出代码以确定作业是否成功。但是,即使程序以异常结束,Java 也会退出 0,除非使用不同的代码专门调用 System.exit,因此脚本总是报告成功。

有没有办法让 spring-batch 在失败时返回非零代码?需要说明的是,我说的不是 ExitStatus 或 BatchStatus,而是 java 进程的实际退出代码。

如果没有办法告诉 spring-batch 返回非零值,我是否可以在 Tasklet(或 Listener)中安全地使用 System.exit 而不会干扰 spring-batch 在异常后所做的任何事情?

如果做不到这一点,任何人都可以提出一种方法来将 BatchStatus 或其他一些失败指示返回到 shell 脚本吗?

【问题讨论】:

  • 是的,我想用 tasklet 中的代码调用 System.exit 应该没问题
  • 我想说我们应该在 JobExecutionListener 的 afterJob() 方法中更新 JobExeuction 对象的 BatchStatus 属性。 Shell Script 将完美地捕捉返回码。
  • 感谢@NghiaDo,这行得通。
  • 太棒了。请将它标记为好,以便大家知道。

标签: java spring-batch


【解决方案1】:

根据this github issue,建议将SpringApplication#exit 的结果传递给System#exit。您无需直接访问ExitCodeGenerator 实例或手动关闭上下文。

ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
int exitCode = SpringApplication.exit(context);
System.exit(exitCode);

【讨论】:

    【解决方案2】:

    我不建议从 tasklet 调用 System.exit(),因为作业不会完全完成,因此 BATCH_-Tables 中的某些条目可能会处于不一致的状态。

    如果您使用类 CommandLineJobRunner 来启动批处理,则返回根据 BatchStatus 的返回码(CommandLineJobRunner 可以配置一个 SystemExiter;默认情况下,它使用一个 JvmSystemExiter,它在最后调用 System.exit() )。但是,这个解决方案绕过了 SpringBoot。

    因此,如果您想使用 springboot,我建议您编写自己的 Launch-Wrapper 主方法。类似的东西

    public static void main(String[] args) throws Exception {
      // spring boot application startup
      SpringApplication springApp = new SpringApplication(.. your context ..);
    
      // calling the run method returns the context
      // pass your program arguments
      ConfigurableApplicationContext context = springApp.run(args);
    
      // spring boot uses exitCode Generators to calculate the exit status
      // there should be one implementation of the ExitCodeGenerator interface
      // in your context. Per default SpringBoot uses the JobExecutionExitCodeGenerator
      ExitCodeGenerator exitCodeGen = context.getBean(ExitCodeGenerator.class);
    
      int code = exitCodeGen.getExitCode();
      context.close();
      System.exit(code);
    }
    

    【讨论】:

      【解决方案3】:

      我前段时间解决了这个问题 - 很抱歉我没有尽快更新。

      Spring Batch 在失败的作业中退出非零值,但有一个微妙的问题。

      如果作业步骤没有明确定义的转换,默认情况下它将在成功时结束作业并在失败时失败作业(步骤)。

      但是,如果该步骤为任何结果定义了转换(例如,成功后到下一步),则任何其他结果都没有默认转换,如果失败,则作业不会正确失败。因此,您必须明确定义“失败时失败”转换(通常,对于除最后一个步骤之外的所有步骤)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-04-08
        • 2011-12-14
        • 2015-04-27
        • 1970-01-01
        • 1970-01-01
        • 2014-10-10
        • 1970-01-01
        相关资源
        最近更新 更多