Spring Batch ExitCodeGenerator在tasklet中抛出异常时

l7mqbcuq  于 5个月前  发布在  Spring
关注(0)|答案(1)|浏览(65)

在我的Spring Batch Application中,我希望根据抛出的Exception返回不同的退出代码。
因此,我遵循以下文档: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()。这个Sping Boot 功能与Spring批处理行为不兼容吗?或者我错过了什么?

6uxekuva

6uxekuva1#

在我的异常中实现ExitCodeGenerator
异常类型不应该是ExitCodeGenerator,而应该是相反的:ExitCodeGenerator应该返回基于异常类型的退出代码。
Sping Boot 会发出一个带有JobExecutionJobExecutionEvent,所以你可以让你的自定义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生成的,带有这个链接。

相关问题