Spring Boot starter that provides comprehensive batch processing capabilities for enterprise Java applications with auto-configuration, job management, and database integration.
—
Spring Boot Batch Starter provides automatic job execution capabilities with application startup integration, exit code generation, and comprehensive job lifecycle management.
Automatically executes batch jobs on application startup with configurable job selection and parameter passing.
/**
* ApplicationRunner that automatically launches batch jobs on application startup.
* Supports job selection, parameter conversion, and integration with Spring Boot lifecycle.
*/
public class JobLauncherApplicationRunner implements ApplicationRunner, InitializingBean {
/**
* Default execution order for the job launcher runner
*/
public static final int DEFAULT_ORDER = 0;
/**
* Constructor for automatic job execution with default configuration
*/
public JobLauncherApplicationRunner(
JobLauncher jobLauncher,
JobExplorer jobExplorer,
JobRepository jobRepository);
/**
* Executes configured batch jobs with command-line arguments as job parameters
* @param args Application arguments that can be converted to job parameters
* @throws Exception if job execution fails
*/
public void run(ApplicationArguments args) throws Exception;
/**
* Executes configured batch jobs with string arguments
* @param args String arguments that can be converted to job parameters
* @throws JobExecutionException if job execution fails
*/
public void run(String... args) throws JobExecutionException;
/**
* Sets the specific job name to execute on startup
* @param jobName Name of the job to execute (must match a bean name)
*/
public void setJobName(String jobName);
/**
* Sets custom job parameters converter for argument processing
* @param converter Custom converter for transforming arguments to job parameters
*/
public void setJobParametersConverter(JobParametersConverter converter);
/**
* Sets the execution order relative to other ApplicationRunners
* @param order Execution order (lower values execute first)
*/
public void setOrder(int order);
/**
* Gets the execution order of this runner
* @return Current execution order
*/
public int getOrder();
/**
* Sets the job registry for looking up registered jobs
* @param jobRegistry Registry containing job definitions
*/
public void setJobRegistry(JobRegistry jobRegistry);
/**
* Sets the collection of job beans available for execution
* @param jobs Collection of job beans
*/
public void setJobs(Collection<Job> jobs);
/**
* Sets the application event publisher for publishing job execution events
* @param publisher Event publisher for job events
*/
public void setApplicationEventPublisher(ApplicationEventPublisher publisher);
/**
* Validates the runner configuration after properties are set
* @throws IllegalStateException if configuration is invalid
*/
public void afterPropertiesSet() throws IllegalStateException;
/**
* @deprecated since 3.0.10 for removal, use afterPropertiesSet() instead
*/
@Deprecated(since = "3.0.10", forRemoval = true)
public void validate();
/**
* Executes a specific job with given parameters
* @param job The job to execute
* @param jobParameters Parameters for job execution
* @throws JobExecutionAlreadyRunningException if job is already running
* @throws JobRestartException if job restart fails
* @throws JobInstanceAlreadyCompleteException if job instance is already complete
* @throws JobParametersInvalidException if job parameters are invalid
*/
protected void execute(Job job, JobParameters jobParameters)
throws JobExecutionAlreadyRunningException, JobRestartException,
JobInstanceAlreadyCompleteException, JobParametersInvalidException;
/**
* Launches jobs based on properties configuration
* @param properties Properties containing job configuration
* @throws JobExecutionException if job execution fails
*/
protected void launchJobFromProperties(Properties properties) throws JobExecutionException;
}Usage Examples:
@SpringBootApplication
public class BatchApplication {
@Bean
public Job dailyReportJob(JobRepository jobRepository, Step reportStep) {
return new JobBuilder("dailyReportJob", jobRepository)
.start(reportStep)
.build();
}
// Job runs automatically on startup with default configuration
public static void main(String[] args) {
SpringApplication.run(BatchApplication.class, args);
}
}
// Run with custom job parameters
java -jar myapp.jar --inputFile=data.csv --outputDir=results/Customize job execution behavior through bean configuration:
@Configuration
public class BatchJobConfiguration {
@Bean
public JobLauncherApplicationRunner customJobRunner(
JobLauncher jobLauncher,
JobExplorer jobExplorer,
JobRepository jobRepository) {
JobLauncherApplicationRunner runner = new JobLauncherApplicationRunner(
jobLauncher, jobExplorer, jobRepository);
// Configure specific job to run
runner.setJobName("mySpecificJob");
// Set custom job parameters
JobParameters params = new JobParametersBuilder()
.addString("environment", "production")
.addLong("timestamp", System.currentTimeMillis())
.toJobParameters();
runner.setJobParameters(params);
// Set execution order
runner.setOrder(1);
return runner;
}
}Generates application exit codes based on batch job execution results, enabling proper integration with external job schedulers and monitoring systems.
/**
* Generates application exit codes based on job execution results.
* Implements both ApplicationListener for job events and ExitCodeGenerator for Spring Boot.
*/
public class JobExecutionExitCodeGenerator
implements ApplicationListener<JobExecutionEvent>, ExitCodeGenerator {
/**
* Handles job execution events to track job results
* @param event Job execution event containing execution details
*/
public void onApplicationEvent(JobExecutionEvent event);
/**
* Generates exit code based on accumulated job execution results
* @return Exit code (0 for success, positive integers for various failure types)
*/
public int getExitCode();
}Exit Code Mapping:
// Exit codes correspond to BatchStatus ordinal values:
// 0 = COMPLETED (success)
// 1 = STARTING
// 2 = STARTED
// 3 = STOPPING
// 4 = STOPPED
// 5 = FAILED
// 6 = ABANDONED
// 7 = UNKNOWNUsage Examples:
@SpringBootApplication
public class BatchApplication {
public static void main(String[] args) {
System.exit(SpringApplication.exit(
SpringApplication.run(BatchApplication.class, args)));
}
@Bean
public Job riskyJob(JobRepository jobRepository, Step riskyStep) {
return new JobBuilder("riskyJob", jobRepository)
.start(riskyStep)
.build();
}
}
// Shell script can check exit codes
#!/bin/bash
java -jar batch-app.jar
EXIT_CODE=$?
if [ $EXIT_CODE -eq 0 ]; then
echo "Batch job completed successfully"
elif [ $EXIT_CODE -eq 5 ]; then
echo "Batch job failed"
exit 1
fiSpring application event that encapsulates job execution information for event-driven batch processing.
/**
* Spring ApplicationEvent that wraps JobExecution for event-driven processing
*/
public class JobExecutionEvent extends ApplicationEvent {
/**
* Creates a new job execution event
* @param execution The job execution that triggered this event
*/
public JobExecutionEvent(JobExecution execution);
/**
* Returns the job execution associated with this event
* @return JobExecution containing execution details, status, and metadata
*/
public JobExecution getJobExecution();
}Usage Examples:
@Component
public class BatchJobEventListener {
@EventListener
public void handleJobExecution(JobExecutionEvent event) {
JobExecution jobExecution = event.getJobExecution();
System.out.println("Job: " + jobExecution.getJobInstance().getJobName());
System.out.println("Status: " + jobExecution.getStatus());
System.out.println("Start Time: " + jobExecution.getStartTime());
System.out.println("End Time: " + jobExecution.getEndTime());
if (jobExecution.getStatus() == BatchStatus.FAILED) {
// Handle job failure - send alerts, log errors, etc.
handleJobFailure(jobExecution);
}
}
private void handleJobFailure(JobExecution jobExecution) {
// Custom failure handling logic
List<Throwable> failureExceptions = jobExecution.getFailureExceptions();
for (Throwable exception : failureExceptions) {
System.err.println("Job failed with: " + exception.getMessage());
}
}
}Automatic conversion of command-line arguments to job parameters with customization options.
/**
* Interface for converting application arguments to job parameters
*/
public interface JobParametersConverter {
/**
* Converts properties to JobParameters
* @param properties Input properties (typically from command line)
* @return JobParameters for job execution
*/
JobParameters getJobParameters(Properties properties);
/**
* Converts JobParameters back to properties
* @param params JobParameters to convert
* @return Properties representation
*/
Properties getProperties(JobParameters params);
}Custom Parameter Converter:
@Component
public class CustomJobParametersConverter implements JobParametersConverter {
@Override
public JobParameters getJobParameters(Properties properties) {
JobParametersBuilder builder = new JobParametersBuilder();
// Convert string properties to typed parameters
for (String key : properties.stringPropertyNames()) {
String value = properties.getProperty(key);
if (key.endsWith(".date")) {
try {
Date date = DateFormat.getDateInstance().parse(value);
builder.addDate(key.replace(".date", ""), date);
} catch (ParseException e) {
builder.addString(key, value);
}
} else if (key.endsWith(".long")) {
try {
long longValue = Long.parseLong(value);
builder.addLong(key.replace(".long", ""), longValue);
} catch (NumberFormatException e) {
builder.addString(key, value);
}
} else {
builder.addString(key, value);
}
}
// Add timestamp for uniqueness
builder.addLong("run.timestamp", System.currentTimeMillis());
return builder.toJobParameters();
}
@Override
public Properties getProperties(JobParameters params) {
Properties properties = new Properties();
for (Map.Entry<String, JobParameter<?>> entry : params.getParameters().entrySet()) {
properties.setProperty(entry.getKey(), entry.getValue().toString());
}
return properties;
}
}When only one job bean exists, it runs automatically:
@SpringBootApplication
public class SingleJobApplication {
@Bean
public Job onlyJob(JobRepository jobRepository, Step step) {
return new JobBuilder("onlyJob", jobRepository)
.start(step)
.build();
}
// Runs automatically on startup
}When multiple jobs exist, specify which one to run:
# Required when multiple jobs are present
spring.batch.job.name=specificJobName@SpringBootApplication
public class MultiJobApplication {
@Bean
public Job job1(JobRepository jobRepository, Step step1) {
return new JobBuilder("job1", jobRepository).start(step1).build();
}
@Bean
public Job job2(JobRepository jobRepository, Step step2) {
return new JobBuilder("job2", jobRepository).start(step2).build();
}
// Without spring.batch.job.name property, application will fail to start
}Disable automatic execution and control jobs programmatically:
spring.batch.job.enabled=false@Component
public class ManualJobLauncher {
@Autowired
private JobLauncher jobLauncher;
@Autowired
private Job myJob;
public void runJobManually() throws Exception {
JobParameters params = new JobParametersBuilder()
.addLong("startedAt", System.currentTimeMillis())
.toJobParameters();
JobExecution execution = jobLauncher.run(myJob, params);
System.out.println("Job Status: " + execution.getStatus());
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-springframework-boot--spring-boot-starter-batch