licensing update to APSL 2.0
[org.ibex.jinetd.git] / src / org / ibex / jinetd / Loader.java
index b166df6..012a935 100644 (file)
@@ -1,4 +1,9 @@
+// Copyright 2000-2005 the Contributors, as shown in the revision logs.
+// Licensed under the Apache Public Source License 2.0 ("the License").
+// You may not use this file except in compliance with the License.
+
 package org.ibex.jinetd;
+import org.ibex.io.*;
 import org.ibex.util.*;
 import java.io.*;
 import java.util.*;
@@ -11,10 +16,14 @@ public class Loader extends Watcher {
 
     ClassLoader parentClassLoader = null;
     static final ClassLoader mycl = Loader.class.getClassLoader();
+
+    protected ThreadGroup tg = new ThreadGroup(getAbsolutePath());
+
     public Loader(String path) { super(path); }
     //public Loader(String path, ClassLoader pcl) { super(path); this.parentClassLoader = pcl; }
     
     private TreeClassLoader classloader = null;
+    public synchronized void scan() throws IOException { super.scan(); }
     public synchronized ClassLoader getClassLoader() {
         ClassLoader classloader = this.classloader;
         if (classloader == null) {
@@ -28,7 +37,6 @@ public class Loader extends Watcher {
                     if (us.endsWith(".jar")) us = "file:"+us;
                     else us = "file:"+us+"/";
                     urls[i] = new URL(us);
-                    Log.warn("[classpath]", urls[i].toString());
                 }
             } catch (MalformedURLException e) {
                 Log.error(this, e);
@@ -52,10 +60,11 @@ public class Loader extends Watcher {
         }
     }
 
+
     public String getClassPath() {
         String classpath = System.getProperty("java.class.path");
         String [] l = new File(Root.root + "/LIB/").list();
-        for(int i=0; i<l.length; i++) {
+        for(int i=0; l != null && i<l.length; i++) {
             if (!l[i].endsWith(".jar")) continue;
             classpath += File.pathSeparatorChar;
             classpath += Root.root + "/LIB/" + l[i];
@@ -122,7 +131,7 @@ public class Loader extends Watcher {
             String[] all = new String[args.size()];
             args.copyInto(all);
             Log.info(this, "invoking javac for " + srcdir.getAbsolutePath());
-            final Process javac = Runtime.getRuntime().exec(all);
+            final Process javac = Runtime.getRuntime().exec(all, new String[] { "PATH=/bin:/usr/bin" });
             final BufferedReader out = new BufferedReader(new InputStreamReader(javac.getInputStream()));
             final BufferedReader err = new BufferedReader(new InputStreamReader(javac.getErrorStream()));
             new Thread() { public void run() {
@@ -143,10 +152,37 @@ public class Loader extends Watcher {
                 path.endsWith(".jar") ) ? super.slash(path) : null; }
 
 
+    private void nuke() {
+        if (tg.activeCount() == 0) return;
+        Log.info(this, "killing all threads for: " + path);
+        Log.info(this, "   thread count before interrupt: " + tg.activeCount());
+        tg.interrupt();
+        try { Thread.sleep(3000); } catch (Exception e) { Log.error(this, e); }
+        Log.info(this, "   thread count before kill: " + tg.activeCount());
+        Thread[] all = new Thread[tg.activeCount()];
+        tg.enumerate(all, true);
+        for(int i=0; i<all.length; i++) Stream.kill(all[i]);
+        try { Thread.sleep(3000); } catch (Exception e) { Log.error(this, e); }
+        Log.info(this, "   thread count after kill: " + tg.activeCount());
+        if (tg.activeCount() > 0) {
+            Log.warn(this, "    annoying threads:");
+            Thread[] annoying = new Thread[tg.activeCount()];
+            tg.enumerate(annoying, true);
+            for(int i=0; i<annoying.length; i++) {
+                Log.warn(this, "      " + annoying[i]);
+                StackTraceElement[] stack = annoying[i].getStackTrace();
+                for(int j=0; j<stack.length; j++) Log.warn(this, "        " + stack[j]);
+                Log.warn(this, " ");
+            }
+        }
+    }
+
     // dump the classloader if anything changes
     public void changed(Watched w) {
         if (w.path.indexOf("BIN") != -1) return;
         if (classloader != null) {
+            for(int i=0; i<3; i++) nuke();
+            tg = new ThreadGroup(getAbsolutePath());
             Log.info(this, "scheduling classes for reload due to change in: " + w.path);
             classloader = null;
         }