how to select which spring batch job to run based on application argument - spring boot java config
Solution 1
To run the jobs you like from the main method you can load the the required job configuration bean and the JobLauncher from the application context and then run it:
@ComponentScan
@EnableAutoConfiguration
public class ApplicationWithJobLauncher {
public static void main(String[] args) throws BeansException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException, JobParametersInvalidException, InterruptedException {
Log log = LogFactory.getLog(ApplicationWithJobLauncher.class);
SpringApplication app = new SpringApplication(ApplicationWithJobLauncher.class);
app.setWebEnvironment(false);
ConfigurableApplicationContext ctx= app.run(args);
JobLauncher jobLauncher = ctx.getBean(JobLauncher.class);
JobParameters jobParameters = new JobParametersBuilder()
.addDate("date", new Date())
.toJobParameters();
if("1".equals(args[0])){
//addNewPodcastJob
Job addNewPodcastJob = ctx.getBean("addNewPodcastJob", Job.class);
JobExecution jobExecution = jobLauncher.run(addNewPodcastJob, jobParameters);
} else {
jobLauncher.run(ctx.getBean("newEpisodesNotificationJob", Job.class), jobParameters);
}
System.exit(0);
}
}
What was causing my lots of confusion was that the second job were executed, even though the first job seemed to be "picked up" by the runner... Well the problem was that in both job's configuration file I used standard method names writer(), reader(), processor() and step()
and it used the ones from the second job that seemed to "overwrite" the ones from the first job without any warnings...
I used though an application config class with @EnableBatchProcessing(modular=true)
, that I thought would be used magically by Spring Boot :
@Configuration
@EnableBatchProcessing(modular=true)
public class AppConfig {
@Bean
public ApplicationContextFactory addNewPodcastJobs(){
return new GenericApplicationContextFactory(AddPodcastJobConfiguration.class);
}
@Bean
public ApplicationContextFactory newEpisodesNotificationJobs(){
return new GenericApplicationContextFactory(NotifySubscribersJobConfiguration.class);
}
}
I will write a blog post about it when it is ready, but until then the code is available at https://github.com/podcastpedia/podcastpedia-batch (work/learning in progress)..
Solution 2
Just set the "spring.batch.job.names=myJob" property. You could set it as SystemProperty when you launch your application (-Dspring.batch.job.names=myjob). If you have defined this property, spring-batch-starter will only launch the jobs, that are defined by this property.
amacoder
Updated on May 07, 2020Comments
-
amacoder about 4 years
I have two independent spring batch jobs in the same project because I want to use the same infrastructure-related beans. Everything is configured in Java. I would like to know if there's a proper way to start the jobs independent based for example on the first java app argument in the main method for example. If I run
SpringApplication.run
only the second job gets executed by magic. The main method looks like:@ComponentScan @EnableAutoConfiguration public class Application { public static void main(String[] args) { SpringApplication app = new SpringApplication(Application.class); app.setWebEnvironment(false); ApplicationContext ctx= app.run(args); } }
and the two jobs are configured as presented in the Spring Batch Getting Started tutorial on Spring.io. Here is the configuration file of the first job, the second being configured in the same way.
@Configuration @EnableBatchProcessing @Import({StandaloneInfrastructureConfiguration.class, ServicesConfiguration.class}) public class AddPodcastJobConfiguration { @Autowired private JobBuilderFactory jobs; @Autowired private StepBuilderFactory stepBuilderFactory; //reader, writer, processor... }
To enable modularization I created an AppConfig class, where I define factories for the two jobs:
@Configuration @EnableBatchProcessing(modular=true) public class AppConfig { @Bean public ApplicationContextFactory addNewPodcastJobs(){ return new GenericApplicationContextFactory(AddPodcastJobConfiguration.class); } @Bean public ApplicationContextFactory newEpisodesNotificationJobs(){ return new GenericApplicationContextFactory(NotifySubscribersJobConfiguration.class); } }
P.S. I am new to Spring configuration in Java configuration Spring Boot and Spring Batch...
-
amacoder almost 10 yearsThanks Luca, but I didn't have any success with the CommandLineJobRunner either...
-
amacoder over 9 yearsAs promised, blog post is there Spring Batch Tutorial with Spring Boot and Java Configuration
-
Pino almost 6 yearsThis is the right answer when using Spring-batch with Spring-boot. Of course it assumes that
BatchAutoConfiguration
has not been disabled (it creates aJobLauncherCommandLineRunner
and passes the job names to it).