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
@@ -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);
}
}