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:
Mark Wielaard 2003-01-04 03:44:07 +00:00 committed by Mark Wielaard
parent 2d2d0877ca
commit 3aa0cc4e82
2 changed files with 82 additions and 43 deletions

View file

@ -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

View file

@ -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;
}