'Spring Boot 2 preventing Tomcat 9 from shutting down

I am having an issue where a Tomcat server fails to shut down correctly when it has a Spring Boot web application. This causes issues with scheduled tasks and batch scripts.

Configuration details:

  • Tomcat version: 9.0.62.0
  • Java version: 17.0.2+8-LTS-86
  • Spring boot version: 2.5.12
  • Operating System (development): Windows 10

The Spring Boot application has several dependencies, including security, jdbc (with 2 data sources, one from Oracle and the other from MS SQL), cache and mail.

This is a brand new Tomcat installation. i.e. I just downloaded it from the website, unzipped it and placed the web application in the webapps folder

As a sanity check, I ran the tomcat server without the Spring Boot application and the shutdown runs correctly.

When I run catalina start, a new tomcat window opens with output from the tomcat server (i.e. startup, logs etc.)

When I run catalina stop, the tomcat window shows the following but does not close : NOTE: test17 is the name of my Spring Boot web application

18-Apr-2022 14:10:10.960 INFO [main] org.apache.catalina.core.StandardServer.await A valid shutdown command was received via the shutdown port. Stopping the Server instance.
18-Apr-2022 14:10:10.961 INFO [main] org.apache.coyote.AbstractProtocol.pause Pausing ProtocolHandler ["http-nio-8080"]
18-Apr-2022 14:10:10.975 INFO [main] org.apache.catalina.core.StandardService.stopInternal Stopping service [Catalina]
2022-04-18 14:10:10.988  INFO 9220 --- [           main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopping...
2022-04-18 14:10:10.988  INFO 9220 --- [           main] o.s.m.s.b.SimpleBrokerMessageHandler     : BrokerAvailabilityEvent[available=false, SimpleBrokerMessageHandler [org.springframework.messaging.simp.broker.DefaultSubscriptionRegistry@69609372]]
2022-04-18 14:10:10.989  INFO 9220 --- [           main] o.s.m.s.b.SimpleBrokerMessageHandler     : Stopped.
2022-04-18 14:10:10.996  INFO 9220 --- [           main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2022-04-18 14:10:10.996  INFO 9220 --- [           main] c.z.h.HikariDataSource                   : HikariPool-2 - Shutdown initiated...
2022-04-18 14:10:11.011  INFO 9220 --- [           main] c.z.h.HikariDataSource                   : HikariPool-2 - Shutdown completed.
2022-04-18 14:10:11.012  INFO 9220 --- [           main] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2022-04-18 14:10:11.012  INFO 9220 --- [           main] c.z.h.HikariDataSource                   : HikariPool-1 - Shutdown initiated...
2022-04-18 14:10:11.014  INFO 9220 --- [           main] c.z.h.HikariDataSource                   : HikariPool-1 - Shutdown completed.
18-Apr-2022 14:10:11.047 WARNING [main] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [myapp17] appears to have started a thread named [ThreadPoolTaskScheduler-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
 [email protected]/jdk.internal.misc.Unsafe.park(Native Method)
 [email protected]/java.util.concurrent.locks.LockSupport.park(LockSupport.java:341)
 [email protected]/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506)
 [email protected]/java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3463)
 [email protected]/java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3434)
 [email protected]/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623)
 [email protected]/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1177)
 [email protected]/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:899)
 [email protected]/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)
 [email protected]/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1122)
 [email protected]/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
 [email protected]/java.lang.Thread.run(Thread.java:833)
18-Apr-2022 14:10:11.048 WARNING [main] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [myapp17] appears to have started a thread named [ThreadPoolTaskScheduler-2] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
 [email protected]/jdk.internal.misc.Unsafe.park(Native Method)
 [email protected]/java.util.concurrent.locks.LockSupport.park(LockSupport.java:341)
 [email protected]/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506)
 [email protected]/java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3463)
 [email protected]/java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3434)
 [email protected]/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623)
 [email protected]/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1177)
 [email protected]/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:899)
 [email protected]/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)
 [email protected]/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1122)
 [email protected]/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
 [email protected]/java.lang.Thread.run(Thread.java:833)
18-Apr-2022 14:10:11.053 WARNING [main] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [myapp17] appears to have started a thread named [ThreadPoolTaskScheduler-3] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
 [email protected]/jdk.internal.misc.Unsafe.park(Native Method)
 [email protected]/java.util.concurrent.locks.LockSupport.park(LockSupport.java:341)
 [email protected]/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506)
 [email protected]/java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3463)
 [email protected]/java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3434)
 [email protected]/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623)
 [email protected]/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1177)
 [email protected]/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:899)
 [email protected]/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)
 [email protected]/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1122)
 [email protected]/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
 [email protected]/java.lang.Thread.run(Thread.java:833)
