我正在尝试修复从shell脚本启动的弹出批处理作业。然后,该脚本检查进程退出代码以确定作业是否成功。但是,即使程序以异常结束,Java也会退出0,除非使用不同的代码专门调用System.exit,因此脚本始终报告成功。
有没有办法让spring-batch在失败时返回非零代码?要清楚,我不是在谈论ExitStatus或BatchStatus,而是java进程的实际退出代码。
如果没有办法告诉spring-batch返回非零,我是否可以在Tasklet(或Listener)中安全地使用System.exit,而不会干扰Spring-batch在异常后执行的任何操作?< / p>
如果失败了,是否有人可以建议一种方法将BatchStatus或其他一些失败指标恢复到shell脚本?
答案 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失败”转换(通常,除了最后一步之外的所有步骤)。