1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

きっかけ

spring batchについて学習しようと思い、spring batch入門について調べていました。
ですが、ハローワールド実行までが難航してしまったのでここに記載します。

内容

spring boot2(batch4)のサポートが終了しているので、spring boot3(batch5)でハローワールドを実行しつつ、boot2との差分を比較するといった内容になっています。

問題

  • batch4とbatch5でコードが変わる

batch4での記述がbatch5でも使えたら問題なかったのですが、一部使えなくなっていました。例:JobBuilderFactory, StepBuilderFactory

下図はboot2ではインポートできるがboot3ではインポートができないという状態です。
(JobBuilderFactoryなどはboot3では非推奨という記事は見かけましたが、使えなくなったとは記載がなかったのでIDE側が原因かもしれないです。※IDEはIntellijを使用。使えたとしても非推奨なのでコード変更の対応が必要)

spring boot3.4.0(batch5), JDK23を使用
image.png

spring boot2.4.2(batch4), JDK14を使用
image.png

プログラムファイル

今回プログラムを記載したファイルは下記の3種になります。

  • \src\main\java\com\example\demo\
    • DemoApplication.java
    • HelloTasklet.java
    • BatchConfig.java

batch5対応の記述

変更前

BatchConfig.java
package com.example.demo;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableBatchProcessing
public class BatchConfig {

  @Autowired
  private JobBuilderFactory jobBuilderFactory;

  @Autowired
  private StepBuilderFactory stepBuilderFactory;

  @Autowired
  private HelloTasklet helloTasklet;

  @Bean
  public Step sampleStep() {
    return stepBuilderFactory.get("HelloStep")
            .tasklet(helloTasklet)
            .build();
  }

  @Bean
  public Job sampleJob() throws Exception {
    return jobBuilderFactory.get("HelloJob")
            .incrementer(new RunIdIncrementer())
            .start(sampleStep())
            .build();
  }
}

変更後

BatchConfig.java
package com.example.demo;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.job.builder.JobBuilder;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;

@Configuration
public class BatchConfig {

  @Autowired
  private HelloTasklet helloTasklet;

  @Bean
  public Step sampleStep(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
    return new StepBuilder("HelloStep", jobRepository)
            .tasklet(helloTasklet, transactionManager)
            .build();
  }

  @Bean
  public Job sampleJob(JobRepository jobRepository, PlatformTransactionManager transactionManager) throws Exception {
    return new JobBuilder("HelloJob", jobRepository)
            .incrementer(new RunIdIncrementer())
            .start(sampleStep(jobRepository, transactionManager))
            .build();
  }
}

変更内容について

○○BuildFactory

batch4
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
// 略
  @Bean
  public Step sampleStep() {
    return stepBuilderFactory.get("HelloStep")
            .tasklet(helloTasklet)
            .build();
  }

  @Bean
  public Job sampleJob() throws Exception {
    return jobBuilderFactory.get("HelloJob")
            .incrementer(new RunIdIncrementer())
            .start(sampleStep())
            .build();
  }

stepBuilderFactoryがStepBuilder, jobBuilderFacotryがJobBuilderに変わっています。
上記2種のFactoryを使用するのに@EnableBatchProcessingが必要でしたが、Factoryを使わなくなったのでこのアノテーションも削除しています。
※taskletについては後述

batch5
// import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
// 略
@Bean
public Step sampleStep(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
  return new StepBuilder("HelloStep", jobRepository)
          .tasklet(helloTasklet, transactionManager)
          .build();
}

@Bean
public Job sampleJob(JobRepository jobRepository, PlatformTransactionManager transactionManager) throws Exception {
  return new JobBuilder("HelloJob", jobRepository)
          .incrementer(new RunIdIncrementer())
          .start(sampleStep(jobRepository, transactionManager))
          .build();
}

tasklet

HelloTasklet.java
package com.example.demo.tasklet;

import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.stereotype.Component;

@Component
@StepScope
public class HelloTasklet implements Tasklet {

  @Override
  public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
    System.out.println("Hello World");
    return RepeatStatus.FINISHED;
  }
}

HelloTasklet.javaはbatch4, 5でコードに変更はありません。
下記はBatchConfig.javaの内容です。

