The auto-configuration for Spring Batch uses the SimpleJobLauncher with SyncTaskExecutor, which is the default. Consequently, Batch jobs are run on the same thread they are launched on, even if it is a Tomcat worker thread. I find this surprising, considering that Spring Boot typically employs sensible defaults, and I have not seen it mentioned in the docs (or in any issue). Furthermore, I expected that Spring Boot would pick up the auto-configured TaskExecutor, but it does not.

https://github.com/spring-projects/spring-boot/blob/56595c00278f1284c4889915e73d279cc4b20fdd/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/batch/BasicBatchConfigurer.java#L119-L124

If it was a conscious decision to use the SimpleJobLauncher with its default task executor, it would be nice if it were documented. Ideally, the docs would also offer some guidance on properly configuring Spring Batch with a different task executor (I expect the answer is to extend BasicBatchConfigurer and to override createJobLauncher()) and whether it's appropriate to use the auto-configured TaskExecutor.

Otherwise, I think it would make sense to change BasicBatchConfigurer to either pick up the auto-configured TaskExecutor, possibly introducing an annotation modelled after @BatchDataSource that allows to configure a dedicated TaskExecutor for batch jobs easily.

Comment From: wilkinsona

@benas What do you consider to be a sensible default for Batch's TaskExecutor?

Comment From: fmbenhassine

I think the default should be a synchronous task executor as it is now. Changing the default to an asynchronous task executor would probably make a non-web boot app running a batch job exit without waiting for the job to finish. Executing batch jobs in servlet containers running 24/7 is actually not the recommended way and was one of the main reasons for deprecating Spring Batch Admin in favor of the single-job containerized boot apps orchestrated by Spring Cloud Dataflow. That's why I think the default should be in line with the recommended packaging/execution model.

That said, I see that boot docs redirect to the docs of @EnableBatchProcessing for details about Batch's defaults, and I noticed that the defaults are not clearly documented there, so I created https://github.com/spring-projects/spring-batch/issues/3993 to improve that on the Batch side.

Comment From: wilkinsona

Thanks very much, @benas. I'll close this in favor of the Batch issue you've created.

Comment From: aahlenst

@benas Thanks a lot for the insight. But reading https://docs.spring.io/spring-batch/docs/4.3.x/reference/html/index-single.html#runningJobsFromWebContainer, it says:

However, there are many cases where launching from an HttpRequest is a better option. Many such use cases include reporting, ad-hoc job running, and web application support. Because a batch job by definition is long running, the most important concern is ensuring to launch the job asynchronously.

I believe that both approaches are valid (application per job and launching from an HttpRequest). But, as I read the docs, the current configuration is geared towards the application per job model, but it's neither explained nor guidance is offered how to reconfigure Boot (or Batch) to support either model.

Comment From: fmbenhassine

Yes, both approaches are valid. I just wanted to mention that the web-based monolithic packaging model is not recommended (for reasons like mixed logs, limited scalability, etc). While not explicitly mentioned in the docs, the recommended approach is the one used in the getting started guide, hopefully guiding users to the right direction. If you think this is not enough, feel free to open a PR to improve the docs in that regard. Do not hesitate to reach out if you need support in your migration, we would be happy to help!

Comment From: vpavic

I just wanted to mention that the web-based monolithic packaging model is not recommended

Personally I'm not a fan of this - a framework like Spring Batch shouldn't impact users' architectural decisions to a degree that it suggests either monolithic or micro-service approach. If it does, it's becoming more geared towards the Spring Cloud ecosystem, than the core Spring ecosystem (basically everything between Spring Framework and Spring Boot) it has originally grown from.

To my knowledge Spring Boot's documentation has zero mentions of micro-services (which I applaud) and would therefore expect its auto-configuration facilities to be equally supportive of all architectural styles, so I share concerns expressed by @aahlenst. Historically I've worked on monolithic projects that used Spring Batch with success, and still perceive this as a valid approach that I'd use in future.