@khmatsunaga

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

GradleのSpringBatchの実行に失敗する。

解決したいこと

SpringBatchのソースを作成し、Spring Bootで実行するとAPPLICATION FAILED TO STARTとなります。
解決方法がわかる方がいらっしゃいましたら、教えて下さい。

発生している問題・エラー

SpringBatchのソースを作成し、Spring Bootで実行するとAPPLICATION FAILED TO STARTとなります。
image.png

警告の英文を見るとBatchConfig.javaのBEANへの登録失敗、依存関係エラーのようなのですが、何が間違っているのか、なんの設定が足りないのか分かりません。

エラーメッセージ
trationDelegate$BeanPostProcessorChecker Bean 'jobRegistry' of type [org.springframework.batch.core.configuration.support.MapJobRegistry] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected into a currently created BeanPostProcessor [jobRegistryBeanPostProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies.```

s.c.a.AnnotationConfigApplicationContext Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'batchConfig' defined in file [C:\pleiades\2023-12\workspace\test-batch\bin\main\com\example\testbatch\BatchConfig.class]: Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type 'org.springframework.batch.core.configuration.annotation.JobBuilderFactory' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

ソースコード

TestBatchApplication.java
package com.example.testbatch;

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

@SpringBootApplication
public class TestBatchApplication {

  public static void main(String[] args) {
    SpringApplication.run(TestBatchApplication.class, args);
  }
}
BatchConfig.java
package com.example.testbatch;

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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import lombok.RequiredArgsConstructor;

@EnableBatchProcessing
@Configuration
@RequiredArgsConstructor // Lombok によるコンストラクタ自動生成
public class BatchConfig {
    private final JobBuilderFactory jobBuilderFactory;
    private final StepBuilderFactory stepBuilderFactory;

      @Bean
    public Job fooJob() {
      System.out.println("fooJob メソッドを実行");
      return jobBuilderFactory.get("myFooJob") // 一意となる任意のジョブ名を指定
        .flow(helloStep()) // 実行する Step を指定
        .end()
        .build();
    }

    @Bean
    public Job barJob() {
      System.out.println("barJob メソッドを実行");
      return jobBuilderFactory.get("myBarJob") // 一意となる任意のジョブ名を指定
        .flow(helloStep()) // 実行する Step を指定
        .next(worldStep()) // 実行する Step を指定
        .end()
        .build();
    }

    @Bean
    public Step helloStep() {
      System.out.println("helloStep メソッドを実行");
      return stepBuilderFactory.get("myHelloStep") // 任意のステップ名を指定
        .tasklet(new MessageTasklet("Hello!")) // 実行する Tasklet を指定
        .build();
    }

    @Bean
    public Step worldStep() {
      System.out.println("worldStep メソッドを実行");
      return stepBuilderFactory.get("myWorldStep") // 任意のステップ名を指定
        .tasklet(new MessageTasklet("World!")) // 実行する Tasklet を指定
        .build();
    }
}

MessageTasklet.java
package com.example.testbatch;

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;

import lombok.RequiredArgsConstructor;

// Tasklet 実装クラス
@RequiredArgsConstructor // Lombok によるコンストラクタ自動生成
@Component
@StepScope
public class MessageTasklet implements Tasklet {

  // 出力するメッセージ
  private final String message;

  // 具体的な処理を実装するメソッド
  @Override
  public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
    System.out.println("Message: " + message); // メッセージを出力
    return RepeatStatus.FINISHED; // 処理が終了したことを示す値を返す
  }
}
build.gradle
plugins {
  id 'java'
  id 'org.springframework.boot' version '3.2.3'
  id 'io.spring.dependency-management' version '1.1.4'
}

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

java {
  sourceCompatibility = '17'
}

configurations {
  compileOnly {
    extendsFrom annotationProcessor
  }
}

repositories {
  mavenCentral()
}

dependencies {
  implementation 'org.springframework.boot:spring-boot-starter-batch'
  implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
  compileOnly 'org.projectlombok:lombok'
  annotationProcessor 'org.projectlombok:lombok'
  testImplementation 'org.springframework.boot:spring-boot-starter-test'
  testImplementation 'org.springframework.batch:spring-batch-test'
}

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

自分で試したこと

ここに問題・エラーに対して試したことを記載してください。

0 likes

2Answer

Comments

  1. @khmatsunaga

    Questioner

    同じソースでの警告です。
    実行結果をよく見たら、エラーの前にこの警告が出ていました。
    こちらの警告のほうが動かない原因なのかと考えて質問を出しました。
    前の質問の方は、一旦クローズさせていただきます。

Spring Batch5.0で推奨されていないJobBuilderFactoryとStepBuilderFactoryを使っていたのが原因でした。
JOBがうまく登録されなかったようです。
推奨されているJobBuilderとStepBuilderを使用したら、動きました。
こちらの質問はクローズさせていただきます。

0Like

Your answer might help someone💌