英文:
Spring batch 5 does not start job automatically
问题
我正在将一个Spring Boot 2的作业升级到Spring Boot 3,同时也将Spring Batch升级到Spring Batch 5。
我遇到的问题是作业不再自动启动。这不是一个定时或异步作业,它只是作为一个JAR文件运行。如果可能的话,我希望以这种方式运行它(在以前的版本中运行良好):
java -jar MyJobApp.jar --batch.input-file="/path/to/file/filename.xml" --spring.config.additional-location=file:/path/to/config/externalPropertyFile.yml
我有自己的数据库表来记录批处理状态等信息,因此我需要配置作业要么不使用默认的批处理表,要么将它们放入内存数据库。我通过JobListener将我需要的内容持久化。
Spring迁移指南提到了这一点:“现在可以定义一个使用@EnableBatchProcessing
注解或扩展Batch的DefaultBatchConfiguration
的Bean,告诉自动配置不要再配置,允许应用完全控制Batch的配置。”
我猜这就是问题所在,但如前所述,我需要为JobRepository配置特定的数据源,我不确定如何在不使用这些配置选项的情况下实现这一点。
我的当前设置类似于以下方式:
@EnableConfigurationProperties(BatchProps::class, WebClientProps::class)
@SpringBootApplication
class MyJobApp
fun main(args: Array<String>) {
exitProcess(SpringApplication.exit(runApplication<MyJobApp>(*args)))
}
spring:
main:
web-application-type: none
application:
name: MyJobApp
batch:
job:
enabled: true
@Configuration
@EnableBatchProcessing(dataSourceRef = "batchDataSource", transactionManagerRef = "batchTransactionManager")
class BatchConfig(
private val reader: PackageDataReader,
private val processor: PackageDataProcessor,
private val writer: OrderWriter,
) {
@Bean
fun job(listener: JobNotificationListener,
jobRepository: JobRepository,
transactionManager: PlatformTransactionManager,
ioStep: Step): Job = JobBuilder(JOB_NAME, jobRepository)
.listener(listener)
.flow(ioStep)
.end()
.build()
@Bean
fun ioStep(jobRepository: JobRepository, transactionManager: PlatformTransactionManager): Step = StepBuilder(STEP_NAME, jobRepository)
.chunk<PackageData, List<OrderType>>(1, transactionManager)
.reader(reader)
.processor(processor)
.writer(writer)
.build()
// 我们不希望Spring批处理元数据表存在于我们的数据库中,所以我们将它们放入内存数据库
@Bean
fun batchDataSource(): DataSource {
return EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2)
.addScript("/org/springframework/batch/core/schema-h2.sql")
.generateUniqueName(true).build()
}
@Bean
fun batchTransactionManager(): JdbcTransactionManager? {
return JdbcTransactionManager(batchDataSource())
}
}
我尝试使用EnableBatchProcessing
来声明性地配置它,还尝试扩展DefaultBatchConfigurer
并重写getDataSource
和getTransactionManager
。我猜想我可以使用类似CommandLineRunner
的东西来手动启动作业,使用自动装配的JobLauncher,但这不感觉是正确的方法。作业在我的集成测试中正常运行,这些测试使用SimpleJobLauncher
通过JobLauncherTestUtils
。
运行作业时的日志:
2023-03-03T11:17:05.041+01:00 DEBUG 20592 --- [ main] MyJobApp : Running with Spring Boot v3.0.2, Spring v6.0.4
2023-03-03T11:17:05.041+01:00 INFO 20592 --- [ main] MyJobApp : The following 1 profile is active: "dev"
2023-03-03T11:17:05.611+01:00 INFO 20592 --- [ main] o.s.b.c.c.annotation.BatchRegistrar : Finished Spring Batch infrastructure beans configuration in 6 ms.
2023-03-03T11:17:07.133+01:00 INFO 20592 --- [ main] o.s.j.d.e.EmbeddedDatabaseFactory : Starting embedded database: url='jdbc:h2:mem:3df4e81c-eff0-45fc-a9f2-9b97f721b113;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false', username='sa'
2023-03-03T11:17:07.433+01:00 INFO 20592 --- [ main] o.s.b.c.r.s.JobRepositoryFactoryBean : No database type set, using meta data indicating: H2
2023-03-03T11:17:07.499+01:00 INFO 20592 --- [ main] .c.a.BatchObservabilityBeanPostProcessor : No Micrometer observation registry found, defaulting to ObservationRegistry.NOOP
2023-03-03T11:17:07.513+01:00 INFO 20592 --- [ main] .c.a.BatchObservabilityBeanPostProcessor : No Micrometer observation registry found, defaulting to ObservationRegistry.NOOP
2023-03-03T11:17:07.519+01:00 INFO 20592 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : No TaskExecutor has been set, defaulting to synchronous executor.
2023-03-03T11:17:07.743+01:00 INFO 20592 --- [ main] MyJobbApp : Started MyJobApp in 3.28 seconds (process running for 4.247)
2023-03-03T11:17:07.755+01:00 INFO 20592 --- [ main] o.s.j.d.e.EmbeddedDatabaseFactory : Shutting down embedded database: url='jdbc:h2:mem:3df4e81c-eff0-45fc-a9f2-9b97f721b113;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false'
Process finished with exit code 0
希望这些信息有所帮助。
英文:
I'm upgrading a job from spring boot 2 to spring boot 3, which also bumps spring batch to spring batch 5.
I'm having an issue where the job no longer starts automatically. This is not a scheduled or asynchronous job, it's simply run as a jar. Preferably I'd run it something like this if possible(which worked fine in previous versions):
java -jar MyJobApp.jar --batch.input-file="/path/to/file/filename.xml" --spring.config.additional-location=file:/path/to/config/externalPropertyFile.yml
I have my own database tables for logging batch statuses etc, so I need to configure the job to either not use the default batch tables at all, or alternatively just stick them into an in-memory db. I'm persisting what I need through a JobListener.
The spring migration guide mentions this "A bean that is annotated with @EnableBatchProcessing
or that extends Batch’s DefaultBatchConfiguration
can now be defined to tell the auto-configuration to back off, allowing the application to take complete control of how Batch is configured."
I'm assuming this is the issue, but as mentioned I need to configure a datasource specific for the JobRepository, and I'm unsure how I can achieve this without using any of these configuration options.
My current setup is something like this:
@EnableConfigurationProperties(BatchProps::class, WebClientProps::class)
@SpringBootApplication
class MyJobApp
fun main(args: Array<String>) {
exitProcess(SpringApplication.exit(runApplication<MyJobApp>(*args)))
}
spring:
main:
web-application-type: none
application:
name: MyJobApp
batch:
job:
enabled: true
@Configuration
@EnableBatchProcessing(dataSourceRef = "batchDataSource", transactionManagerRef = "batchTransactionManager")
class BatchConfig(
private val reader: PackageDataReader,
private val processor: PackageDataProcessor,
private val writer: OrderWriter,
) {
@Bean
fun job(listener: JobNotificationListener,
jobRepository: JobRepository,
transactionManager: PlatformTransactionManager,
ioStep: Step): Job = JobBuilder(JOB_NAME, jobRepository)
.listener(listener)
.flow(ioStep)
.end()
.build()
@Bean
fun ioStep(jobRepository: JobRepository, transactionManager: PlatformTransactionManager): Step = StepBuilder(STEP_NAME, jobRepository)
.chunk<PackageData, List<OrderType>>(1, transactionManager)
.reader(reader)
.processor(processor)
.writer(writer)
.build()
// We don't want the spring batch metadata tables in our db, so we just stick these into an in-memory db
@Bean
fun batchDataSource(): DataSource {
return EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2)
.addScript("/org/springframework/batch/core/schema-h2.sql")
.generateUniqueName(true).build()
}
@Bean
fun batchTransactionManager(): JdbcTransactionManager? {
return JdbcTransactionManager(batchDataSource())
}
}
I've tried using EnableBatchProcessing
to configure it declaratively, and I've tried extending DefaultBatchConfigurer
and overriding getDataSource
and getTransactionManager
. I'm assuming I could use something like a CommandLineRunner
to manually launch the job with an autowired JobLauncher, but this does not feel like the correct way of doing it. The job runs fine in my integration tests which uses a SimpleJobLauncher
through JobLauncherTestUtils
.
Logs when running the job:
2023-03-03T11:17:05.041+01:00 DEBUG 20592 --- [ main] MyJobApp : Running with Spring Boot v3.0.2, Spring v6.0.4
2023-03-03T11:17:05.041+01:00 INFO 20592 --- [ main] MyJobApp : The following 1 profile is active: "dev"
2023-03-03T11:17:05.611+01:00 INFO 20592 --- [ main] o.s.b.c.c.annotation.BatchRegistrar : Finished Spring Batch infrastructure beans configuration in 6 ms.
2023-03-03T11:17:07.133+01:00 INFO 20592 --- [ main] o.s.j.d.e.EmbeddedDatabaseFactory : Starting embedded database: url='jdbc:h2:mem:3df4e81c-eff0-45fc-a9f2-9b97f721b113;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false', username='sa'
2023-03-03T11:17:07.433+01:00 INFO 20592 --- [ main] o.s.b.c.r.s.JobRepositoryFactoryBean : No database type set, using meta data indicating: H2
2023-03-03T11:17:07.499+01:00 INFO 20592 --- [ main] .c.a.BatchObservabilityBeanPostProcessor : No Micrometer observation registry found, defaulting to ObservationRegistry.NOOP
2023-03-03T11:17:07.513+01:00 INFO 20592 --- [ main] .c.a.BatchObservabilityBeanPostProcessor : No Micrometer observation registry found, defaulting to ObservationRegistry.NOOP
2023-03-03T11:17:07.519+01:00 INFO 20592 --- [ main] o.s.b.c.l.support.SimpleJobLauncher : No TaskExecutor has been set, defaulting to synchronous executor.
2023-03-03T11:17:07.743+01:00 INFO 20592 --- [ main] MyJobbApp : Started MyJobApp in 3.28 seconds (process running for 4.247)
2023-03-03T11:17:07.755+01:00 INFO 20592 --- [ main] o.s.j.d.e.EmbeddedDatabaseFactory : Shutting down embedded database: url='jdbc:h2:mem:3df4e81c-eff0-45fc-a9f2-9b97f721b113;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false'
Process finished with exit code 0
Any help would be appreciated.
答案1
得分: 2
这是正确的。在Spring Boot 3中,当添加@EnableBatchProcessing
或扩展DefaultBatchConfiguration
时,批处理自动配置(包括启动时的自动作业执行)会被禁用。
英文:
That's correct. With Spring Boot 3, the batch auto-configuration (including the automatic job execution at startup) is disabled when adding @EnableBatchProcessing
or extending DefaultBatchConfiguration
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论