我正在开发一个基于Java的应用程序,其中包括嵌入式Tomcat。 Tomcat的启动可以像这样正常运行:
logger.info("Starting application server");
String baseDir = ConfigHandler.getProperty("tomcat.baseDir");
tomcat = new Tomcat();
tomcat.enableNaming();
tomcat.setPort(ConfigHandler.getIntegerProperty("tomcat.defaultPort", 8080));
tomcat.setBaseDir(baseDir);
tomcat.getHost().setAppBase(baseDir);
tomcat.getHost().setAutoDeploy(true);
try
{
webContext = tomcat.addWebapp(tomcat.getHost(), "/orion", Files.createTempDirectory("orion_doc_base").toString());
webContext.setAltDDName("src/main/webapp/WEB-INF/web.xml");
//URL url = (new File("src/main/resources/META-INF/context.xml")).toURI().toURL();
//webContext.setConfigFile(url);
tomcat.getServer().setShutdown("SHUTDOWN");
tomcat.start();
}
catch(IOException e)
{
e.printStackTrace();
logger.fatal("Error starting server!", e);
}
catch(LifecycleException e)
{
e.printStackTrace();
logger.error("Error starting server!", e);
}
logger.info("Application server ready with Tomcat listening on port " + String.valueOf(ConfigHandler.getIntegerProperty("tomcat.defaultPort", 8080)));
tomcat.getServer().await();
但是,当我尝试关闭Tomcat时,整个应用程序挂起,并且关闭不完全:
try
{
logger.warn("Shutting down tomcat...");
webContext.stop();
System.out.println("ORIONStarter.shutdown - 1");
tomcat.stop();
System.out.println("ORIONStarter.shutdown - 2");
logger.warn("Tomcat has been shut down");
}
catch(LifecycleException e)
{
logger.throwing(e);
e.printStackTrace();
}
控制台输出如下:
05.10.2018 19:33:53.143+0200 [WARN] de.blackhole.software.orion.base.boot.ORIONStarter - Shutting down tomcat...
ORIONStarter.shutdown - 1
ORIONStarter.shutdown - 2
我的tomcat版本是
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>8.5.14</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>8.5.14</version>
</dependency>
更新
这是应用程序挂起时的线程转储:
2018-10-06 10:35:27
Full thread dump Java HotSpot(TM) 64-Bit Server VM (10.0.1+10 mixed mode):
Threads class SMR info:
_java_thread_list=0x00007f8847d0f2d0, length=17, elements={
0x00007f88480f4800, 0x00007f88480ec000, 0x00007f884901c800, 0x00007f8849028000,
0x00007f8849029000, 0x00007f88480ef000, 0x00007f884902a000, 0x00007f8848802800,
0x00007f88481f5000, 0x00007f88480d7800, 0x00007f8849d54000, 0x00007f884af08000,
0x00007f884d03a000, 0x00007f884b9e1000, 0x00007f884b98a000, 0x00007f884b98d000,
0x00007f884baf4800
}
"Reference Handler" #2 daemon prio=10 os_prio=31 tid=0x00007f88480f4800 nid=0x4503 waiting on condition [0x0000700005c0b000]
java.lang.Thread.State: RUNNABLE
at java.lang.ref.Reference.waitForReferencePendingList(java.base@10.0.1/Native Method)
at java.lang.ref.Reference.processPendingReferences(java.base@10.0.1/Reference.java:174)
at java.lang.ref.Reference.access$000(java.base@10.0.1/Reference.java:44)
at java.lang.ref.Reference$ReferenceHandler.run(java.base@10.0.1/Reference.java:138)
"Finalizer" #3 daemon prio=8 os_prio=31 tid=0x00007f88480ec000 nid=0x3a03 in Object.wait() [0x0000700005d0e000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(java.base@10.0.1/Native Method)
- waiting on <0x00000006c026fb18> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(java.base@10.0.1/ReferenceQueue.java:151)
- waiting to re-lock in wait() <0x00000006c026fb18> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(java.base@10.0.1/ReferenceQueue.java:172)
at java.lang.ref.Finalizer$FinalizerThread.run(java.base@10.0.1/Finalizer.java:216)
"Signal Dispatcher" #4 daemon prio=9 os_prio=31 tid=0x00007f884901c800 nid=0x5803 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" #5 daemon prio=9 os_prio=31 tid=0x00007f8849028000 nid=0xa703 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
No compile task
"C2 CompilerThread1" #6 daemon prio=9 os_prio=31 tid=0x00007f8849029000 nid=0xa603 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
No compile task
"C1 CompilerThread2" #7 daemon prio=9 os_prio=31 tid=0x00007f88480ef000 nid=0x5d03 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
No compile task
"Sweeper thread" #8 daemon prio=9 os_prio=31 tid=0x00007f884902a000 nid=0xa303 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Common-Cleaner" #9 daemon prio=8 os_prio=31 tid=0x00007f8848802800 nid=0xa003 in Object.wait() [0x0000700006320000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(java.base@10.0.1/Native Method)
- waiting on <0x00000006c02708c8> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(java.base@10.0.1/ReferenceQueue.java:151)
- waiting to re-lock in wait() <0x00000006c02708c8> (a java.lang.ref.ReferenceQueue$Lock)
at jdk.internal.ref.CleanerImpl.run(java.base@10.0.1/CleanerImpl.java:148)
at java.lang.Thread.run(java.base@10.0.1/Thread.java:844)
at jdk.internal.misc.InnocuousThread.run(java.base@10.0.1/InnocuousThread.java:134)
"Monitor Ctrl-Break" #10 daemon prio=5 os_prio=31 tid=0x00007f88481f5000 nid=0x6103 runnable [0x0000700006423000]
java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(java.base@10.0.1/Native Method)
at java.net.SocketInputStream.socketRead(java.base@10.0.1/SocketInputStream.java:116)
at java.net.SocketInputStream.read(java.base@10.0.1/SocketInputStream.java:171)
at java.net.SocketInputStream.read(java.base@10.0.1/SocketInputStream.java:141)
at sun.nio.cs.StreamDecoder.readBytes(java.base@10.0.1/StreamDecoder.java:284)
at sun.nio.cs.StreamDecoder.implRead(java.base@10.0.1/StreamDecoder.java:326)
at sun.nio.cs.StreamDecoder.read(java.base@10.0.1/StreamDecoder.java:178)
- locked <0x00000006c0272e18> (a java.io.InputStreamReader)
at java.io.InputStreamReader.read(java.base@10.0.1/InputStreamReader.java:185)
at java.io.BufferedReader.fill(java.base@10.0.1/BufferedReader.java:161)
at java.io.BufferedReader.readLine(java.base@10.0.1/BufferedReader.java:326)
- locked <0x00000006c0272e18> (a java.io.InputStreamReader)
at java.io.BufferedReader.readLine(java.base@10.0.1/BufferedReader.java:392)
at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)
"Service Thread" #11 daemon prio=9 os_prio=31 tid=0x00007f88480d7800 nid=0x6303 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"process reaper" #14 daemon prio=10 os_prio=31 tid=0x00007f8849d54000 nid=0x6403 waiting on condition [0x0000700006650000]
java.lang.Thread.State: TIMED_WAITING (parking)
at jdk.internal.misc.Unsafe.park(java.base@10.0.1/Native Method)
- parking to wait for <0x00000006c055d560> (a java.util.concurrent.SynchronousQueue$TransferStack)
at java.util.concurrent.locks.LockSupport.parkNanos(java.base@10.0.1/LockSupport.java:234)
at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(java.base@10.0.1/SynchronousQueue.java:462)
at java.util.concurrent.SynchronousQueue$TransferStack.transfer(java.base@10.0.1/SynchronousQueue.java:361)
at java.util.concurrent.SynchronousQueue.poll(java.base@10.0.1/SynchronousQueue.java:937)
at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@10.0.1/ThreadPoolExecutor.java:1060)
at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@10.0.1/ThreadPoolExecutor.java:1121)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@10.0.1/ThreadPoolExecutor.java:635)
at java.lang.Thread.run(java.base@10.0.1/Thread.java:844)
"NioBlockingSelector.BlockPoller-1" #53 daemon prio=5 os_prio=31 tid=0x00007f884af08000 nid=0x14203 runnable [0x0000700008cc2000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.KQueueArrayWrapper.kevent0(java.base@10.0.1/Native Method)
at sun.nio.ch.KQueueArrayWrapper.poll(java.base@10.0.1/KQueueArrayWrapper.java:196)
at sun.nio.ch.KQueueSelectorImpl.doSelect(java.base@10.0.1/KQueueSelectorImpl.java:116)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(java.base@10.0.1/SelectorImpl.java:89)
- locked <0x00000006c14112f0> (a sun.nio.ch.Util$2)
- locked <0x00000006c1411300> (a java.util.Collections$UnmodifiableSet)
- locked <0x00000006c14112a0> (a sun.nio.ch.KQueueSelectorImpl)
at sun.nio.ch.SelectorImpl.select(java.base@10.0.1/SelectorImpl.java:100)
at org.apache.tomcat.util.net.NioBlockingSelector$BlockPoller.run(NioBlockingSelector.java:339)
"Tomcat-startStop-1" #54 daemon prio=5 os_prio=31 tid=0x00007f884d03a000 nid=0xd403 waiting on condition [0x0000700008dc5000]
java.lang.Thread.State: TIMED_WAITING (parking)
at jdk.internal.misc.Unsafe.park(java.base@10.0.1/Native Method)
- parking to wait for <0x00000006c16e81c8> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.parkNanos(java.base@10.0.1/LockSupport.java:234)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(java.base@10.0.1/AbstractQueuedSynchronizer.java:2117)
at java.util.concurrent.LinkedBlockingQueue.poll(java.base@10.0.1/LinkedBlockingQueue.java:460)
at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@10.0.1/ThreadPoolExecutor.java:1060)
at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@10.0.1/ThreadPoolExecutor.java:1121)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@10.0.1/ThreadPoolExecutor.java:635)
at java.lang.Thread.run(java.base@10.0.1/Thread.java:844)
"localhost-startStop-1" #55 daemon prio=5 os_prio=31 tid=0x00007f884b9e1000 nid=0x13f03 waiting on condition [0x0000700008ec8000]
java.lang.Thread.State: TIMED_WAITING (parking)
at jdk.internal.misc.Unsafe.park(java.base@10.0.1/Native Method)
- parking to wait for <0x00000006c1a76e48> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.parkNanos(java.base@10.0.1/LockSupport.java:234)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(java.base@10.0.1/AbstractQueuedSynchronizer.java:2117)
at java.util.concurrent.LinkedBlockingQueue.poll(java.base@10.0.1/LinkedBlockingQueue.java:460)
at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@10.0.1/ThreadPoolExecutor.java:1060)
at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@10.0.1/ThreadPoolExecutor.java:1121)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@10.0.1/ThreadPoolExecutor.java:635)
at java.lang.Thread.run(java.base@10.0.1/Thread.java:844)
"SIGINT handler" #95 daemon prio=9 os_prio=31 tid=0x00007f884b98a000 nid=0x15d03 in Object.wait() [0x000070000b740000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(java.base@10.0.1/Native Method)
- waiting on <0x00000006c155f580> (a de.blackhole.software.orion.base.Main$1)
at java.lang.Thread.join(java.base@10.0.1/Thread.java:1353)
- waiting to re-lock in wait() <0x00000006c155f580> (a de.blackhole.software.orion.base.Main$1)
at java.lang.Thread.join(java.base@10.0.1/Thread.java:1427)
at java.lang.ApplicationShutdownHooks.runHooks(java.base@10.0.1/ApplicationShutdownHooks.java:107)
at java.lang.ApplicationShutdownHooks$1.run(java.base@10.0.1/ApplicationShutdownHooks.java:46)
at java.lang.Shutdown.runHooks(java.base@10.0.1/Shutdown.java:123)
at java.lang.Shutdown.sequence(java.base@10.0.1/Shutdown.java:167)
at java.lang.Shutdown.exit(java.base@10.0.1/Shutdown.java:212)
- locked <0x00000006c028ab88> (a java.lang.Class for java.lang.Shutdown)
at java.lang.Terminator$1.handle(java.base@10.0.1/Terminator.java:51)
at jdk.internal.misc.Signal$1.run(java.base@10.0.1/Signal.java:220)
at java.lang.Thread.run(java.base@10.0.1/Thread.java:844)
"Thread-1" #51 prio=5 os_prio=31 tid=0x00007f884b98d000 nid=0x1fa03 waiting for monitor entry [0x000070000b843000]
java.lang.Thread.State: BLOCKED (on object monitor)
at java.lang.Shutdown.exit(java.base@10.0.1/Shutdown.java:212)
- waiting to lock <0x00000006c028ab88> (a java.lang.Class for java.lang.Shutdown)
at java.lang.Runtime.exit(java.base@10.0.1/Runtime.java:118)
at de.blackhole.software.orion.base.boot.ORIONStarter.shutdown(ORIONStarter.java:155)
at de.blackhole.software.orion.base.Main$1.run(Main.java:64)
"DestroyJavaVM" #98 prio=5 os_prio=31 tid=0x00007f884baf4800 nid=0x2603 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"VM Thread" os_prio=31 tid=0x00007f88480da800 nid=0x4603 runnable
"GC Thread#0" os_prio=31 tid=0x00007f884801d000 nid=0x2b03 runnable
"GC Thread#1" os_prio=31 tid=0x00007f884880a000 nid=0x5103 runnable
"GC Thread#2" os_prio=31 tid=0x00007f884801d800 nid=0x4f03 runnable
"GC Thread#3" os_prio=31 tid=0x00007f884801e800 nid=0x4d03 runnable
"G1 Main Marker" os_prio=31 tid=0x00007f884804b800 nid=0x2c03 runnable
"G1 Conc#0" os_prio=31 tid=0x00007f884804c000 nid=0x4b03 runnable
"G1 Refine#0" os_prio=31 tid=0x00007f88480cd000 nid=0x4a03 runnable
"G1 Refine#1" os_prio=31 tid=0x00007f88480cd800 nid=0x3203 runnable
"G1 Refine#2" os_prio=31 tid=0x00007f8849800800 nid=0x3403 runnable
"G1 Refine#3" os_prio=31 tid=0x00007f88480ce800 nid=0x4803 runnable
"G1 Young RemSet Sampling" os_prio=31 tid=0x00007f88480cf000 nid=0x3503 runnable
"VM Periodic Task Thread" os_prio=31 tid=0x00007f884884e000 nid=0x9d03 waiting on condition
JNI global references: 20
Heap
garbage-first heap total 378880K, used 117760K [0x00000006c0000000, 0x00000007c0000000)
region size 1024K, 89 young (91136K), 7 survivors (7168K)
Metaspace used 61192K, capacity 62505K, committed 62812K, reserved 1105920K
class space used 6738K, capacity 7187K, committed 7292K, reserved 1048576K
Process finished with exit code 137 (interrupted by signal 9: SIGKILL)