We have a spring-boot based web application and using these components below
- jmsTemplate for ActiveMQ connection
- Spring quartz scheduler for scheduling task
- spring-boot-starter-data-mongodb and mongo-java-driver as persistence
- Logback as logging
When we stoped the web application by tomcat manager, there will have warning or severe log as below
13-Jul-2016 08:54:44.688 INFO [http-nio-80-exec-19] org.apache.jasper.servlet.TldScanner.scanJars At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
13-Jul-2016 08:55:08.376 WARNING [http-nio-80-exec-18] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [demo] appears to have started a thread named [AsyncLogger-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
com.lmax.disruptor.BlockingWaitStrategy.waitFor(BlockingWaitStrategy.java:45)
com.lmax.disruptor.ProcessingSequenceBarrier.waitFor(ProcessingSequenceBarrier.java:55)
com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:123)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
java.lang.Thread.run(Thread.java:745)
13-Jul-2016 08:55:08.380 WARNING [http-nio-80-exec-18] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [demo] appears to have started a thread named [schedulerFactoryBean_Worker-1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.lang.Object.wait(Native Method)
org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:568)
13-Jul-2016 08:55:08.383 WARNING [http-nio-80-exec-18] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [demo] appears to have started a thread named [schedulerFactoryBean_Worker-2] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.lang.Object.wait(Native Method)
org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:568)
13-Jul-2016 08:55:08.387 WARNING [http-nio-80-exec-18] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [demo] appears to have started a thread named [schedulerFactoryBean_Worker-3] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.lang.Object.wait(Native Method)
org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:568)
13-Jul-2016 08:55:08.389 WARNING [http-nio-80-exec-18] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [demo] appears to have started a thread named [schedulerFactoryBean_Worker-4] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.lang.Object.wait(Native Method)
org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:568)
13-Jul-2016 08:55:08.390 WARNING [http-nio-80-exec-18] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [demo] appears to have started a thread named [schedulerFactoryBean_Worker-5] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.lang.Object.wait(Native Method)
org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:568)
13-Jul-2016 08:55:08.391 WARNING [http-nio-80-exec-18] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [demo] appears to have started a thread named [schedulerFactoryBean_Worker-6] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.lang.Object.wait(Native Method)
org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:568)
13-Jul-2016 08:55:08.393 WARNING [http-nio-80-exec-18] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [demo] appears to have started a thread named [schedulerFactoryBean_Worker-7] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.lang.Object.wait(Native Method)
org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:568)
13-Jul-2016 08:55:08.394 WARNING [http-nio-80-exec-18] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [demo] appears to have started a thread named [schedulerFactoryBean_Worker-8] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.lang.Object.wait(Native Method)
org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:568)
13-Jul-2016 08:55:08.395 WARNING [http-nio-80-exec-18] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [demo] appears to have started a thread named [schedulerFactoryBean_Worker-9] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.lang.Object.wait(Native Method)
org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:568)
13-Jul-2016 08:55:08.397 WARNING [http-nio-80-exec-18] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [demo] appears to have started a thread named [schedulerFactoryBean_Worker-10] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.lang.Object.wait(Native Method)
org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:568)
13-Jul-2016 08:55:08.398 WARNING [http-nio-80-exec-18] org.apache.catalina.loader.WebappClassLoaderBase.clearReferencesThreads The web application [demo] appears to have started a thread named [ActiveMQ Session: ID:WIN-U2S1V56UQ42-60029-1468400094066-1:1:1] but has failed to stop it. This is very likely to create a memory leak. Stack trace of thread:
java.lang.Object.wait(Native Method)
java.lang.Object.wait(Object.java:502)
org.apache.activemq.thread.DedicatedTaskRunner.runTask(DedicatedTaskRunner.java:119)
org.apache.activemq.thread.DedicatedTaskRunner$1.run(DedicatedTaskRunner.java:42)
13-Jul-2016 08:55:08.400 SEVERE [http-nio-80-exec-18] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [demo] created a ThreadLocal with key of type [org.apache.axiom.util.UIDGenerator$1] (value [org.apache.axiom.util.UIDGenerator$1@53197bfc]) and a value of type [long[]] (value [[J@3ab7d938]) 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.
13-Jul-2016 08:55:08.402 SEVERE [http-nio-80-exec-18] org.apache.catalina.loader.WebappClassLoaderBase.checkThreadLocalMapForLeaks The web application [demo] created a ThreadLocal with key of type [org.apache.logging.log4j.core.async.AsyncLogger$Info$1] (value [org.apache.logging.log4j.core.async.AsyncLogger$Info$1@6ddb14cb]) and a value of type [org.apache.logging.log4j.core.async.AsyncLogger.Info] (value [org.apache.logging.log4j.core.async.AsyncLogger$Info@4f6422bc]) 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.
It looks like the thread of logger, quartz scheduler and activeMQ connection have failed to shutdown properly. There will sometimes have something like mongoDB driver connection failed to closed(Sorry for that we have not capture the log yet).
We can not just shutdown tomcat but only closed the specified applicatoin is allowed. So that is important to make sure the application can be closed gracefully.
How can we do to let whole web application to be closed properly? Could we set something(like hook?) for container to handle the shutdown operation?
Or shall we handle these operations manually on ContextClosedEvent? and How to do so?