Commit 3aa0cc4e by Mark Wielaard Committed by Mark Wielaard

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
parent 2d2d0877
2003-01-03 Mark Wielaard <mark@klomp.org> 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 * java/io/FileInputStream.java (finalize): Don't explicitly
finalize FileDescriptor. finalize FileDescriptor.
......
/* ObjectStreamClass.java -- Class used to write class information /* ObjectStreamClass.java -- Class used to write class information
about serialized objects. 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. This file is part of GNU Classpath.
...@@ -44,6 +44,7 @@ import java.lang.reflect.Field; ...@@ -44,6 +44,7 @@ import java.lang.reflect.Field;
import java.lang.reflect.Member; import java.lang.reflect.Member;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.security.DigestOutputStream; import java.security.DigestOutputStream;
import java.security.MessageDigest; import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException; import java.security.NoSuchAlgorithmException;
...@@ -76,6 +77,19 @@ public class ObjectStreamClass implements Serializable ...@@ -76,6 +77,19 @@ public class ObjectStreamClass implements Serializable
if (! (Serializable.class).isAssignableFrom (cl)) if (! (Serializable.class).isAssignableFrom (cl))
return null; 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); ObjectStreamClass osc = (ObjectStreamClass)classLookupTable.get (cl);
if (osc != null) if (osc != null)
...@@ -260,13 +274,12 @@ public class ObjectStreamClass implements Serializable ...@@ -260,13 +274,12 @@ public class ObjectStreamClass implements Serializable
void setClass (Class cl) throws InvalidClassException void setClass (Class cl) throws InvalidClassException
{ {
this.clazz = cl; this.clazz = cl;
long class_uid = getClassUID (cl); long class_uid = getClassUID (cl);
if (uid == 0) if (uid == 0)
{
uid = class_uid; uid = class_uid;
return; else
} {
// Check that the actual UID of the resolved class matches the UID from // Check that the actual UID of the resolved class matches the UID from
// the stream. // the stream.
if (uid != class_uid) if (uid != class_uid)
...@@ -278,6 +291,14 @@ public class ObjectStreamClass implements Serializable ...@@ -278,6 +291,14 @@ public class ObjectStreamClass implements Serializable
} }
} }
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) void setSuperclass (ObjectStreamClass osc)
{ {
superClass = osc; superClass = osc;
...@@ -328,11 +349,14 @@ public class ObjectStreamClass implements Serializable ...@@ -328,11 +349,14 @@ public class ObjectStreamClass implements Serializable
{ {
uid = 0; uid = 0;
flags = 0; flags = 0;
isProxyClass = Proxy.isProxyClass (cl);
clazz = cl; clazz = cl;
name = cl.getName (); name = cl.getName ();
setFlags (cl); setFlags (cl);
setFields (cl); setFields (cl);
// to those class nonserializable, its uid field is 0
if ( (Serializable.class).isAssignableFrom (cl) && !isProxyClass)
uid = getClassUID (cl); uid = getClassUID (cl);
superClass = lookup (cl.getSuperclass ()); superClass = lookup (cl.getSuperclass ());
} }
...@@ -377,6 +401,7 @@ public class ObjectStreamClass implements Serializable ...@@ -377,6 +401,7 @@ public class ObjectStreamClass implements Serializable
{ {
Field serialPersistentFields Field serialPersistentFields
= cl.getDeclaredField ("serialPersistentFields"); = cl.getDeclaredField ("serialPersistentFields");
serialPersistentFields.setAccessible(true);
int modifiers = serialPersistentFields.getModifiers (); int modifiers = serialPersistentFields.getModifiers ();
if (Modifier.isStatic (modifiers) if (Modifier.isStatic (modifiers)
...@@ -427,26 +452,27 @@ public class ObjectStreamClass implements Serializable ...@@ -427,26 +452,27 @@ public class ObjectStreamClass implements Serializable
{ {
try 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"); Field suid = cl.getDeclaredField ("serialVersionUID");
suid.setAccessible(true);
int modifiers = suid.getModifiers (); int modifiers = suid.getModifiers ();
if (Modifier.isStatic (modifiers) && Modifier.isFinal (modifiers)) if (Modifier.isStatic (modifiers)
&& Modifier.isFinal (modifiers)
&& suid.getType() == Long.TYPE)
return suid.getLong (null); return suid.getLong (null);
} }
catch (NoSuchFieldException ignore) catch (NoSuchFieldException ignore)
{ {}
}
catch (IllegalAccessException ignore) catch (IllegalAccessException ignore)
{ {}
}
// cl didn't define serialVersionUID, so we have to compute it // cl didn't define serialVersionUID, so we have to compute it
try try
{ {
MessageDigest md = null; MessageDigest md;
DigestOutputStream digest_out = null;
DataOutputStream data_out = null;
try try
{ {
md = MessageDigest.getInstance ("SHA"); md = MessageDigest.getInstance ("SHA");
...@@ -459,8 +485,10 @@ public class ObjectStreamClass implements Serializable ...@@ -459,8 +485,10 @@ public class ObjectStreamClass implements Serializable
md = MessageDigest.getInstance ("SHA"); md = MessageDigest.getInstance ("SHA");
} }
digest_out = new DigestOutputStream (nullOutputStream, md); DigestOutputStream digest_out =
data_out = new DataOutputStream (digest_out); new DigestOutputStream (nullOutputStream, md);
DataOutputStream data_out = new DataOutputStream (digest_out);
data_out.writeUTF (cl.getName ()); data_out.writeUTF (cl.getName ());
int modifiers = cl.getModifiers (); int modifiers = cl.getModifiers ();
...@@ -497,17 +525,7 @@ public class ObjectStreamClass implements Serializable ...@@ -497,17 +525,7 @@ public class ObjectStreamClass implements Serializable
} }
// write class initializer method if present // write class initializer method if present
boolean has_init; if (hasClassInitializer (cl))
try
{
has_init = hasClassInitializer (cl);
}
catch (NoSuchMethodError e)
{
has_init = false;
}
if (has_init)
{ {
data_out.writeUTF ("<clinit>"); data_out.writeUTF ("<clinit>");
data_out.writeInt (Modifier.STATIC); data_out.writeInt (Modifier.STATIC);
...@@ -564,11 +582,11 @@ public class ObjectStreamClass implements Serializable ...@@ -564,11 +582,11 @@ public class ObjectStreamClass implements Serializable
catch (NoSuchAlgorithmException e) catch (NoSuchAlgorithmException e)
{ {
throw new RuntimeException ("The SHA algorithm was not found to use in computing the Serial Version UID for class " 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) catch (IOException ioe)
{ {
throw new RuntimeException (ioe.getMessage ()); throw new RuntimeException (ioe);
} }
} }
...@@ -582,6 +600,7 @@ public class ObjectStreamClass implements Serializable ...@@ -582,6 +600,7 @@ public class ObjectStreamClass implements Serializable
// Use getDeclaredField rather than getField for the same reason // Use getDeclaredField rather than getField for the same reason
// as above in getDefinedSUID. // as above in getDefinedSUID.
Field f = clazz.getDeclaredField ("getSerialPersistentFields"); Field f = clazz.getDeclaredField ("getSerialPersistentFields");
f.setAccessible(true);
o = (ObjectStreamField[])f.get (null); o = (ObjectStreamField[])f.get (null);
} }
catch (java.lang.NoSuchFieldException e) catch (java.lang.NoSuchFieldException e)
...@@ -597,21 +616,23 @@ public class ObjectStreamClass implements Serializable ...@@ -597,21 +616,23 @@ public class ObjectStreamClass implements Serializable
// Returns true if CLAZZ has a static class initializer // Returns true if CLAZZ has a static class initializer
// (a.k.a. <clinit>). // (a.k.a. <clinit>).
//
// A NoSuchMethodError is raised if CLAZZ has no such method.
private static boolean hasClassInitializer (Class clazz) private static boolean hasClassInitializer (Class clazz)
throws java.lang.NoSuchMethodError
{ {
Method m = null; Method m = null;
try 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[] = {}; Class classArgs[] = {};
m = clazz.getDeclaredMethod ("<clinit>", classArgs); m = clazz.getDeclaredMethod ("<clinit>", classArgs);
} }
catch (java.lang.NoSuchMethodException e) catch (java.lang.NoSuchMethodException e)
{ {
throw new java.lang.NoSuchMethodError ();
} }
return m != null; return m != null;
...@@ -640,9 +661,12 @@ public class ObjectStreamClass implements Serializable ...@@ -640,9 +661,12 @@ public class ObjectStreamClass implements Serializable
int primFieldSize = -1; // -1 if not yet calculated int primFieldSize = -1; // -1 if not yet calculated
int objectFieldCount; int objectFieldCount;
boolean isProxyClass = false;
// This is probably not necessary because this class is special cased already // This is probably not necessary because this class is special cased already
// but it will avoid showing up as a discrepancy when comparing SUIDs. // but it will avoid showing up as a discrepancy when comparing SUIDs.
private static final long serialVersionUID = -6120832682080437368L; private static final long serialVersionUID = -6120832682080437368L;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment