package net.glowstone.util;

import net.glowstone.GlowServer;

import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Level;

/**
 * Thread started on shutdown that monitors for and kills rogue non-daemon threads.
 */
public class ShutdownMonitorThread extends Thread {

    /**
     * The delay in milliseconds until leftover threads are killed.
     */
    private static final int DELAY = 8000;

    public ShutdownMonitorThread() {
        setName("ShutdownMonitorThread");
        setDaemon(true);
    }

    @Override
    public void run() {
        try {
            Thread.sleep(DELAY);
        } catch (InterruptedException e) {
            GlowServer.logger.log(Level.SEVERE, "Shutdown monitor interrupted", e);
            System.exit(0);
            return;
        }

        GlowServer.logger.warning("Still running after shutdown, finding rogue threads...");

        Map<Thread, StackTraceElement[]> traces = Thread.getAllStackTraces();
        for (Entry<Thread, StackTraceElement[]> entry : traces.entrySet()) {
            Thread thread = entry.getKey();
            StackTraceElement[] stack = entry.getValue();

            if (thread.isDaemon() || !thread.isAlive() || stack.length == 0) {
                // won't keep JVM from exiting
                continue;
            }

            GlowServer.logger.warning("Rogue thread: " + thread);
            for (StackTraceElement trace : stack) {
                GlowServer.logger.warning("    at " + trace);
            }

            // ask nicely to kill them
            thread.interrupt();
            // wait for them to die on their own
            if (thread.isAlive()) {
                try {
                    thread.join(1000);
                } catch (InterruptedException ex) {
                    GlowServer.logger.log(Level.SEVERE, "Shutdown monitor interrupted", ex);
                    System.exit(0);
                    return;
                }
            }
        }
        // kill them forcefully
        System.exit(0);
    }

}

@@ -820,23 +820,20 @@
 .logger.
-warning
+info
 (%22Still 
@@ -1314,203 +1314,8 @@
  %7D%0A%0A
-            GlowServer.logger.warning(%22Rogue thread: %22 + thread);%0A            for (StackTraceElement trace : stack) %7B%0A                GlowServer.logger.warning(%22    at %22 + trace);%0A            %7D%0A%0A
     
@@ -1574,17 +1574,16 @@
 eption e
-x
 ) %7B%0A    
@@ -1667,17 +1667,16 @@
 pted%22, e
-x
 );%0A     
@@ -1768,32 +1768,32 @@
     %7D%0A        %7D%0A
-
         // kill 
@@ -1808,16 +1808,88 @@
 cefully%0A
+        GlowServer.logger.info(%22Rogue threads killed, shutting down.%22);%0A
         

Resolve confusion over rogue threads