batch4
  @Bean
  public Step sampleStep() {
    return stepBuilderFactory.get("HelloStep")
            .tasklet(helloTasklet)
            .build();
  }

taskletにPlatformTransactionManagerが要求されるようになりました。

batch5
 @Bean
  public Step sampleStep(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
    return new StepBuilder("HelloStep", jobRepository)
            .tasklet(helloTasklet, transactionManager)
            .build();
  }

実行結果

DemoApplication.java
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

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

@SpringBootApplicationが付与されているクラスを実行すると、下記内容が出力されるのを確認できると思います。

2024-12-12T00:24:11.148+09:00  INFO 25432 --- [demo] [           main] o.s.b.c.l.s.TaskExecutorJobLauncher      : Job: [SimpleJob: [name=HelloJob]] launched with the following parameters: [{'run.id':'{value=1, type=class java.lang.Long, identifying=true}'}]
2024-12-12T00:24:11.164+09:00  INFO 25432 --- [demo] [           main] o.s.batch.core.job.SimpleStepHandler     : Executing step: [HelloStep]
Hello World
2024-12-12T00:24:11.174+09:00  INFO 25432 --- [demo] [           main] o.s.batch.core.step.AbstractStep         : Step: [HelloStep] executed in 8ms
2024-12-12T00:24:11.178+09:00  INFO 25432 --- [demo] [           main] o.s.b.c.l.s.TaskExecutorJobLauncher      : Job: [SimpleJob: [name=HelloJob]] completed with the following parameters: [{'run.id':'{value=1, type=class java.lang.Long, identifying=true}'}] and the following status: [COMPLETED] in 21ms
2024-12-12T00:24:11.181+09:00  INFO 25432 --- [demo] [ionShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...

上記のようなログが出ない場合

BatchConfig.javaに@EnableBatchProcessingが付与されているとうまく実行できないみたいで、下記のようなログのみ出力され上記のようにどのバッチ、ステップが呼ばれたかなどは出力されませんでした。また、この動きに対してエラーはでませんでした。(デバッグするとjobやstepの呼び出しはしているが、taskletは呼ばれていないのが確認できます。これにずっとハマってました)

2024-12-12T00:31:02.411+09:00  INFO 23436 --- [demo] [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Start completed.
2024-12-12T00:31:02.420+09:00  INFO 23436 --- [demo] [           main] o.s.b.c.r.s.JobRepositoryFactoryBean     : No database type set, using meta data indicating: H2
2024-12-12T00:31:02.449+09:00  INFO 23436 --- [demo] [           main] .c.a.BatchObservabilityBeanPostProcessor : No Micrometer observation registry found, defaulting to ObservationRegistry.NOOP
2024-12-12T00:31:02.453+09:00  INFO 23436 --- [demo] [           main] .c.a.BatchObservabilityBeanPostProcessor : No Micrometer observation registry found, defaulting to ObservationRegistry.NOOP
2024-12-12T00:31:02.456+09:00  INFO 23436 --- [demo] [           main] o.s.b.c.l.s.TaskExecutorJobLauncher      : No TaskExecutor has been set, defaulting to synchronous executor.
2024-12-12T00:31:02.521+09:00  INFO 23436 --- [demo] [           main] com.example.demo.DemoApplication         : Started DemoApplication in 0.968 seconds (process running for 1.201)
2024-12-12T00:31:02.524+09:00  INFO 23436 --- [demo] [ionShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown initiated...
2024-12-12T00:31:02.546+09:00  INFO 23436 --- [demo] [ionShutdownHook] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Shutdown completed.

gradle

build.gradle
plugins {
	id 'java'
	id 'org.springframework.boot' version '3.4.0'
	id 'io.spring.dependency-management' version '1.1.6'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'

java {
	toolchain {
		languageVersion = JavaLanguageVersion.of(23)
	}
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-batch'
	runtimeOnly 'com.h2database:h2'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	testImplementation 'org.springframework.batch:spring-batch-test'
	testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

tasks.named('test') {
	useJUnitPlatform()
}

spring batch使うならおそらくDBが必要です。DBがないと実行時にエラーになりました。
上記だと下記がDBに該当します。

runtimeOnly 'com.h2database:h2'

runtimeOnly 'org.hsqldb:hsqldb'でもOK、他は未確認。

終わり

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?