18-Apr-2022 14:10:11.054 WARNING [main] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [myapp17] appears to have started a thread named [ThreadPoolTaskScheduler-4] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
 [email protected]/jdk.internal.misc.Unsafe.park(Native Method)
 [email protected]/java.util.concurrent.locks.LockSupport.park(LockSupport.java:341)
 [email protected]/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506)
 [email protected]/java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3463)
 [email protected]/java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3434)
 [email protected]/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623)
 [email protected]/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1177)
 [email protected]/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:899)
 [email protected]/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)
 [email protected]/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1122)
 [email protected]/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
 [email protected]/java.lang.Thread.run(Thread.java:833)
18-Apr-2022 14:10:11.055 WARNING [main] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [myapp17] appears to have started a thread named [ThreadPoolTaskScheduler-5] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
 [email protected]/jdk.internal.misc.Unsafe.park(Native Method)
 [email protected]/java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:252)
 [email protected]/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:1672)
 [email protected]/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1182)
 [email protected]/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:899)
 [email protected]/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)
 [email protected]/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1122)
 [email protected]/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
 [email protected]/java.lang.Thread.run(Thread.java:833)
18-Apr-2022 14:10:11.055 WARNING [main] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [myapp17] appears to have started a thread named [ThreadPoolTaskScheduler-6] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
 [email protected]/jdk.internal.misc.Unsafe.park(Native Method)
 [email protected]/java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:252)
 [email protected]/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:1672)
 [email protected]/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1182)
 [email protected]/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:899)
 [email protected]/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)
 [email protected]/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1122)
 [email protected]/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
 [email protected]/java.lang.Thread.run(Thread.java:833)
18-Apr-2022 14:10:11.056 WARNING [main] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [myapp17] appears to have started a thread named [ThreadPoolTaskScheduler-7] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
 [email protected]/jdk.internal.misc.Unsafe.park(Native Method)
 [email protected]/java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:252)
 [email protected]/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:1672)
 [email protected]/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1182)
 [email protected]/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:899)
 [email protected]/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)
 [email protected]/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1122)
 [email protected]/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
 [email protected]/java.lang.Thread.run(Thread.java:833)
18-Apr-2022 14:10:11.056 WARNING [main] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [myapp17] appears to have started a thread named [ThreadPoolTaskScheduler-8] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
 [email protected]/jdk.internal.misc.Unsafe.park(Native Method)
 [email protected]/java.util.concurrent.locks.LockSupport.park(LockSupport.java:341)
 [email protected]/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(AbstractQueuedSynchronizer.java:506)
 [email protected]/java.util.concurrent.ForkJoinPool.unmanagedBlock(ForkJoinPool.java:3463)
 [email protected]/java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3434)
 [email protected]/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1623)
 [email protected]/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1177)
 [email protected]/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:899)
 [email protected]/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)
 [email protected]/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1122)
 [email protected]/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
 [email protected]/java.lang.Thread.run(Thread.java:833)
18-Apr-2022 14:10:11.057 WARNING [main] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [myapp17] appears to have started a thread named [ThreadPoolTaskScheduler-9] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
 [email protected]/jdk.internal.misc.Unsafe.park(Native Method)
 [email protected]/java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:252)
 [email protected]/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:1672)
 [email protected]/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1182)
 [email protected]/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:899)
 [email protected]/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)
 [email protected]/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1122)
 [email protected]/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
 [email protected]/java.lang.Thread.run(Thread.java:833)
18-Apr-2022 14:10:11.057 WARNING [main] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [myapp17] appears to have started a thread named [ThreadPoolTaskScheduler-10] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
 [email protected]/jdk.internal.misc.Unsafe.park(Native Method)
 [email protected]/java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:252)
 [email protected]/java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:1672)
 [email protected]/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1182)
 [email protected]/java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:899)
 [email protected]/java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1062)
 [email protected]/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1122)
 [email protected]/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
 [email protected]/java.lang.Thread.run(Thread.java:833)
