Patch: FYI: Fix loadClass() bug

Tom Tromey tromey@redhat.com
Wed Apr 6 22:27:00 GMT 2005


I'm checking this in on the trunk and the 4.0 branch.

This fixes a bug in ClassLoader.loadClass().  It introduces a
Classpath divergence, which is bad.  But there doesn't really seem to
be a better way to do this.

This is just a small rewrite of a patch that Andrew wrote.  His test
case is included.

Tom

Index: ChangeLog
from  Andrew Haley  <aph@redhat.com>

	* testsuite/libjava.lang/bytearray.java: New file.
	* testsuite/libjava.lang/bytearray.out: New file.
	* java/lang/ClassLoader.java (loadClassFromSig): Declare
	(loadClass): Use it.
	* java/lang/natClassLoader.cc (loadClassFromSig): New method.

Index: java/lang/ClassLoader.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/ClassLoader.java,v
retrieving revision 1.40
diff -u -r1.40 ClassLoader.java
--- java/lang/ClassLoader.java 4 Apr 2005 18:40:24 -0000 1.40
+++ java/lang/ClassLoader.java 6 Apr 2005 22:24:55 -0000
@@ -260,6 +260,9 @@
     return loadClass(name, false);
   }
 
+  private native Class loadClassFromSig(String name)
+    throws ClassNotFoundException;
+
   /**
    * Load a class using this ClassLoader or its parent, possibly resolving
    * it as well using <code>resolveClass()</code>. It first tries to find
@@ -283,29 +286,36 @@
   protected synchronized Class loadClass(String name, boolean resolve)
     throws ClassNotFoundException
   {
-    // Have we already loaded this class?
-    Class c = findLoadedClass(name);
-    if (c == null)
+    // Arrays are handled specially.
+    Class c;
+    if (name.charAt(0) == '[')
+      c = loadClassFromSig(name);
+    else
       {
-	// Can the class be loaded by a parent?
-	try
+	// Have we already loaded this class?
+	c = findLoadedClass(name);
+	if (c == null)
 	  {
-	    if (parent == null)
+	    // Can the class be loaded by a parent?
+	    try
 	      {
-		c = VMClassLoader.loadClass(name, resolve);
-		if (c != null)
-		  return c;
+		if (parent == null)
+		  {
+		    c = VMClassLoader.loadClass(name, resolve);
+		    if (c != null)
+		      return c;
+		  }
+		else
+		  {
+		    return parent.loadClass(name, resolve);
+		  }
 	      }
-	    else
+	    catch (ClassNotFoundException e)
 	      {
-		return parent.loadClass(name, resolve);
 	      }
+	    // Still not found, we have to do it ourself.
+	    c = findClass(name);
 	  }
-	catch (ClassNotFoundException e)
-	  {
-	  }
-	// Still not found, we have to do it ourself.
-	c = findClass(name);
       }
     if (resolve)
       resolveClass(c);
Index: java/lang/natClassLoader.cc
===================================================================
RCS file: /cvs/gcc/gcc/libjava/java/lang/natClassLoader.cc,v
retrieving revision 1.80
diff -u -r1.80 natClassLoader.cc
--- java/lang/natClassLoader.cc 5 Apr 2005 22:26:24 -0000 1.80
+++ java/lang/natClassLoader.cc 6 Apr 2005 22:24:55 -0000
@@ -65,6 +65,17 @@
 
 
 
+jclass
+java::lang::ClassLoader::loadClassFromSig(jstring name)
+{
+  int len = _Jv_GetStringUTFLength (name);
+  char sig[len + 1];
+  _Jv_GetStringUTFRegion (name, 0, name->length(), sig);
+  return _Jv_FindClassFromSignature(sig, this);
+}
+
+
+
 // This tries to find a class in our built-in cache.  This cache is
 // used only for classes which are linked in to the executable or
 // loaded via dlopen().
Index: testsuite/libjava.lang/bytearray.java
===================================================================
RCS file: testsuite/libjava.lang/bytearray.java
diff -N testsuite/libjava.lang/bytearray.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/libjava.lang/bytearray.java 6 Apr 2005 22:24:56 -0000
@@ -0,0 +1,10 @@
+public class bytearray
+{
+  public static void main (String[] argv) throws Throwable {
+    Class c = Class.forName ("[Ljava.lang.String;");
+    c = Class.forName ("[B");
+    System.out.println (c);
+    c = ClassLoader.getSystemClassLoader().loadClass ("[[Ljava.lang.String;");
+    System.out.println (c);
+  }
+}
Index: testsuite/libjava.lang/bytearray.out
===================================================================
RCS file: testsuite/libjava.lang/bytearray.out
diff -N testsuite/libjava.lang/bytearray.out
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/libjava.lang/bytearray.out 6 Apr 2005 22:24:56 -0000
@@ -0,0 +1,2 @@
+class [B
+class [[Ljava.lang.String;



More information about the Java-patches mailing list