Spring batch return custom process exit code

限于喜欢 提交于 2019-12-06 11:03:16

Thanks to @Mahendra I've got an idea :)

I've created a JobCompletionNotificationListener class as @Mahendra suggested:

@Component
public class JobCompletionNotificationListener extends JobExecutionListenerSupport {

    private static final Logger logger = LoggerFactory.getLogger(JobCompletionNotificationListener.class);

    @Override
    public void afterJob(JobExecution jobExecution) {

        SingletonExitCode exitCode = SingletonExitCode.getInstance();

       if(jobExecution.getStatus() == BatchStatus.COMPLETED)
       {
           logger.info("Exit with code " + ExitCode.NORMAL_END_OF_EXECUTION);
           exitCode.setExitCode(ExitCode.NORMAL_END_OF_EXECUTION);
       }
       else {
           logger.info("Exit with code " + ExitCode.ABNORMAL_END_OF_EXECUTION_WARNING);
           exitCode.setExitCode(ExitCode.ABNORMAL_END_OF_EXECUTION_WARNING);
       }
    }
}

But I don't force the application to exit with System.exit() from this class. I've implemented a simple singleton like this:

public class SingletonExitCode {

    public ExitCode exitCode = ExitCode.ABNORMAL_END_OF_EXECUTION_WARNING; // Default code 3
    private static SingletonExitCode instance = new SingletonExitCode();

    private SingletonExitCode() {}

    public static SingletonExitCode getInstance() {
        return instance;
    }

    public void setExitCode(ExitCode exitCode) {
        this.exitCode = exitCode;
    }
}

and I ask the ExitCode from my singleton after closing Spring context:

@SpringBootApplication
@EnableBatchProcessing
@Import(CoreCommonsAppComponent.class)
public class Application {
    // a lot of nice things

    public static void main(String... args) throws Exception{
        ApplicationContext context = SpringApplication.run(Application.class, args);
        logger.info("================================================");
        SpringApplication.exit(context);
        System.exit(SingletonExitCode.getInstance().exitCode.getCode());
    }
}

I did this because if we exit directly from JobCompletionNotificationListener class we miss an important line in the logs:

Job: [FlowJob: [name=writeErrorFromFile]] completed with the following parameters: [{-input.xml.file=c:/temp/unit-test-error.xml, -spring.batch.job.names=writeErrorFromFile, run.id=15, input.xml.file=c:/temp/unit-test-error.xml}] and the following status: [FAILED]

And seems that Spring context is not properly closed.

Despite of exit-status of Sprint-Batch's Job (i.e. COMPLETED or FAILED), java process will be completed successfully (and you will get process exit-code as 0).

If you want a custom exit-code for java process so that you can use it any script or somewhere else, you can use JobExecutionListener.

You can check the job's exitStatus in afterJob() and accordingly exit the java process with your desired exit-code (i.e. 4 for FAILURE)

Example of JobExecutionListener

public class InterceptingExitStatus implements JobExecutionListener{

    @Override
    public void beforeJob(JobExecution jobExecution) {
    }

    @Override
    public void afterJob(JobExecution jobExecution) {
        ExitStatus exitStatus = jobExecution.getExitStatus() ;

        if(exitStatus == ExitStatus.COMPLETED ){
            System.exit(0);
        }

        if(exitStatus == ExitStatus.FAILED ){
            System.exit(4);
        }
    }

}

and this is how you can configure job-listener in the xml file -

<job id="job">
....
....

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