18-Apr-2022 14:10:11.058 SEVERE [main] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [myapp17] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@265c741]) and a value of type [java.lang.Class] (value [class oracle.sql.AnyDataFactory]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
18-Apr-2022 14:10:11.058 SEVERE [main] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [myapp17] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@20d8d02d]) and a value of type [java.lang.Class] (value [class oracle.sql.TypeDescriptorFactory]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
18-Apr-2022 14:10:11.067 INFO [main] org.apache.coyote.AbstractProtocol.stop Stopping ProtocolHandler ["http-nio-8080"]
18-Apr-2022 14:10:11.080 INFO [main] org.apache.coyote.AbstractProtocol.destroy Destroying ProtocolHandler ["http-nio-8080"]

Any ideas what may be preventing Tomcat from properly shutting down? Does it have something to do with all these memory leak warnings?

UPDATE 1

Here is the code where I create my ThreadPoolTaskScheduler

import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;

@Configuration
public class SchedulingConfigurerConfiguration implements SchedulingConfigurer {

    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
        taskScheduler.setPoolSize(10);
        taskScheduler.initialize();
        taskRegistrar.setTaskScheduler(taskScheduler);
    }
}

UPDATE 2

I have cleared some unused dependencies, removed all my scheduled tasks and upgraded the JDBC drivers to the latest versions without any success. Here is a Thread Dump (Taken using jstack) after the server has shut down but the server window remains open.

2022-04-25 09:45:43
Full thread dump Java HotSpot(TM) 64-Bit Server VM (17.0.2+8-LTS-86 mixed mode, sharing):

Threads class SMR info:
_java_thread_list=0x000001df031609d0, length=15, elements={
0x000001df7f0590c0, 0x000001df7f059e40, 0x000001df7fbeb090, 0x000001df7fbee970,
0x000001df7fbf0240, 0x000001df7fbf4000, 0x000001df7fbf4ca0, 0x000001df7fbfda60,
0x000001df7fc0bb60, 0x000001df7fd48110, 0x000001df7fd48c10, 0x000001df7fdd8950,
0x000001df0285a4a0, 0x000001df08ebead0, 0x000001df07475cb0
}

"Reference Handler" #2 daemon prio=10 os_prio=2 cpu=0.00ms elapsed=170.00s tid=0x000001df7f0590c0 nid=0x12c8 waiting on condition  [0x0000001b491ff000]
   java.lang.Thread.State: RUNNABLE
        at java.lang.ref.Reference.waitForReferencePendingList([email protected]/Native Method)
        at java.lang.ref.Reference.processPendingReferences([email protected]/Reference.java:253)
        at java.lang.ref.Reference$ReferenceHandler.run([email protected]/Reference.java:215)

"Finalizer" #3 daemon prio=8 os_prio=1 cpu=0.00ms elapsed=170.00s tid=0x000001df7f059e40 nid=0x2bc8 in Object.wait()  [0x0000001b492ff000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait([email protected]/Native Method)
        - waiting on <0x0000000402800be0> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove([email protected]/ReferenceQueue.java:155)
        - locked <0x0000000402800be0> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove([email protected]/ReferenceQueue.java:176)
        at java.lang.ref.Finalizer$FinalizerThread.run([email protected]/Finalizer.java:172)

"Signal Dispatcher" #4 daemon prio=9 os_prio=2 cpu=0.00ms elapsed=169.99s tid=0x000001df7fbeb090 nid=0x50e0 waiting on condition  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Attach Listener" #5 daemon prio=5 os_prio=2 cpu=0.00ms elapsed=169.99s tid=0x000001df7fbee970 nid=0x6734 waiting on condition  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Service Thread" #6 daemon prio=9 os_prio=0 cpu=0.00ms elapsed=169.99s tid=0x000001df7fbf0240 nid=0x6b68 runnable  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Monitor Deflation Thread" #7 daemon prio=9 os_prio=0 cpu=0.00ms elapsed=169.99s tid=0x000001df7fbf4000 nid=0x4188 runnable  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #8 daemon prio=9 os_prio=2 cpu=8578.12ms elapsed=169.99s tid=0x000001df7fbf4ca0 nid=0x7724 waiting on condition  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
   No compile task

"C1 CompilerThread0" #16 daemon prio=9 os_prio=2 cpu=1265.62ms elapsed=169.99s tid=0x000001df7fbfda60 nid=0x2248 waiting on condition  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE
   No compile task

