diff options
author | Mark Wielaard <mark@klomp.org> | 2003-01-04 03:44:07 +0000 |
---|---|---|
committer | Mark Wielaard <mark@gcc.gnu.org> | 2003-01-04 03:44:07 +0000 |
commit | 3aa0cc4e82a3f0455704a262e0b715f127ca019b (patch) | |
tree | 74b3f7ec645e8f76f6314fcc86bc21fca8f8e9b5 /libjava | |
parent | 2d2d0877ca0d5477ec0100aed0934bf35f5a20c1 (diff) | |
download | gcc-3aa0cc4e82a3f0455704a262e0b715f127ca019b.zip gcc-3aa0cc4e82a3f0455704a262e0b715f127ca019b.tar.gz gcc-3aa0cc4e82a3f0455704a262e0b715f127ca019b.tar.bz2 |
Merge with Classpath:
* java/io/ObjectStreamClass.java (lookup): Split method and call
lookupForClassObject().
(lookupForClassObject): New method.
(isProxyClass): New field.
(setClass): Set isProxyClass, add object to classLookupTable, set
superClass and calculateOffsets.
(ObjectStreamClass): Set isProxyClass. Only set uid when Serializable
and not a proxy class.
(setFields): Set accessible true for serialPersistentFields.
(getClassUID): Same for suid. And check if suid is of type long.
(hasClassInitializer): Don't throw NoSuchMethodError.
From-SVN: r60867
Diffstat (limited to 'libjava')
-rw-r--r-- | libjava/ChangeLog | 15 | ||||
-rw-r--r-- | libjava/java/io/ObjectStreamClass.java | 110 |
2 files changed, 82 insertions, 43 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog index 7489088..b38a3a5 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,5 +1,20 @@ 2003-01-03 Mark Wielaard <mark@klomp.org> + Merge with Classpath: + * java/io/ObjectStreamClass.java (lookup): Split method and call + lookupForClassObject(). + (lookupForClassObject): New method. + (isProxyClass): New field. + (setClass): Set isProxyClass, add object to classLookupTable, set + superClass and calculateOffsets. + (ObjectStreamClass): Set isProxyClass. Only set uid when Serializable + and not a proxy class. + (setFields): Set accessible true for serialPersistentFields. + (getClassUID): Same for suid. And check if suid is of type long. + (hasClassInitializer): Don't throw NoSuchMethodError. + +2003-01-03 Mark Wielaard <mark@klomp.org> + * java/io/FileInputStream.java (finalize): Don't explicitly finalize FileDescriptor. diff --git a/libjava/java/io/ObjectStreamClass.java b/libjava/java/io/ObjectStreamClass.java index ecdd91d..5d4c102 100644 --- a/libjava/java/io/ObjectStreamClass.java +++ b/libjava/java/io/ObjectStreamClass.java @@ -1,6 +1,6 @@ /* ObjectStreamClass.java -- Class used to write class information about serialized objects. - Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -44,6 +44,7 @@ import java.lang.reflect.Field; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.lang.reflect.Proxy; import java.security.DigestOutputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -76,6 +77,19 @@ public class ObjectStreamClass implements Serializable if (! (Serializable.class).isAssignableFrom (cl)) return null; + return lookupForClassObject (cl); + } + + /** + * This lookup for internal use by ObjectOutputStream. Suppose + * we have a java.lang.Class object C for class A, though A is not + * serializable, but it's okay to serialize C. + */ + static ObjectStreamClass lookupForClassObject (Class cl) + { + if (cl == null) + return null; + ObjectStreamClass osc = (ObjectStreamClass)classLookupTable.get (cl); if (osc != null) @@ -260,22 +274,29 @@ public class ObjectStreamClass implements Serializable void setClass (Class cl) throws InvalidClassException { this.clazz = cl; + long class_uid = getClassUID (cl); if (uid == 0) + uid = class_uid; + else { - uid = class_uid; - return; - } - - // Check that the actual UID of the resolved class matches the UID from - // the stream. - if (uid != class_uid) - { - String msg = cl + - ": Local class not compatible: stream serialVersionUID=" - + uid + ", local serialVersionUID=" + class_uid; - throw new InvalidClassException (msg); + // Check that the actual UID of the resolved class matches the UID from + // the stream. + if (uid != class_uid) + { + String msg = cl + + ": Local class not compatible: stream serialVersionUID=" + + uid + ", local serialVersionUID=" + class_uid; + throw new InvalidClassException (msg); + } } + + isProxyClass = clazz != null && Proxy.isProxyClass (clazz); + ObjectStreamClass osc = (ObjectStreamClass)classLookupTable.get (clazz); + if (osc == null) + classLookupTable.put (clazz, this); + superClass = lookupForClassObject (clazz.getSuperclass ()); + calculateOffsets (); } void setSuperclass (ObjectStreamClass osc) @@ -328,12 +349,15 @@ public class ObjectStreamClass implements Serializable { uid = 0; flags = 0; + isProxyClass = Proxy.isProxyClass (cl); clazz = cl; name = cl.getName (); setFlags (cl); setFields (cl); - uid = getClassUID (cl); + // to those class nonserializable, its uid field is 0 + if ( (Serializable.class).isAssignableFrom (cl) && !isProxyClass) + uid = getClassUID (cl); superClass = lookup (cl.getSuperclass ()); } @@ -377,6 +401,7 @@ public class ObjectStreamClass implements Serializable { Field serialPersistentFields = cl.getDeclaredField ("serialPersistentFields"); + serialPersistentFields.setAccessible(true); int modifiers = serialPersistentFields.getModifiers (); if (Modifier.isStatic (modifiers) @@ -427,26 +452,27 @@ public class ObjectStreamClass implements Serializable { try { + // Use getDeclaredField rather than getField, since serialVersionUID + // may not be public AND we only want the serialVersionUID of this + // class, not a superclass or interface. Field suid = cl.getDeclaredField ("serialVersionUID"); + suid.setAccessible(true); int modifiers = suid.getModifiers (); - if (Modifier.isStatic (modifiers) && Modifier.isFinal (modifiers)) - return suid.getLong (null); + if (Modifier.isStatic (modifiers) + && Modifier.isFinal (modifiers) + && suid.getType() == Long.TYPE) + return suid.getLong (null); } catch (NoSuchFieldException ignore) - { - } + {} catch (IllegalAccessException ignore) - { - } + {} // cl didn't define serialVersionUID, so we have to compute it try { - MessageDigest md = null; - DigestOutputStream digest_out = null; - DataOutputStream data_out = null; - + MessageDigest md; try { md = MessageDigest.getInstance ("SHA"); @@ -459,8 +485,10 @@ public class ObjectStreamClass implements Serializable md = MessageDigest.getInstance ("SHA"); } - digest_out = new DigestOutputStream (nullOutputStream, md); - data_out = new DataOutputStream (digest_out); + DigestOutputStream digest_out = + new DigestOutputStream (nullOutputStream, md); + DataOutputStream data_out = new DataOutputStream (digest_out); + data_out.writeUTF (cl.getName ()); int modifiers = cl.getModifiers (); @@ -497,17 +525,7 @@ public class ObjectStreamClass implements Serializable } // write class initializer method if present - boolean has_init; - try - { - has_init = hasClassInitializer (cl); - } - catch (NoSuchMethodError e) - { - has_init = false; - } - - if (has_init) + if (hasClassInitializer (cl)) { data_out.writeUTF ("<clinit>"); data_out.writeInt (Modifier.STATIC); @@ -564,11 +582,11 @@ public class ObjectStreamClass implements Serializable catch (NoSuchAlgorithmException e) { throw new RuntimeException ("The SHA algorithm was not found to use in computing the Serial Version UID for class " - + cl.getName ()); + + cl.getName (), e); } catch (IOException ioe) { - throw new RuntimeException (ioe.getMessage ()); + throw new RuntimeException (ioe); } } @@ -582,6 +600,7 @@ public class ObjectStreamClass implements Serializable // Use getDeclaredField rather than getField for the same reason // as above in getDefinedSUID. Field f = clazz.getDeclaredField ("getSerialPersistentFields"); + f.setAccessible(true); o = (ObjectStreamField[])f.get (null); } catch (java.lang.NoSuchFieldException e) @@ -597,21 +616,23 @@ public class ObjectStreamClass implements Serializable // Returns true if CLAZZ has a static class initializer // (a.k.a. <clinit>). - // - // A NoSuchMethodError is raised if CLAZZ has no such method. private static boolean hasClassInitializer (Class clazz) - throws java.lang.NoSuchMethodError { Method m = null; try { + /* + * There exists a problem here, according to the spec + * clazz.getDeclaredMethod ("<clinit>", classArgs); + * will always throw NoSuchMethodException, even if the static + * intializer does exist. + */ Class classArgs[] = {}; m = clazz.getDeclaredMethod ("<clinit>", classArgs); } catch (java.lang.NoSuchMethodException e) { - throw new java.lang.NoSuchMethodError (); } return m != null; @@ -640,9 +661,12 @@ public class ObjectStreamClass implements Serializable int primFieldSize = -1; // -1 if not yet calculated int objectFieldCount; + boolean isProxyClass = false; + // This is probably not necessary because this class is special cased already // but it will avoid showing up as a discrepancy when comparing SUIDs. private static final long serialVersionUID = -6120832682080437368L; + } |