Application stuck on shutdown if ConcurrentTaskScheduler
is used and application has startup error.
Reproducer repository: https://github.com/alexey-anufriev/spring-shutdown-stuck-with-custom-scheduler
Readme: https://github.com/alexey-anufriev/spring-shutdown-stuck-with-custom-scheduler/blob/master/README.md
Comment From: snicoll
That sounds like the expected behavior to me. The non-working example is creating a task scheduler manually. You're then responsible to shut it down, which happens automatically when exposed as a @Bean
.
Comment From: alexey-anufriev
hi @snicoll,
here is attempt to fix it: https://github.com/alexey-anufriev/spring-shutdown-stuck-with-custom-scheduler/commit/828bf9f71b6e592030c9b0cb856eccb8a93bf57a
but the behavior is still the same
Comment From: philwebb
@alexey-anufriev I'm trying to reproduce the error, but I can't get it to fail in the IDE or by using java -jar
. I do see things hang when using ./mvnw spring-boot:run
. Are you seeing the problem in production, or is it only when using ./mvnw spring-boot:run
?
Comment From: alexey-anufriev
@philwebb, you can check my README: https://github.com/alexey-anufriev/spring-shutdown-stuck-with-custom-scheduler/blob/master/README.md
or just run ./mvnw clean spring-boot:run -Dspring-boot.run.profiles=non-working
it is important to have a profile enabled.
Comment From: philwebb
@alexey-anufriev I did that and replicated the problem when using ./mvnw spring-boot:run
but I'm trying to find out if the problem happens outside of that. When I tried java -jar -Dspring-boot.run.profiles=non-working ./target/spring-shutdown-stuck-0.0.1-SNAPSHOT.jar
the application didn't hang. Neither did it hang in the IDE with that profile active.
Comment From: snicoll
@philwebb that's because -Dspring-boot.run.profiles
is specific to the Maven plugin. Setting that property in your IDE or when invoking a repackaged archive has no effect.
@alexey-anufriev my initial comment still stands. ConcurrentTaskScheduler
is primarily meant for wrapping an existing ScheduledExecutorService
. The default constructor though creates an internal default executor, with no way to shut it down. In your custom arrangement, we'd really recommend you to use ThreadPoolTaskScheduler
. If you insist on using ConcurrentTaskScheduler
then you should use the constructor that takes a ScheduledExecutorService
and shut it down yourself.
I've created https://github.com/spring-projects/spring-framework/issues/27914 to improve things in that area.
Comment From: alexey-anufriev
@snicoll, my initial thought was that spring boot just missed to close ConcurrentTaskScheduler
but it turns out that this is rather a limitation of ConcurrentTaskScheduler
. In any case, thank you for the issue you created and for the explanations.