"Sweeper thread" #20 daemon prio=9 os_prio=2 cpu=187.50ms elapsed=169.99s tid=0x000001df7fc0bb60 nid=0x8c8 runnable  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Common-Cleaner" #21 daemon prio=8 os_prio=1 cpu=0.00ms elapsed=169.98s tid=0x000001df7fd48110 nid=0x5f34 in Object.wait()  [0x0000001b49dfe000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
        at java.lang.Object.wait([email protected]/Native Method)
        - waiting on <0x0000000402800f50> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove([email protected]/ReferenceQueue.java:155)
        - locked <0x0000000402800f50> (a java.lang.ref.ReferenceQueue$Lock)
        at jdk.internal.ref.CleanerImpl.run([email protected]/CleanerImpl.java:140)
        at java.lang.Thread.run([email protected]/Thread.java:833)
        at jdk.internal.misc.InnocuousThread.run([email protected]/InnocuousThread.java:162)

"Notification Thread" #22 daemon prio=9 os_prio=0 cpu=15.62ms elapsed=169.97s tid=0x000001df7fd48c10 nid=0x6ac runnable  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"AsyncFileHandlerWriter-1028214719" #25 daemon prio=5 os_prio=0 cpu=31.25ms elapsed=169.94s tid=0x000001df7fdd8950 nid=0x11a0 waiting on condition  [0x0000001b4a0fe000]
   java.lang.Thread.State: WAITING (parking)
        at jdk.internal.misc.Unsafe.park([email protected]/Native Method)
        - parking to wait for  <0x00000004028015a8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park([email protected]/LockSupport.java:341)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block([email protected]/AbstractQueuedSynchronizer.java:506)
        at java.util.concurrent.ForkJoinPool.unmanagedBlock([email protected]/ForkJoinPool.java:3463)
        at java.util.concurrent.ForkJoinPool.managedBlock([email protected]/ForkJoinPool.java:3434)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await([email protected]/AbstractQueuedSynchronizer.java:1623)
        at java.util.concurrent.LinkedBlockingDeque.takeFirst([email protected]/LinkedBlockingDeque.java:485)
        at java.util.concurrent.LinkedBlockingDeque.take([email protected]/LinkedBlockingDeque.java:673)
        at org.apache.juli.AsyncFileHandler$LoggerThread.run(AsyncFileHandler.java:204)

"FileHandlerLogFilesCleaner-1" #26 daemon prio=5 os_prio=0 cpu=15.62ms elapsed=169.91s tid=0x000001df0285a4a0 nid=0x5058 waiting on condition  [0x0000001b4a1ff000]
   java.lang.Thread.State: WAITING (parking)
        at jdk.internal.misc.Unsafe.park([email protected]/Native Method)
        - parking to wait for  <0x0000000402803c38> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park([email protected]/LockSupport.java:341)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block([email protected]/AbstractQueuedSynchronizer.java:506)
        at java.util.concurrent.ForkJoinPool.unmanagedBlock([email protected]/ForkJoinPool.java:3463)
        at java.util.concurrent.ForkJoinPool.managedBlock([email protected]/ForkJoinPool.java:3434)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await([email protected]/AbstractQueuedSynchronizer.java:1623)
        at java.util.concurrent.LinkedBlockingQueue.take([email protected]/LinkedBlockingQueue.java:435)
        at java.util.concurrent.ThreadPoolExecutor.getTask([email protected]/ThreadPoolExecutor.java:1062)
        at java.util.concurrent.ThreadPoolExecutor.runWorker([email protected]/ThreadPoolExecutor.java:1122)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run([email protected]/ThreadPoolExecutor.java:635)
        at java.lang.Thread.run([email protected]/Thread.java:833)

"ThreadPoolTaskScheduler-1" #37 prio=5 os_prio=0 cpu=0.00ms elapsed=153.76s tid=0x000001df08ebead0 nid=0x5030 waiting on condition  [0x0000001b4baff000]
   java.lang.Thread.State: WAITING (parking)
        at jdk.internal.misc.Unsafe.park([email protected]/Native Method)
        - parking to wait for  <0x00000004078110c8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park([email protected]/LockSupport.java:341)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block([email protected]/AbstractQueuedSynchronizer.java:506)
        at java.util.concurrent.ForkJoinPool.unmanagedBlock([email protected]/ForkJoinPool.java:3463)
        at java.util.concurrent.ForkJoinPool.managedBlock([email protected]/ForkJoinPool.java:3434)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await([email protected]/AbstractQueuedSynchronizer.java:1623)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take([email protected]/ScheduledThreadPoolExecutor.java:1170)
        at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take([email protected]/ScheduledThreadPoolExecutor.java:899)
        at java.util.concurrent.ThreadPoolExecutor.getTask([email protected]/ThreadPoolExecutor.java:1062)
        at java.util.concurrent.ThreadPoolExecutor.runWorker([email protected]/ThreadPoolExecutor.java:1122)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run([email protected]/ThreadPoolExecutor.java:635)
        at java.lang.Thread.run([email protected]/Thread.java:833)

