mike-neckのブログ

Java or Groovy or Swift or Golang

Spring Batch を Spring Boot で作った場合のプロセスの終了コード(exit code) の設定の仕方

f:id:mike_neck:20200309072715p:plain

Spring Batch で終了コードを設定する方法を調べると、おそらく次の資料に出くわす

docs.spring.io

terasoluna-batch.github.io

ただ、 Spring Boot で Spring Batch を作る場合はこの方法では多分うまくいかない。これらの資料では Spring Batch にある CommandLineJobRunner というクラスで実行することを前提にしている。しかし、 Spring Boot で作ったバッチの場合は spring-boot-autoconfigure にある JobLauncherCommandLineRunner によって起動されるため、これらの資料の方法で作る ExitCodeMapper は使われない。

では、実行した Job を表す JobExecution はどうすれば取得できるかというと、 ApplicationEventPublisher を介して取得でき、そのイベントクラスは JobExecutionEvent である。また、 Spring Boot で終了コードを設定する方法は調べればいくらでも出てくるので、それらを組み合わせればよい。

@Component
class Exit: ExitCodeGenerator {

  val logger: Logger<Exit> = logger()

  val events: MutableList<AppExitStatus> = mutableListOf()

  @EventListener
  fun receive(jobExecutionEvent: JobExecutionEvent) {
    val exitCode = jobExecutionEvent.jobExecution.exitStatus.exitCode
    logger.info("receive event: {}", exitCode)
    events += AppExitStatus.fromString(exitCode)
  }

  override fun getExitCode(): Int {
    val status = events.find { it != AppExitStatus.SUCCESS } ?: AppExitStatus.SUCCESS
    return status.exitCode
  }
}

例えば、上記のクラスを作ったうえで、 SpringApplication#exit で得られる終了コードをそのまま使えばよい

fun main(args: Array<String>) {
  val exitCode = SpringApplication.exit(runApplication<ExampleApp>(*args))
  exitProcess(exitCode)
}