Hi,

I would like to apply the attached patch. It fixes a potential
initialization order issue for VMs that support running Java code
without first initializing the VM explicitly (like IKVM does).

The current code calls ClassLoader.getSystemClassLoader() in the Thread
constructor that the VM uses to create thread objects for threads that
are started outside of Java (for example, through JNI code that attaches
a thread), this can cause problems if this is the first time that
ClassLoader.getSystemClassLoader() is being called and the system class
loader construction code path happens to call Thread.currentThread().

I can also fix this in IKVM specific code, but that would be uglier and
I believe that other VMs will also benefit from this change (at the
small cost of an extra boolean in each Thread instance).

Any comments?

Regards,
Jeroen

2006-05-17  Jeroen Frijters  <[EMAIL PROTECTED]>

        * java/lang/Thread.java (contextClassLoaderIsSystemClassLoader):
New field.
        (Thread(VMThread,String,int,boolean)): Set
contextClassLoaderIsSystemClassLoader to true.
        (getContextClassLoader): Check
contextClassLoaderIsSystemClassLoader.
        (setContextClassLoader): Clear
contextClassLoaderIsSystemClassLoader.
Index: java/lang/Thread.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/lang/Thread.java,v
retrieving revision 1.22
diff -u -r1.22 Thread.java
--- java/lang/Thread.java       9 May 2006 14:42:13 -0000       1.22
+++ java/lang/Thread.java       17 May 2006 09:41:02 -0000
@@ -131,7 +131,8 @@
 
   /** The context classloader for this Thread. */
   private ClassLoader contextClassLoader;
-  
+  private boolean contextClassLoaderIsSystemClassLoader;
+
   /** This thread's ID.  */
   private final long threadId;
 
@@ -388,12 +389,11 @@
     this.name = name;
     this.priority = priority;
     this.daemon = daemon;
-    this.contextClassLoader = ClassLoader.getSystemClassLoader();
+    contextClassLoaderIsSystemClassLoader = true;
     synchronized (Thread.class)
       {
        this.threadId = nextThreadId++;
       }
-
   }
 
   /**
@@ -751,7 +751,8 @@
     if (sm != null)
       // XXX Don't check this if the caller's class loader is an ancestor.
       sm.checkPermission(new RuntimePermission("getClassLoader"));
-    return contextClassLoader;
+    return contextClassLoaderIsSystemClassLoader ?
+        ClassLoader.getSystemClassLoader() : contextClassLoader;
   }
 
   /**
@@ -772,6 +773,7 @@
     if (sm != null)
       sm.checkPermission(new RuntimePermission("setContextClassLoader"));
     this.contextClassLoader = classloader;
+    contextClassLoaderIsSystemClassLoader = false;
   }
 
   /**

Reply via email to