--- /home/cpdev/src/classpath/gnu/java/lang/MainThread.java	2005-07-02 21:03:03.000000000 +0000
+++ gnu/java/lang/MainThread.java	2005-06-30 05:34:05.000000000 +0000
@@ -1,4 +1,4 @@
-/* MainThread.java --
+/* gnu.java.lang.MainThread
    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
    Free Software Foundation, Inc.
 
@@ -39,8 +39,8 @@
 
 package gnu.java.lang;
 
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
 
 /**
  * MainThread is a Thread which uses the main() method of some class.
@@ -48,36 +48,87 @@
  * @author John Keiser
  * @author Tom Tromey (tromey@redhat.com)
  */
-public class MainThread
+final class MainThread extends Thread
 {
+  // If the user links statically then we need to ensure that these
+  // classes are linked in.  Otherwise bootstrapping fails.  These
+  // classes are only referred to via Class.forName(), so we add an
+  // explicit mention of them here.
+  static final Class Kcert     = java.security.cert.Certificate.class;
+  static final Class Kfile     = gnu.java.net.protocol.file.Handler.class;
+  static final Class Khttp     = gnu.java.net.protocol.http.Handler.class;
+  static final Class Kjar      = gnu.java.net.protocol.jar.Handler.class;
+  static final Class Klocale   = gnu.java.locale.LocaleInformation.class;
+  static final Class Kcalendar = gnu.java.locale.Calendar.class;
+
   // Private data.
-  String[] args;
-  Method mainMethod;
+  private Class klass;
+  private String klass_name;
+  private String[] args;
+  private boolean is_jar;
+
+  public MainThread(Class k, String[] args)
+  {
+    super(null, null, "main");
+    klass = k;
+    this.args = args;
+  }
 
-  public MainThread(String classname, String[] args)
-    throws ClassNotFoundException, NoSuchMethodException
+  public MainThread(String classname, String[] args, boolean is_jar)
   {
-    Class found = Class.forName(classname, true,
-				ClassLoader.getSystemClassLoader());
-    Class[] argTypes = new Class[1];
-    argTypes[0] = args.getClass();
-    mainMethod = found.getMethod("main", argTypes);
+    super (null, null, "main");
+    klass_name = classname;
     this.args = args;
+    this.is_jar = is_jar;
   }
 
   public void run()
   {
+    if (is_jar)
+      klass_name = getMain(klass_name);
+
+    if (klass == null)
+      {
+        try
+	  {
+	    klass = Class.forName(klass_name, true,
+				  ClassLoader.getSystemClassLoader());
+	  }
+	catch (ClassNotFoundException x)
+	  {
+	    NoClassDefFoundError ncdfe = new NoClassDefFoundError(klass_name);
+	    ncdfe.initCause(x);
+	    throw ncdfe;
+	  }
+      }
+
+    call_main();
+  }
+
+  private String getMain(String name)
+  {
+    String mainName = null;
     try
       {
-	mainMethod.invoke(null,args);
+	JarFile j = new JarFile(name);
+	Attributes a = j.getManifest().getMainAttributes();
+	mainName = a.getValue(Attributes.Name.MAIN_CLASS);
       }
-    catch(IllegalAccessException e)
+    catch (Exception e)
       {
 	// Ignore.
       }
-    catch(InvocationTargetException e)
+
+    if (mainName == null)
       {
-	// Ignore.
+	System.err.println("Failed to load Main-Class manifest attribute from "
+			   + name);
+	System.exit(1);
       }
+    return mainName;
   }
+
+  // Note: this function name is known to the stack tracing code.
+  // You shouldn't change this without also updating stacktrace.cc.
+  private native void call_main();
 }
