[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] Serialization #5
From: |
Guilhem Lavaux |
Subject: |
[PATCH] Serialization #5 |
Date: |
Tue, 02 Dec 2003 22:01:52 +0100 |
User-agent: |
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gecko/20030630 |
Hi,
This is the patch #5 (the last will be the #6) about serialization.
It fixes the following problems:
* getField handles transient and non persistent field,
* readClassDescriptor uses the right class loader to decode fields,
it also verifies that the available fields (and required by the input stream)
are
of the required types.
* if getOffset() < 0 then readFields() should not try to read any field from
the input stream.
Cheers,
Guilhem.
ChangeLog entry:
2003-12-02 Guilhem Lavaux <address@hidden>
* java/io/ObjectInputStream.java:
(getField): Handle transient and non persistent fields.
(readClassDescriptor): Better error handling, use the right class
loader.
(readFields): Fields marked as not present in the stream or not to be
set are
not read and set.
Index: java/io/ObjectInputStream.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/io/ObjectInputStream.java,v
retrieving revision 1.33
diff -u -r1.33 ObjectInputStream.java
--- java/io/ObjectInputStream.java 2 Dec 2003 18:35:51 -0000 1.33
+++ java/io/ObjectInputStream.java 2 Dec 2003 20:46:54 -0000
@@ -434,6 +434,7 @@
flags, fields);
assignNewHandle (osc);
+ int real_count;
for (int i=0; i < field_count; i++)
{
dumpElement (" TYPE CODE=");
@@ -442,18 +443,46 @@
String field_name = this.realInputStream.readUTF ();
dumpElementln (field_name);
String class_name;
-
+
+ // There're many cases you can't get java.lang.Class from
+ // typename if your context class loader can't load it,
+ // then use typename to construct the field
+ // GL => No. You lose the capability to access the class loader.
+ // Type resolution must be done here. If it is an object we
+ // create the class just here if it is something else we delegate
+ // to TypeSignature.
if (type_code == 'L' || type_code == '[')
class_name = (String)readObject ();
else
class_name = String.valueOf (type_code);
-
- // There're many cases you can't get java.lang.Class from
- // typename if your context class loader can't load it,
- // then use typename to construct the field
+
fields[i] =
- new ObjectStreamField (field_name, class_name);
+ new ObjectStreamField (field_name, class_name, currentLoader());
+ }
+
+
+ /* Now that fields have been read we may resolve the class
+ * (and read annotation if needed). */
+ Class clazz = resolveClass(osc);
+
+ for (int i=0; i < field_count; i++)
+ {
+ Field f;
+
+ try
+ {
+ f = clazz.getDeclaredField (fields[i].getName());
+ if (f != null && !f.getType().equals(fields[i].getType()))
+ throw new InvalidClassException("invalid field type for " +
+ fields[i].getName() + " in class
" + name +
+ " (requested was \"" +
fields[i].getType() +
+ " and found \"" + f.getType() +
"\")");
+ }
+ catch (NoSuchFieldException _)
+ {
+ }
}
+
Class clazz = resolveClass (osc);
boolean oldmode = setBlockDataMode (true);
@@ -1424,6 +1453,15 @@
}
}
+ if (stream_field.getOffset() < 0)
+ {
+ default_initialize = true;
+ set_value = false;
+ }
+
+ if (!stream_field.isToSet())
+ set_value = false;
+
try
{
if (type == Boolean.TYPE)
@@ -1571,10 +1609,23 @@
*/
private static native ClassLoader currentClassLoader (SecurityManager sm);
- private static Field getField (Class klass, String name)
+ /**
+ * This method tries to access a precise field called in the
+ * specified class. Before accessing the field, it tries to
+ * gain control on this field. If the field is either declared as
+ * not persistent or transient then it returns null
+ * immediately.
+ *
+ * @param klass Class to get the field from.
+ * @param name Name of the field to access.
+ * @return Field instance representing the requested field.
+ * @throws NoSuchFieldException if the field does not exist.
+ */
+ private Field getField (Class klass, String name)
throws java.lang.NoSuchFieldException
{
final Field f = klass.getDeclaredField(name);
+ ObjectStreamField sf = lookupClass (klass).getField(name);
AccessController.doPrivileged(new PrivilegedAction()
{
@@ -1584,6 +1635,14 @@
return null;
}
});
+
+ /* We do not want to modify transient fields. They should
+ * be left to 0.
+ * N.B.: Not valid if the field is in serialPersistentFields.
+ */
+ if (Modifier.isTransient(f.getModifiers()) && !sf.isPersistent())
+ return null;
+
return f;
}
- [PATCH] Serialization #5,
Guilhem Lavaux <=