"DestroyJavaVM" #59 prio=5 os_prio=0 cpu=14281.25ms elapsed=113.68s tid=0x000001df07475cb0 nid=0x6f08 waiting on condition  [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"VM Thread" os_prio=2 cpu=15.62ms elapsed=170.00s tid=0x000001df7f053cf0 nid=0x7260 runnable

"GC Thread#0" os_prio=2 cpu=15.62ms elapsed=170.01s tid=0x000001df41c61fb0 nid=0x7258 runnable

"GC Thread#1" os_prio=2 cpu=15.62ms elapsed=168.95s tid=0x000001df0555b580 nid=0x297c runnable

"GC Thread#2" os_prio=2 cpu=46.88ms elapsed=168.95s tid=0x000001df04aa3c40 nid=0x7248 runnable

"GC Thread#3" os_prio=2 cpu=62.50ms elapsed=168.95s tid=0x000001df04aa3ef0 nid=0x3678 runnable

"GC Thread#4" os_prio=2 cpu=31.25ms elapsed=168.95s tid=0x000001df04aa41a0 nid=0x7510 runnable

"GC Thread#5" os_prio=2 cpu=46.88ms elapsed=168.95s tid=0x000001df04aa4860 nid=0x2548 runnable

"GC Thread#6" os_prio=2 cpu=31.25ms elapsed=168.95s tid=0x000001df04aa4b10 nid=0x35ec runnable

"GC Thread#7" os_prio=2 cpu=31.25ms elapsed=168.95s tid=0x000001df04aa4dc0 nid=0x3a28 runnable

"GC Thread#8" os_prio=2 cpu=31.25ms elapsed=168.95s tid=0x000001df0320b550 nid=0x6af4 runnable

"GC Thread#9" os_prio=2 cpu=15.62ms elapsed=168.94s tid=0x000001df0320b800 nid=0x7604 runnable

"GC Thread#10" os_prio=2 cpu=31.25ms elapsed=168.94s tid=0x000001df0372d060 nid=0x4db4 runnable

"GC Thread#11" os_prio=2 cpu=15.62ms elapsed=168.94s tid=0x000001df0372d310 nid=0x206c runnable

"GC Thread#12" os_prio=2 cpu=78.12ms elapsed=168.94s tid=0x000001df0372ddd0 nid=0x6470 runnable

"G1 Main Marker" os_prio=2 cpu=0.00ms elapsed=170.01s tid=0x000001df41c72d50 nid=0x5cfc runnable

"G1 Conc#0" os_prio=2 cpu=78.12ms elapsed=170.01s tid=0x000001df41c74e20 nid=0x158 runnable

"G1 Conc#1" os_prio=2 cpu=62.50ms elapsed=164.05s tid=0x000001df0372d5c0 nid=0x2104 runnable

"G1 Conc#2" os_prio=2 cpu=93.75ms elapsed=164.05s tid=0x000001df0372d870 nid=0x2468 runnable

"G1 Refine#0" os_prio=2 cpu=15.62ms elapsed=170.01s tid=0x000001df7efe9020 nid=0x39d0 runnable

"G1 Service" os_prio=2 cpu=0.00ms elapsed=170.01s tid=0x000001df7efe9950 nid=0xbc4 runnable

"VM Periodic Task Thread" os_prio=2 cpu=78.12ms elapsed=169.97s tid=0x000001df7ee768a0 nid=0xc4 waiting on condition

JNI global refs: 30, weak refs: 0

UPDATE 3

  • Removing the following properties resolved my issue:
spring.datasource.testOnBorrow
spring.datasource.validationQuery
spring.datasource.hikari.maximumPoolSize


Solution 1:[1]

Apparently (likely during some initialization), you're providing a component that creates threads (e.g. ThreadPoolTaskScheduler). If these threads are non-daemon threads, Tomcat rightfully can't stop before they end.

As you're creating this scheduler yourself, assume responsibility to clean up after yourself, and shut it down when the webapplication goes down (or find a way to delegate this responsibility to spring - I'd assume that this would be delegating creation and teardown).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Olaf Kock