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
This commit is contained in:
parent
2d2d0877ca
commit
3aa0cc4e82
2 changed files with 82 additions and 43 deletions
|
@ -1,3 +1,18 @@
|
|||
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
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue