Skip to content

Spring boot application does not get shut down if you are using ScheduledExecutorService to start Kafka server #4008

Closed
@ghost

Description

I am have a spring boot application that sends/receive messages to Apache Kafka server. The project using ScheduledExecutorService to start/stop apache kafka server. All the things work well till I try to shutdown the server using curl -X POST http://localhost:9012/shutdown. On running this command the spring container closes however the ScheduledExecutorService task still exists.
KafkaServerTask

public class KafkaServerTask {
    private static final Logger logger = Logger.getLogger(KafkaServerTask.class.getName());
    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    ScheduledFuture<?> kafkaserverFutureTask = null;
    KafkaMessageDrivenChannelAdapter kafkaMessageDrivenChannelAdapter;
    Long taskPeriod;
    public void setTaskPeriod(Long taskPeriod) {
        this.taskPeriod = taskPeriod;
    }
    public void setKafkaMessageDrivenChannelAdapter(KafkaMessageDrivenChannelAdapter kafkaMessageDrivenChannelAdapter) {
        this.kafkaMessageDrivenChannelAdapter = kafkaMessageDrivenChannelAdapter;
    }
    /*
     * Bean start up method.
     * Start the kafka server.
     */
    public void startKafkaServer() {
        final Runnable startKafkaServerTask = new Runnable() {
            public void run() {
                if (!kafkaMessageDrivenChannelAdapter.isRunning()) {
                    try {
                        kafkaMessageDrivenChannelAdapter.start();
                        logger.info("kafka server starteds");
                    } catch (Exception exp) {
                        logger.info("Failed to start the kafka server. " + exp.getMessage());
                    }
                }
            }
        };
        kafkaserverFutureTask = scheduler.scheduleAtFixedRate(startKafkaServerTask, 0, taskPeriod, TimeUnit.MINUTES);
    }
    /*
     * Bean destroy method.
     * Stop the kafka server and exit the task.
     */
    public void stopKafkaServer() {
        try {
            logger.info("stop the kafka server");
            kafkaMessageDrivenChannelAdapter.stop();
        } catch (Exception exp) {
            logger.info("Failed to stop the kafka server. " + exp.getMessage());
        }
        kafkaserverFutureTask.cancel(false);
        try {
            scheduler.awaitTermination(taskPeriod, TimeUnit.MINUTES);
        } catch (InterruptedException exp) {
            logger.info("InterruptedExceptio: " + exp.getMessage());
        }
        scheduler.shutdownNow();
    }
}

Thread dump:

Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.51-b03 mixed mode):

"Attach Listener" #63 daemon prio=9 os_prio=31 tid=0x00007fe6d9861000 nid=0x9d0f waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"ServoMonitorGetValueLimiter-0" #49 daemon prio=5 os_prio=31 tid=0x00007fe6d814a800 nid=0x8803 waiting on condition [0x00000001e04b4000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x000000011355ff50> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

"DestroyJavaVM" #45 prio=5 os_prio=31 tid=0x00007fe6d9a93800 nid=0x1303 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"pool-6-thread-1" #38 prio=5 os_prio=31 tid=0x00007fe6d93a6800 nid=0x7403 waiting on condition [0x00000001e0b04000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000001135476e0> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

"pool-3-thread-1" #35 prio=5 os_prio=31 tid=0x00007fe6d89e9800 nid=0x6a07 waiting on condition [0x00000001e07fb000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x0000000113560790> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

"metrics-meter-tick-thread-2" #34 daemon prio=5 os_prio=31 tid=0x00007fe6d45be000 nid=0x6e07 waiting on condition [0x00000001df6e6000]
   java.lang.Thread.State: TIMED_WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x0000000113273290> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

"metrics-meter-tick-thread-1" #33 daemon prio=5 os_prio=31 tid=0x00007fe6d421d000 nid=0x6c07 waiting on condition [0x00000001de5fb000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x0000000113273290> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1088)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

"java-sdk-http-connection-reaper" #27 daemon prio=5 os_prio=31 tid=0x00007fe6d999c000 nid=0x300b waiting on condition [0x00000001dc556000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
    at java.lang.Thread.sleep(Native Method)
    at com.amazonaws.http.IdleConnectionReaper.run(IdleConnectionReaper.java:112)

"Abandoned connection cleanup thread" #25 daemon prio=5 os_prio=31 tid=0x00007fe6d718b000 nid=0x3307 in Object.wait() [0x00000001dd358000]
   java.lang.Thread.State: TIMED_WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
    - locked <0x0000000112ae4818> (a java.lang.ref.ReferenceQueue$Lock)
    at com.mysql.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:43)

"RMI TCP Accept-0" #12 daemon prio=5 os_prio=31 tid=0x00007fe6d421e000 nid=0x5207 runnable [0x00000001dace5000]
   java.lang.Thread.State: RUNNABLE
    at java.net.PlainSocketImpl.socketAccept(Native Method)
    at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:404)
    at java.net.ServerSocket.implAccept(ServerSocket.java:545)
    at java.net.ServerSocket.accept(ServerSocket.java:513)
    at sun.management.jmxremote.LocalRMIServerSocketFactory$1.accept(LocalRMIServerSocketFactory.java:52)
    at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:400)
    at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:372)
    at java.lang.Thread.run(Thread.java:745)

"RMI TCP Accept-20562" #11 daemon prio=5 os_prio=31 tid=0x00007fe6d52f5000 nid=0x4b03 runnable [0x00000001dabe2000]
   java.lang.Thread.State: RUNNABLE
    at java.net.PlainSocketImpl.socketAccept(Native Method)
    at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:404)
    at java.net.ServerSocket.implAccept(ServerSocket.java:545)
    at java.net.ServerSocket.accept(ServerSocket.java:513)
    at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:400)
    at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:372)
    at java.lang.Thread.run(Thread.java:745)

"RMI TCP Accept-0" #10 daemon prio=5 os_prio=31 tid=0x00007fe6d38fb000 nid=0x4903 runnable [0x00000001daadf000]
   java.lang.Thread.State: RUNNABLE
    at java.net.PlainSocketImpl.socketAccept(Native Method)
    at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:404)
    at java.net.ServerSocket.implAccept(ServerSocket.java:545)
    at java.net.ServerSocket.accept(ServerSocket.java:513)
    at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.executeAcceptLoop(TCPTransport.java:400)
    at sun.rmi.transport.tcp.TCPTransport$AcceptLoop.run(TCPTransport.java:372)
    at java.lang.Thread.run(Thread.java:745)

"Service Thread" #8 daemon prio=9 os_prio=31 tid=0x00007fe6d3864800 nid=0x4703 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread2" #7 daemon prio=9 os_prio=31 tid=0x00007fe6d3842000 nid=0x4503 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #6 daemon prio=9 os_prio=31 tid=0x00007fe6d3841000 nid=0x4303 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #5 daemon prio=9 os_prio=31 tid=0x00007fe6d3831800 nid=0x4103 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" #4 daemon prio=9 os_prio=31 tid=0x00007fe6d4008800 nid=0x3417 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=31 tid=0x00007fe6d5024800 nid=0x2d03 in Object.wait() [0x00000001d8322000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
    - locked <0x000000011182b700> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
    at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)

"Reference Handler" #2 daemon prio=10 os_prio=31 tid=0x00007fe6d5024000 nid=0x2b03 in Object.wait() [0x00000001d821f000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    at java.lang.Object.wait(Object.java:502)
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:157)
    - locked <0x000000011182b740> (a java.lang.ref.Reference$Lock)

"VM Thread" os_prio=31 tid=0x00007fe6d5021000 nid=0x2903 runnable 

"GC task thread#0 (ParallelGC)" os_prio=31 tid=0x00007fe6d5016800 nid=0x2103 runnable 

"GC task thread#1 (ParallelGC)" os_prio=31 tid=0x00007fe6d5017800 nid=0x2303 runnable 

"GC task thread#2 (ParallelGC)" os_prio=31 tid=0x00007fe6d5018000 nid=0x2503 runnable 

"GC task thread#3 (ParallelGC)" os_prio=31 tid=0x00007fe6d5018800 nid=0x2703 runnable 

"VM Periodic Task Thread" os_prio=31 tid=0x00007fe6d4910000 nid=0x5303 waiting on condition 

JNI global references: 350

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions