如果抛出异常,则使用非零代码创建一个spring-batch作业出口

时间:2016-11-04 16:31:30

标签: java spring-batch

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

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

如果没有办法告诉spring-batch返回非零,我是否可以在Tasklet(或Listener)中安全地使用System.exit,而不会干扰Spring-batch在异常后执行的任何操作?< / p>

如果失败了,是否有人可以建议一种方法将BatchStatus或其他一些失败指标恢复到shell脚本?

3 个答案:

答案 0 :(得分:2)

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

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

因此,如果您想使用springboot,我建议您编写自己的Launch-Wrapper main -method。像

这样的东西
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);
}

答案 1 :(得分:2)

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

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

答案 2 :(得分:1)

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

Spring Batch确实在失败的作业上退出非零,但是有一个微妙的问题。

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

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

相关问题