classpath-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[cp-patches] FYI: Fix serialization of Class objects


From: Mark Wielaard
Subject: [cp-patches] FYI: Fix serialization of Class objects
Date: Tue, 18 Jan 2005 23:58:56 +0100

Hi,

Bug #11618 pointed out that we didn't handle (de)serialization of Class
objects. Class objects are done almost like ObjectStreamClass objects,
but they can represent objects that are not serializable and/or don't
have a serializable super class. Additional mauve tests also pointed out
that we didn't handle Object.class and Class objects for primitive types
correctly. This patch fixes that:

2005-01-18  Mark Wielaard  <address@hidden>

        Fixes bug #11618.
        * java/io/ObjectInputStream.java (readClassDescriptor): Handle classes
        without a super class and us ObjectStreamClass.lookupForClassObject().
        (resolveClass): Check for primitive types.
        (lookupClass): Return null when argument is null.

There are new Mauve tests for this, which all pass with this patch. And
this improves our unit test score for the commons-collections package
(tested by gump).

Committed,

Mark
Index: java/io/ObjectInputStream.java
===================================================================
RCS file: /cvsroot/classpath/classpath/java/io/ObjectInputStream.java,v
retrieving revision 1.50
diff -u -r1.50 ObjectInputStream.java
--- java/io/ObjectInputStream.java      7 Dec 2004 08:49:46 -0000       1.50
+++ java/io/ObjectInputStream.java      17 Jan 2005 17:06:55 -0000
@@ -1,5 +1,6 @@
 /* ObjectInputStream.java -- Class used to read serialized objects
-   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, 
Inc.
+   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005
+   Free Software Foundation, Inc.
 
 This file is part of GNU Classpath.
 
@@ -536,8 +537,14 @@
     // find the first non-serializable, non-abstract
     // class in clazz's inheritance hierarchy
     Class first_nonserial = clazz.getSuperclass();
-    while (Serializable.class.isAssignableFrom(first_nonserial)
-       || Modifier.isAbstract(first_nonserial.getModifiers()))
+    // Maybe it is a primitive class, those don't have a super class,
+    // or Object itself.  Otherwise we can keep getting the superclass
+    // till we hit the Object class, or some other non-serializable class.
+    if (first_nonserial == null)
+      first_nonserial = clazz;
+    else
+      while (Serializable.class.isAssignableFrom(first_nonserial)
+            || Modifier.isAbstract(first_nonserial.getModifiers()))
        first_nonserial = first_nonserial.getSuperclass();
 
     final Class local_constructor_class = first_nonserial;
@@ -567,7 +574,7 @@
     osc.realClassIsExternalizable = 
Externalizable.class.isAssignableFrom(clazz);
 
     ObjectStreamField[] stream_fields = osc.fields;
-    ObjectStreamField[] real_fields = ObjectStreamClass.lookup(clazz).fields;
+    ObjectStreamField[] real_fields = 
ObjectStreamClass.lookupForClassObject(clazz).fields;
     ObjectStreamField[] fieldmapping = new ObjectStreamField[2 * 
Math.max(stream_fields.length, real_fields.length)];
 
     int stream_idx = 0;
@@ -733,7 +740,37 @@
   protected Class resolveClass(ObjectStreamClass osc)
     throws ClassNotFoundException, IOException
   {
-    return Class.forName(osc.getName(), true, currentLoader());
+    try
+      {
+       return Class.forName(osc.getName(), true, currentLoader());
+      }
+    catch (ClassNotFoundException cnfe)
+      {
+       // Maybe it was an primitive class?
+       String name = osc.getName();
+       if (name.equals("void"))
+         return Void.TYPE;
+       if (name.equals("boolean"))
+         return Boolean.TYPE;
+       if (name.equals("byte"))
+         return Byte.TYPE;
+       if (name.equals("short"))
+         return Short.TYPE;
+       if (name.equals("char"))
+         return Character.TYPE;
+       if (name.equals("int"))
+         return Integer.TYPE;
+       if (name.equals("long"))
+         return Long.TYPE;
+       if (name.equals("float"))
+         return Float.TYPE;
+       if (name.equals("double"))
+         return Double.TYPE;
+       if (name.equals("void"))
+         return Void.TYPE;
+
+       throw cnfe;
+      }
   }
 
   /**
@@ -766,8 +803,10 @@
    */
   private ObjectStreamClass lookupClass(Class clazz)
   {
-    ObjectStreamClass oclazz;
+    if (clazz == null)
+      return null;
 
+    ObjectStreamClass oclazz;
     oclazz = (ObjectStreamClass)classLookupTable.get(clazz);
     if (oclazz == null)
       return ObjectStreamClass.lookup(clazz);

Attachment: signature.asc
Description: This is a digitally signed message part


reply via email to

[Prev in Thread] Current Thread [Next in Thread]