Hello again,
There's something that, I think, misbehaves in readClassDescriptor.
Fields are read before the loading of the actual object's class CL in
the stream, which is necessary. When loading the classes of the fields
(before loading CL), the classloader given is the callersClassLoader
which is set to currentLoader() the most recent user defined
classloader on the execution stack.
When using the method with RMI here is the class context :
class java.io.VMObjectInputStream$1
class java.security.AccessController
class java.io.VMObjectInputStream
class java.io.ObjectInputStream
class java.io.ObjectInputStream
class java.io.ObjectInputStream
class java.io.ObjectInputStream
class gnu.java.rmi.server.RMIObjectInputStream
class gnu.java.rmi.server.UnicastServerRef
class gnu.java.rmi.server.UnicastServer
class gnu.java.rmi.server.UnicastServer
class gnu.java.rmi.server.UnicastConnection
class java.lang.Thread
class java.lang.VMThread
So the callersClassLoader is set to null and the fields of CL are
loaded with the VM ClassLoader (which won't found any classes loaded
by the application class loader or other user defined classloader)
Because RMI redefines the resolveClass(ObjectStreamClass), CL is
found, as it used the "correct" classloader. The problem arrives when
CL was loaded by MyClassLoader, and CL has one field whose class was
also loaded by MyClassLoader.
What I suggest is to use the classloader of CL, once CL is loaded, to
load the fields. What i do in the attached patch is reading the fields
and storing them in a temporary class, loading CL as it was done
before (this is when the RMI's resolveClass is used :
gnu.java.rmi.server.RMIObjectInputStream) and finally loading the
fields with CL's classloader.
Would that be a correct behaviour?
Cheers
Nicolas
------------------------------------------------------------------------
*** java/io/ObjectInputStream.java Fri Jul 15 15:57:35 2005
--- java/io/ObjectInputStream.java Fri Jul 22 15:36:01 2005
***************
*** 468,473 ****
--- 468,484 ----
}
}
+
+ private class TemporaryStreamField{
+ String field_name;
+ String class_name;
+
+ TemporaryStreamField(String field, String clazz){
+ field_name = field;
+ class_name = clazz;
+ }
+ }
+
/**
* This method reads a class descriptor from the real input stream
* and use these data to create a new instance of ObjectStreamClass.
***************
*** 497,509 ****
short field_count = this.realInputStream.readShort();
if(dump) dumpElementln(Short.toString(field_count));
ObjectStreamField[] fields = new ObjectStreamField[field_count];
ObjectStreamClass osc = new ObjectStreamClass(name, uid,
flags, fields);
assignNewHandle(osc);
- if (callersClassLoader == null)
- callersClassLoader = currentLoader();
-
for (int i = 0; i < field_count; i++)
{
if(dump) dumpElement(" TYPE CODE=");
--- 508,518 ----
short field_count = this.realInputStream.readShort();
if(dump) dumpElementln(Short.toString(field_count));
ObjectStreamField[] fields = new ObjectStreamField[field_count];
+ TemporaryStreamField[] temp_fields = new
TemporaryStreamField[field_count];
ObjectStreamClass osc = new ObjectStreamClass(name, uid,
flags, fields);
assignNewHandle(osc);
for (int i = 0; i < field_count; i++)
{
if(dump) dumpElement(" TYPE CODE=");
***************
*** 521,529 ****
class_name = (String)readObject();
else
class_name = String.valueOf(type_code);
!
! fields[i] =
! new ObjectStreamField(field_name, class_name, callersClassLoader);
}
/* Now that fields have been read we may resolve the class
--- 530,537 ----
class_name = (String)readObject();
else
class_name = String.valueOf(type_code);
!
! temp_fields[i] = new TemporaryStreamField(field_name, class_name);
}
/* Now that fields have been read we may resolve the class
***************
*** 558,563 ****
--- 566,577 ----
throw cnfe;
}
+ ClassLoader loader = clazz.getClassLoader();
+ for(int i =0; i < field_count; i++)
+ fields[i] = new ObjectStreamField(temp_fields[i].field_name,
+ temp_fields[i].class_name, loader);
+
+
boolean oldmode = setBlockDataMode(true);
osc.setClass(clazz, lookupClass(clazz.getSuperclass()));
classLookupTable.put(clazz, osc);
------------------------------------------------------------------------
_______________________________________________
Classpath mailing list
address@hidden
http://lists.gnu.org/mailman/listinfo/classpath