Hi,

An IKVM user reported a problem with RMI. I debugged it and it turned
out that ObjectInputStream was using the incorrect class loader to try
and load the field types. Fixed by the attached patch (already
committed).

Note that the ObjectStreamField(String,String) constructor was
previously unused, so I did not change it's behavior unintentionally.

Regards,
Jeroen

2006-08-11  Jeroen Frijters  <[EMAIL PROTECTED]>

        * java/io/ObjectInputStream.java (readClassDescriptor):
        Use class's class loader to resolve field types.
        * java/io/ObjectStreamField.java
        (ObjectStreamField(String,String,ClassLoader)): Removed.
        (ObjectStreamField(String,String)): Don't try to resolve
typename.
        (resolveType): New method.
Index: java/io/ObjectInputStream.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/io/ObjectInputStream.java,v
retrieving revision 1.76
diff -u -r1.76 ObjectInputStream.java
--- java/io/ObjectInputStream.java      21 May 2006 20:53:14 -0000      1.76
+++ java/io/ObjectInputStream.java      11 Aug 2006 07:33:25 -0000
@@ -539,8 +539,6 @@
                                                  flags, fields);
     assignNewHandle(osc);
 
-    ClassLoader callersClassLoader = currentLoader();
-             
     for (int i = 0; i < field_count; i++)
       {
        if(dump) dumpElement("  TYPE CODE=");
@@ -560,12 +558,17 @@
          class_name = String.valueOf(type_code);
                  
        fields[i] =
-         new ObjectStreamField(field_name, class_name, callersClassLoader);
+         new ObjectStreamField(field_name, class_name);
       }
              
     /* Now that fields have been read we may resolve the class
      * (and read annotation if needed). */
     Class clazz = resolveClass(osc);
+    ClassLoader loader = clazz.getClassLoader();
+    for (int i = 0; i < field_count; i++)
+      {
+        fields[i].resolveType(loader);
+      }
     boolean oldmode = setBlockDataMode(true);
     osc.setClass(clazz, lookupClass(clazz.getSuperclass()));
     classLookupTable.put(clazz, osc);
Index: java/io/ObjectStreamField.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/io/ObjectStreamField.java,v
retrieving revision 1.20
diff -u -r1.20 ObjectStreamField.java
--- java/io/ObjectStreamField.java      13 Sep 2005 21:25:07 -0000      1.20
+++ java/io/ObjectStreamField.java      11 Aug 2006 07:32:58 -0000
@@ -111,28 +111,10 @@
   {
     this.name = name;
     this.typename = typename;
-    try
-      {
-        type = TypeSignature.getClassForEncoding(typename);
-      }
-    catch(ClassNotFoundException e)
-      {
-      }
   }
-  
-  /**
-   * There are many cases you can not get java.lang.Class from typename 
-   * if your context class loader cann not load it, then use typename to
-   * construct the field.
-   *
-   * @param name Name of the field to export.
-   * @param typename The coded name of the type for this field.
-   * @param loader The class loader to use to resolve class names.
-   */
-  ObjectStreamField (String name, String typename, ClassLoader loader)
+
+  void resolveType(ClassLoader loader)
   {
-    this.name = name;
-    this.typename = typename;
     try
       {
         type = TypeSignature.getClassForEncoding(typename, true, loader);
@@ -141,7 +123,7 @@
       {
       }
   }
-
+  
   /**
    * This method returns the name of the field represented by the
    * ObjectStreamField instance.

Reply via email to