Spring 批量 return 自定义进程退出代码
Spring batch return custom process exit code
我有一个包含多个作业的 jar,我想每次只执行一个作业并检索自定义退出代码。
例如,我有基本的作业 (retrieveErrorsJob
) 配置,其中一步将读取输入 XML 文件并将数据写入特定数据库 table。
申请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);
}
}
我可以从命令行中选择一项工作:
java -jar my-jar.jar --spring.batch.job.names=retrieveErrorsJob --input.xml.file=myfile.xml
Spring 批处理启动正确的作业。
问题是我需要 jar 来 return 自定义进程退出整数,如 ExitCode.FAILED == 4
等。但我总是有一个零(如果 ExitCode = SUCCESS 或 FAILED)。
根据文档,我需要实现 ExitCodeMapper
接口。
代码(未完)
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;
}
}
}
我找不到使用此自定义实现的方法。我可以将自定义实现设置为 CommandLineJobRunner
但如何使用此 class?
尽管 Sprint-Batch 作业的退出状态(即完成或失败),java 进程将成功完成(您将获得进程退出代码 0)。
如果您想要 java 进程的自定义退出代码以便您可以在任何脚本或其他地方使用它,您可以使用 JobExecutionListener.
您可以在 afterJob()
中检查作业的退出状态,并相应地使用您想要的退出代码退出 java 进程(即 4 表示失败)
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);
}
}
}
这就是如何在 xml 文件中配置作业侦听器 -
<job id="job">
....
....
<listeners>
<listener ref="interceptingExitStatus "/>
</listeners>
</job>
感谢@Mahendra,我有了一个主意:)
我按照@Mahendra 的建议创建了一个 JobCompletionNotificationListener
class:
@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);
}
}
}
但我不会强制应用程序从 class 退出 System.exit()
。我已经实现了一个像这样的简单单例:
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;
}
}
关闭 Spring 上下文后,我向单身人士询问 ExitCode
:
@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());
}
}
我这样做是因为如果我们直接从 JobCompletionNotificationListener
class 退出,我们会错过日志中的重要一行:
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]
似乎 Spring 上下文没有正确关闭。
Spring Boot 和 Sring Batch 已经有内部解决方案,你只需要额外的一行代码:
System.exit(SpringApplication.exit(applicationContext));
这是另一个例子:
public class BatchApplication {
public static void main(String[] args) {
ApplicationContext applicationContext = SpringApplication.run(BatchApplication.class, args);
System.exit(SpringApplication.exit(applicationContext));
}
}
编辑:如果您想知道它是如何工作的,请查看此 class:org.springframework.boot.autoconfigure.batch.JobExecutionExitCodeGenerator
我有一个包含多个作业的 jar,我想每次只执行一个作业并检索自定义退出代码。
例如,我有基本的作业 (retrieveErrorsJob
) 配置,其中一步将读取输入 XML 文件并将数据写入特定数据库 table。
申请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);
}
}
我可以从命令行中选择一项工作:
java -jar my-jar.jar --spring.batch.job.names=retrieveErrorsJob --input.xml.file=myfile.xml
Spring 批处理启动正确的作业。
问题是我需要 jar 来 return 自定义进程退出整数,如 ExitCode.FAILED == 4
等。但我总是有一个零(如果 ExitCode = SUCCESS 或 FAILED)。
根据文档,我需要实现 ExitCodeMapper
接口。
代码(未完)
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;
}
}
}
我找不到使用此自定义实现的方法。我可以将自定义实现设置为 CommandLineJobRunner
但如何使用此 class?
尽管 Sprint-Batch 作业的退出状态(即完成或失败),java 进程将成功完成(您将获得进程退出代码 0)。
如果您想要 java 进程的自定义退出代码以便您可以在任何脚本或其他地方使用它,您可以使用 JobExecutionListener.
您可以在 afterJob()
中检查作业的退出状态,并相应地使用您想要的退出代码退出 java 进程(即 4 表示失败)
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);
}
}
}
这就是如何在 xml 文件中配置作业侦听器 -
<job id="job">
....
....
<listeners>
<listener ref="interceptingExitStatus "/>
</listeners>
</job>
感谢@Mahendra,我有了一个主意:)
我按照@Mahendra 的建议创建了一个 JobCompletionNotificationListener
class:
@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);
}
}
}
但我不会强制应用程序从 class 退出 System.exit()
。我已经实现了一个像这样的简单单例:
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;
}
}
关闭 Spring 上下文后,我向单身人士询问 ExitCode
:
@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());
}
}
我这样做是因为如果我们直接从 JobCompletionNotificationListener
class 退出,我们会错过日志中的重要一行:
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]
似乎 Spring 上下文没有正确关闭。
Spring Boot 和 Sring Batch 已经有内部解决方案,你只需要额外的一行代码:
System.exit(SpringApplication.exit(applicationContext));
这是另一个例子:
public class BatchApplication {
public static void main(String[] args) {
ApplicationContext applicationContext = SpringApplication.run(BatchApplication.class, args);
System.exit(SpringApplication.exit(applicationContext));
}
}
编辑:如果您想知道它是如何工作的,请查看此 class:org.springframework.boot.autoconfigure.batch.JobExecutionExitCodeGenerator