Spring Batch ExitCodeGenerator 在 tasklet 中抛出异常时

问题描述 投票:0回答:1

在我的 Spring Batch 应用程序中,我想根据抛出的异常返回不同的退出代码。

所以我遵循了这个文档:https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#features.spring-application.application-exit

并在我的异常中实现 ExitCodeGenerator :

class MyCustomException(message: String) : RuntimeException(message), ExitCodeGenerator {
    override fun getExitCode(): Int {
        return 13
    }

}
 

这个异常是在tasklet中抛出的,应用程序是这样运行的:

@SpringBootApplication
class MyApplication

fun main(args: Array<String>) {
    exitProcess(
        SpringApplication.exit(
            runApplication<MyApplication>(*args)
        )
    )
}

但是当抛出异常时,应用程序失败并返回退出代码 5。看来步骤中的异常不会传播到检查异常退出代码的 SpringApplication.run() 。这个 Spring Boot 功能是否与 Spring 批处理行为不兼容,或者我错过了什么?

spring spring-boot kotlin error-handling spring-batch
1个回答
0
投票

在我的异常中实现 ExitCodeGenerator

异常类型不应该是

ExitCodeGenerator
,而应该是相反的:
ExitCodeGenerator
应根据异常类型返回退出代码。

Spring Boot 会发出带有

JobExecutionEvent
JobExecution
,因此您可以使自定义
ExitCodeGenerator
成为此类事件的侦听器,例如:

package com.example.demo;

import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.job.builder.JobBuilder;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.boot.ExitCodeGenerator;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.batch.JobExecutionEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.transaction.PlatformTransactionManager;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        System.exit(
                SpringApplication.exit(
                        SpringApplication.run(DemoApplication.class, args)
                )
        );
    }

    @Bean
    public Job job(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
        Step step = new StepBuilder("step", jobRepository)
                .tasklet((contribution, chunkContext) -> {
                    throw new Exception("Boom");
                }, transactionManager).build();
        return new JobBuilder("job", jobRepository)
                .start(step)
                .build();
    }

    @Bean
    public ExitCodeGenerator exitCodeGenerator () {
        return new MyExitCodeGenerator();
    }

    static class MyExitCodeGenerator implements ExitCodeGenerator, ApplicationListener<JobExecutionEvent> {

        private JobExecution jobExecution;

        @Override
        public int getExitCode() {
            ExitStatus exitStatus = jobExecution.getExitStatus();
            if (ExitStatus.FAILED.getExitCode().equals(exitStatus.getExitCode())) {
                return 13;
            }
            return 0;
        }

        @Override
        public void onApplicationEvent(JobExecutionEvent jobExecutionEvent) {
            this.jobExecution = jobExecutionEvent.getJobExecution();
        }
    }

}

如果您运行此应用程序,则进程的退出代码应为 13。该项目是通过此链接从 start.spring.io 生成的。

© www.soinside.com 2019 - 2024. All rights reserved.