I am upgrading to Spring Batch 5 / Spring Boot 3 / Jakarta 10. With Spring Batch 5, @EnableBatchProcessing(modular=true)
does not behave as before, as it now disables the Auto-Configuration of Spring Batch, meaning I'd have to configure nearly everything myself that was configured by Spring Batch before.
I'd like to avoid this (because I assume it requires far more effort) so I have to remove the @EnableBatchProcessing(modular=true)
from my application and somehow modularize the contexts manually.
I have a Batch Application with 4 jobs, more are likely to be added. Each job defines its own typical beans, like
I basically need to have the whole configuration of the individual jobs modularized, so that all of the beans live in their own contexts and beans that are created by other jobs should not be found. For example, the step()
method in the configuration of the job job-a
, namely BatchJobAConfiguration.class
, injects a bean of type Resource
. The job job-b
also defines a bean of type Resource
, but the beans should live in different contexts so the application does not crash with an error like
Parameter 2 of method step in path.to.my.batch.jobs.BatchJobAConfiguration required a single bean, but 2 were found:
Probably, I could simply give each of my beans a @Qualifier
and use it to prevent this type of error from occuring but, assuming this actually works, considering I already have 4 jobs and more are likely to be added I don't think this is the right way to do it. I would have to place like 15 @Qualifier
s or so.
Here is my current setup from before the update to Spring Batch 5. Please note that I cannot share the actual code because this is company code and thus i cannot share it here.
@SpringBootApplication
@EnableJpaRepositories("path.to.my.repositories")
@EntityScan("path.to.my.entities")
@EnableTask
public class MyBatchApplication{
public static void main(String[] args) {
System.exit(SpringApplication.exit(SpringApplication.run(MyBatchApplication.class, args)));
}
}
This is my config
@Configuration
@EnableBatchProcessing(modular = true)
public class MyModularBatchJobContextConfiguration {
@Bean
ApplicationContextFactory getJobAContext() {
return new GenericApplicationContextFactory(BatchJobAConfiguration.class);
}
@Bean
ApplicationContextFactory getJobBContext() {
return new GenericApplicationContextFactory(BatchJobBConfiguration.class);
}
// More jobs ...
}
public class BatchJobAConfiguration {
private static final String MY_JOB_NAME = "job-a"
@Autowired
private EntityManagerFactory emf;
@Bean
public Job jobA(JobRepository jobRepository, Step myStep) {
return new JobBuilder(MY_JOB_NAME, jobRepository)
.flow(myStep)
.end()
.build();
}
@Bean
public Step myStep(JpaTransactionManager transactionManager,
JobRepository jobRepository,
FlatFileItemReader<MyEntity> reader,
ItemProcessor<MyEntity, MyEntity> processor,
JpaItemWriter<MyEntity> entityWriter) {
return new StepBuilder(MY_STEP_NAME, jobRepository)
.<MyEntity, MyEntity>chunk(10, transactionManager)
.reader(reader)
.processor(processor)
.writer(plzOrtEntityWriter)
.transactionManager(transactionManager)
.build();
}
@Bean
JpaTransactionManager jobATransactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
// Reader, Writer, Processor...
Add the same time, I want to execute these jobs both from the IDE / CommandLine and from Spring Cloud Dataflow. Hence, the @EnableTask
on the application class. But I would be already happy if I could make it work from IDE / CommandLine.
Before the update to Spring Boot 3, this setup worked like a charm.
Right now, after the update to Spring Batch 5, the Application basically does not run any job when I start it. Which makes sense, as the auto configuration is turned off.
Removing @EnableBatchProcessing(modular=true)
and MyModularBatchJobContextConfiguration
and annotating my Batch job configuration classes with @Configuration
now causes several bean clashes, which also makes sense because now all the beans are no longer present in their own isolated context.
How can i migrate my setup to Spring Batch 5 without @EnableBatchProcessing(modular = true)
so my setup works again?
Keeping EnableBatchProcessing(modular = true)
is also an option, but I am not sure what I have to configure myself now in order to make it work.
Thanks in Advance!
I solved my problem by removing EnableBatchProcessing(modular = true)
(by deleting MyModularBatchJobContextConfiguration
), re-adding @Configuration
to my batch job configuration classes and adding @ConditionalOnProperty("spring.batch.job.name", havingValue=<job-name-goes-here>)
to each of them.
This way, the configuration only gets initialized when the job is started with --spring.batch.job.name=
. All other job configurations will not be initialized, thus the beans from other jobs won't get created.