Add batch-5-to-6 module: Spring Batch 5.2 to 6.0 migration on Boot 3.5 to 4.1

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Gth99spB1CzQmBFofXmU4Z
This commit is contained in:
2026-09-28 09:09:50 +00:00
co-authored by Claude Sonnet 5
parent 804c33f0d5
commit ae681f85c4
22 changed files with 495 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.5.16</version>
<relativePath/>
</parent>
<groupId>com.ankurm</groupId>
<artifactId>batch-legacy</artifactId>
<version>1.0.0</version>
<properties><java.version>21</java.version></properties>
<dependencies>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-batch</artifactId></dependency>
<dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><scope>runtime</scope></dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
<dependency><groupId>org.springframework.batch</groupId><artifactId>spring-batch-test</artifactId><scope>test</scope></dependency>
</dependencies>
<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>
@@ -0,0 +1,14 @@
package com.ankurm.batch;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class App {
public static void main(String[] args) {
ConfigurableApplicationContext ctx = SpringApplication.run(App.class, args);
ctx.getBean(JobRunner.class).run();
ctx.close();
}
}
@@ -0,0 +1,55 @@
package com.ankurm.batch;
import java.util.List;
import org.springframework.batch.core.ChunkListener;
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.repository.JobRepository;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.support.ListItemReader;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
@Configuration
public class BatchConfig {
@Bean
ItemReader<Integer> reader() {
return new ListItemReader<>(List.of(1, 2, 3, 4, 5, 6, 7));
}
@Bean
ItemWriter<String> writer() {
return chunk -> System.out.println("WRITE " + chunk.getItems());
}
@Bean
ChunkListener chunkListener() {
return new ChunkListener() {
@Override public void afterChunk(ChunkContext context) {
System.out.println("CHUNK DONE, read so far=" + context.getStepContext().getStepExecution().getReadCount());
}
};
}
@Bean
Step squareStep(JobRepository repo, PlatformTransactionManager tx, ChunkListener listener) {
return new StepBuilder("squareStep", repo)
.<Integer, String>chunk(3, tx)
.reader(reader())
.processor(i -> "sq" + (i * i))
.writer(writer())
.listener(listener)
.build();
}
@Bean
Job squareJob(JobRepository repo, Step squareStep) {
return new JobBuilder("squareJob", repo).start(squareStep).build();
}
}
@@ -0,0 +1,33 @@
package com.ankurm.batch;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.explore.JobExplorer;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.stereotype.Component;
@Component
public class JobRunner {
private final JobLauncher launcher;
private final JobExplorer explorer;
private final Job job;
public JobRunner(JobLauncher launcher, JobExplorer explorer, Job squareJob) {
this.launcher = launcher; this.explorer = explorer; this.job = squareJob;
}
public void run() {
try {
JobParameters params = new JobParametersBuilder().addLong("run.id", 1L).toJobParameters();
JobExecution exec = launcher.run(job, params);
System.out.println("STATUS " + exec.getStatus() + " exit=" + exec.getExitStatus().getExitCode());
System.out.println("INSTANCES " + explorer.getJobInstanceCount("squareJob"));
System.out.println("DONE " + (exec.getStatus() == BatchStatus.COMPLETED));
} catch (Exception e) {
throw new IllegalStateException(e);
}
}
}
@@ -0,0 +1,3 @@
spring.batch.job.enabled=false
spring.datasource.url=jdbc:h2:mem:legacy;DB_CLOSE_DELAY=-1
spring.batch.jdbc.initialize-schema=always
@@ -0,0 +1,23 @@
package com.ankurm.batch;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.Test;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.test.JobLauncherTestUtils;
import org.springframework.batch.test.context.SpringBatchTest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
@SpringBatchTest
class JobTest {
@Autowired JobLauncherTestUtils utils;
@Test
void jobCompletes() throws Exception {
JobExecution exec = utils.launchJob();
assertThat(exec.getStatus()).isEqualTo(BatchStatus.COMPLETED);
}
}