当前位置:   article > 正文

java自定义终止程序,Spring批处理返回自定义流程退出代码

java process退出码自定义

I have one jar with several jobs, I want to execute only one job each time and retrieve a custom exit code.

For example, I have basic job (retrieveErrorsJob) configuration with one step that will read an input XML file and write the data in specific database table.

Application class

@SpringBootApplication

@EnableBatchProcessing

@Import(CoreCommonsAppComponent.class)

public class Application {

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

private ConfigurationConstants constants;

@Autowired

public Application(ConfigurationConstants constants) {

this.constants = constants;

}

@EventListener(ApplicationStartedEvent.class)

public void idApplication()

{

logger.info("================================================");

logger.info(constants.APPLICATION_NAME() + "-v." + constants.APPLICATION_VERSION() + " started on " + constants.REMOTE_HOST());

logger.info("------------------------------------------------");

}

public static void main(String... args) throws Exception{

ApplicationContext context = SpringApplication.run(Application.class, args);

logger.info("================================================");

SpringApplication.exit(context);

}

}

I can choose one job from command line:

java -jar my-jar.jar --spring.batch.job.names=retrieveErrorsJob --input.xml.file=myfile.xml

Spring Batch starts the correct job.

The problem is that I need the jar to return a custom process exit integer like ExitCode.FAILED == 4 etc. But I always have a ZERO (if ExitCode = SUCCESS or FAILED).

As per the docs, I need to implement ExitCodeMapper interface.

Code (not finished)

public class CustomExitCodeMapper implements ExitCodeMapper {

private static final int NORMAL_END_EXECUTION = 1;

private static final int NORMAL_END_WARNING = 2;

private static final int ABNORMAL_END_WARNING = 3;

private static final int ABNORMAL_END_ERROR = 4;

@Override

public int intValue(String exitCode) {

System.out.println("EXIT CODE = " + exitCode);

switch (exitCode)

{

case "FAILED":

return ABNORMAL_END_WARNING;

default:

return NORMAL_END_EXECUTION;

}

}

}

I can't find a way to use this custom implementation. I could set the custom implementation to CommandLineJobRunner but how to use this class?

解决方案

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.

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/334289
推荐阅读
相关标签
  

闽ICP备14008679号