Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Spring application hangs on shutdown with @Scheduled(cron=...) when custom ScheduledExecutorService bean is defined (Java 19+) #35316

Closed
Assignees
Labels
in: coreIssues in core modules (aop, beans, core, context, expression) type: bugA general bug
Milestone
@chengchen

Description

When a Spring Boot application defines its own ScheduledExecutorService bean (e.g. via Executors.newSingleThreadScheduledExecutor()), the application hangs indefinitely after receiving a SIGTERM signal if there are active @Scheduled(cron = ...) tasks.

This only occurs starting with Java 19, because ExecutorService now implements AutoCloseable.
Spring detects the bean as AutoCloseable and calls close() during context shutdown. However, if the executor is used for @Scheduled cron jobs, it waits for the recurring tasks to finish — which never happens — resulting in a stuck shutdown.

Steps to Reproduce:

  • Use Java 20 or higher
  • Create a Spring Boot app with:
@SpringBootApplication
@EnableScheduling
public class DemoApp implements SchedulingConfigurer {
	public static void main(String[] args) {
		SpringApplication.run(DemoApp.class, args);
	}
	@Override
	public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
		taskRegistrar.setScheduler(taskExecutor());
	}
	@Bean
	public Executor taskExecutor() {
		return Executors.newSingleThreadScheduledExecutor();
	}
	@Scheduled(cron = "* 0 * * * *")
	public void runJob() {
		System.out.println("Running job...");
	}
}
  • Run the application
  • Send a SIGTERM (e.g. kill -15 <pid>)
  • Observe that the application does not exit

Expected behavior:
Spring should shut down cleanly, cancelling or stopping recurring tasks using the executor.

Actual behavior:
Shutdown hangs indefinitely, because the executor’s close() waits for the cron task to complete, but the task is recurring and never terminates.

Potential workarounds:

  • Let Spring define its default TaskScheduler, it's handled properly by calling shutdownNow().
  • Annotate the executor with @Bean(destroyMethod = "shutdownNow")

Suggestion:
Maybe a better approach would be always handling the custom ScheduledExecutorService the same way as localExecutor in ScheduledTaskRegistrar? But in this case, we don't cover custom TaskScheduler case... Any idea or suggestions are welcome 🙏

Metadata

Metadata

Labels

in: coreIssues in core modules (aop, beans, core, context, expression) type: bugA general bug

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

    AltStyle によって変換されたページ (->オリジナル) /