Make a spring-batch job exit with non-zero code if an exception is thrown

北城以北 提交于 2019-11-28 02:09:46

问题


I'm trying to fix a spring-batch job which is launched from a shell script. The script then checks the process exit code to determine whether the job has succeeded. Java, however, exits 0 even if the program ended with an exception, unless System.exit was specifically called with a different code, so the script always reports success.

Is there a way to make spring-batch return a non-zero code on failure? To be clear, I'm not talking about the ExitStatus or BatchStatus, but the actual exit code of the java process.

If there's no way to tell spring-batch to return non-zero, can I safely use System.exit in a Tasklet (or a Listener) without interfering with anything that spring-batch does under the hood after an exception?

Failing that, can anyone suggest a way to get the BatchStatus or some other indicator of failure back to the shell script?


回答1:


I would not recommend calling System.exit() from a tasklet, since the job will NOT finish completely and hence some entries in BATCH_-Tables could be left in an inconsistent state.

If you use the class CommandLineJobRunner to start your batch, then the return code according to the BatchStatus is returned (CommandLineJobRunner can be configured with an SystemExiter; as default it uses a JvmSystemExiter which calls System.exit() at the very end). However, this solution circumvents SpringBoot.

Therefore, if you want to use springboot, I'd recommend writing your own Launch-Wrapper main -method. Something like

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);
}



回答2:


As per this github issue it's recommended to pass the result of SpringApplication#exit to System#exit. You don't need to access an ExitCodeGenerator instance directly or manually close the context.

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



回答3:


I solved this some time ago - apologies that I did not update sooner.

Spring Batch does exit non-zero on an failed job, but there's a subtle catch.

If a job step has no transitions explicitly defined it will by default end the job on success and fail the job on failure (of the step).

If, however, the step has a transition defined for any result (e.g. to the next step on success), there is no default transition for any other result, and if it fails the job won't be properly failed. So you have to explicitly define a "fail on FAILED" transition (typically, for all steps except the last).



来源:https://stackoverflow.com/questions/40427590/make-a-spring-batch-job-exit-with-non-zero-code-if-an-exception-is-thrown

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!