ObjectInputStream.java: Made all calls to dumpElement[ln] conditional on dump flag.

2004-02-06  Jeroen Frijters  <jeroen@frijters.net>

	* java/io/ObjectInputStream.java: Made all calls
	to dumpElement[ln] conditional on dump flag. (readObject): Changed to
	use cached info from ObjectStreamClass. (readClassDescriptor):
	Cache more information in ObjectStreamClass. (processResolution,
	readFields): Use cached info from ObjectStreamClass.
	(newObject): Throw exception instead of returning null for failure.
	(getField, getMethod, callReadMethod, setBooleanField, setByteField,
	setCharField, setDoubleField, setFloatField, setIntField,
	setLongField, setShortField, setObjectField, readObjectParams):
	Removed. (dumpElement, dumpElementln): Removed dump flag condition
	check.
	* java/io/ObjectStreamField.java (hasReadMethod): Removed.
	(setClass): Added call to cacheMethods() (findMethod): New method.
	(cacheMethods): New method. (ObjectStreamClass): Added call to
	cacheMethods(). (setFields): Cache fields. (getClassUID): Use
	AccessController.doPrivileged to invoke setAccessible.
	(readObjectMethod, readResolveMethod, realClassIsSerializable,
	realClassIsExternalizable, fieldMapping, firstNonSerializableParent):
	New fields.
	* java/io/ObjectStreamField.java (ObjectStreamField): New constructor.
	(ObjectStreamField): Removed FIXME workaround. (getTypeString,
	isPrimitive): Made safe for cases where type == null.
	(setBooleanField, setByteField, setCharField, setShortField,
	setIntField, setLongField, setFloatField, setDoubleField,
	setObjectField): New methods.

From-SVN: r77395
This commit is contained in:
Jeroen Frijters 2004-02-06 13:27:36 +00:00 committed by Michael Koch
parent eb457a7a07
commit 2941cc061a
4 changed files with 487 additions and 596 deletions

View File

@ -1,3 +1,31 @@
2004-02-06 Jeroen Frijters <jeroen@frijters.net>
* java/io/ObjectInputStream.java: Made all calls
to dumpElement[ln] conditional on dump flag. (readObject): Changed to
use cached info from ObjectStreamClass. (readClassDescriptor):
Cache more information in ObjectStreamClass. (processResolution,
readFields): Use cached info from ObjectStreamClass.
(newObject): Throw exception instead of returning null for failure.
(getField, getMethod, callReadMethod, setBooleanField, setByteField,
setCharField, setDoubleField, setFloatField, setIntField,
setLongField, setShortField, setObjectField, readObjectParams):
Removed. (dumpElement, dumpElementln): Removed dump flag condition
check.
* java/io/ObjectStreamField.java (hasReadMethod): Removed.
(setClass): Added call to cacheMethods() (findMethod): New method.
(cacheMethods): New method. (ObjectStreamClass): Added call to
cacheMethods(). (setFields): Cache fields. (getClassUID): Use
AccessController.doPrivileged to invoke setAccessible.
(readObjectMethod, readResolveMethod, realClassIsSerializable,
realClassIsExternalizable, fieldMapping, firstNonSerializableParent):
New fields.
* java/io/ObjectStreamField.java (ObjectStreamField): New constructor.
(ObjectStreamField): Removed FIXME workaround. (getTypeString,
isPrimitive): Made safe for cases where type == null.
(setBooleanField, setByteField, setCharField, setShortField,
setIntField, setLongField, setFloatField, setDoubleField,
setObjectField): New methods.
2004-02-05 Thomas Fitzsimmons <fitzsim@redhat.com>
* java/awt/Component.java (getFont): Return a default font

File diff suppressed because it is too large Load Diff

View File

@ -45,9 +45,11 @@ import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.security.AccessController;
import java.security.DigestOutputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivilegedAction;
import java.security.Security;
import java.util.Arrays;
import java.util.Comparator;
@ -192,29 +194,6 @@ public class ObjectStreamClass implements Serializable
return (flags & ObjectStreamConstants.SC_WRITE_METHOD) != 0;
}
// Returns true iff the class that this ObjectStreamClass represents
// has the following method:
//
// private void readObject (ObjectOutputStream)
//
// This method is used by the class to override default
// serialization behavior.
boolean hasReadMethod()
{
try
{
Class[] readObjectParams = { ObjectInputStream.class };
forClass().getDeclaredMethod("readObject", readObjectParams);
return true;
}
catch (NoSuchMethodException e)
{
return false;
}
}
// Returns true iff the class that this ObjectStreamClass represents
// implements Serializable but does *not* implement Externalizable.
boolean isSerializable()
@ -306,6 +285,8 @@ public class ObjectStreamClass implements Serializable
{
this.clazz = cl;
cacheMethods();
long class_uid = getClassUID(cl);
if (uid == 0)
uid = class_uid;
@ -452,6 +433,50 @@ public class ObjectStreamClass implements Serializable
fields[i].setOffset(objectFieldCount++);
}
private Method findMethod(Method[] methods, String name, Class[] params,
Class returnType)
{
outer:
for(int i = 0; i < methods.length; i++)
{
if(methods[i].getName().equals(name) &&
methods[i].getReturnType() == returnType)
{
Class[] mp = methods[i].getParameterTypes();
if(mp.length == params.length)
{
for(int j = 0; j < mp.length; j++)
{
if(mp[j] != params[j])
{
continue outer;
}
}
final Method m = methods[i];
AccessController.doPrivileged(new PrivilegedAction()
{
public Object run()
{
m.setAccessible(true);
return null;
}
});
return m;
}
}
}
return null;
}
private void cacheMethods()
{
Method[] methods = forClass().getDeclaredMethods();
readObjectMethod = findMethod(methods, "readObject",
new Class[] { ObjectInputStream.class },
Void.TYPE);
readResolveMethod = findMethod(methods, "readResolve",
new Class[0], Object.class);
}
private ObjectStreamClass(Class cl)
{
@ -460,6 +485,7 @@ public class ObjectStreamClass implements Serializable
isProxyClass = Proxy.isProxyClass(cl);
clazz = cl;
cacheMethods();
name = cl.getName();
setFlags(cl);
setFields(cl);
@ -508,9 +534,16 @@ public class ObjectStreamClass implements Serializable
try
{
Field serialPersistentFields =
final Field serialPersistentFields =
cl.getDeclaredField("serialPersistentFields");
serialPersistentFields.setAccessible(true);
AccessController.doPrivileged(new PrivilegedAction()
{
public Object run()
{
serialPersistentFields.setAccessible(true);
return null;
}
});
int modifiers = serialPersistentFields.getModifiers();
if (Modifier.isStatic(modifiers)
@ -553,12 +586,28 @@ public class ObjectStreamClass implements Serializable
for (int from = 0, to = 0; from < all_fields.length; from++)
if (all_fields[from] != null)
{
Field f = all_fields[from];
fields[to] = new ObjectStreamField(f.getName(), f.getType());
final Field f = all_fields[from];
AccessController.doPrivileged(new PrivilegedAction()
{
public Object run()
{
f.setAccessible(true);
return null;
}
});
fields[to] = new ObjectStreamField(all_fields[from]);
to++;
}
Arrays.sort(fields);
// Make sure we don't have any duplicate field names
// (Sun JDK 1.4.1. throws an Internal Error as well)
for (int i = 1; i < fields.length; i++)
{
if(fields[i - 1].getName().equals(fields[i].getName()))
throw new InternalError("Duplicate field " +
fields[i].getName() + " in class " + cl.getName());
}
calculateOffsets();
}
@ -571,8 +620,15 @@ public class ObjectStreamClass implements Serializable
// 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);
final Field suid = cl.getDeclaredField("serialVersionUID");
AccessController.doPrivileged(new PrivilegedAction()
{
public Object run()
{
suid.setAccessible(true);
return null;
}
});
int modifiers = suid.getModifiers();
if (Modifier.isStatic(modifiers)
@ -769,6 +825,13 @@ public class ObjectStreamClass implements Serializable
int primFieldSize = -1; // -1 if not yet calculated
int objectFieldCount;
Method readObjectMethod;
Method readResolveMethod;
boolean realClassIsSerializable;
boolean realClassIsExternalizable;
ObjectStreamField[] fieldMapping;
Class firstNonSerializableParent;
boolean isProxyClass = false;
// This is probably not necessary because this class is special cased already

View File

@ -38,6 +38,8 @@ exception statement from your version. */
package java.io;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import gnu.java.lang.reflect.TypeSignature;
/**
@ -54,6 +56,14 @@ public class ObjectStreamField implements Comparable
private boolean unshared;
private boolean persistent = false;
private boolean toset = true;
private Field field;
ObjectStreamField (Field field)
{
this (field.getName(), field.getType());
this.field = field;
toset = !Modifier.isFinal(field.getModifiers());
}
/**
* This constructor creates an ObjectStreamField instance
@ -105,7 +115,6 @@ public class ObjectStreamField implements Comparable
}
catch(ClassNotFoundException e)
{
type = Object.class; //FIXME: ???
}
}
@ -128,7 +137,6 @@ public class ObjectStreamField implements Comparable
}
catch(ClassNotFoundException e)
{
type = Object.class; // ALSO FIXME
}
}
@ -176,7 +184,7 @@ public class ObjectStreamField implements Comparable
public String getTypeString ()
{
// use intern()
if (this.type.isPrimitive())
if (isPrimitive())
return null;
return typename.intern();
}
@ -225,7 +233,7 @@ public class ObjectStreamField implements Comparable
*/
public boolean isPrimitive ()
{
return type.isPrimitive ();
return typename.length() == 1;
}
public int compareTo (Object o)
@ -299,5 +307,112 @@ public class ObjectStreamField implements Comparable
{
return "ObjectStreamField< " + type + " " + name + " >";
}
}
final void setBooleanField(Object obj, boolean val)
{
try
{
field.setBoolean(obj, val);
}
catch(IllegalAccessException x)
{
throw new InternalError(x.getMessage());
}
}
final void setByteField(Object obj, byte val)
{
try
{
field.setByte(obj, val);
}
catch(IllegalAccessException x)
{
throw new InternalError(x.getMessage());
}
}
final void setCharField(Object obj, char val)
{
try
{
field.setChar(obj, val);
}
catch(IllegalAccessException x)
{
throw new InternalError(x.getMessage());
}
}
final void setShortField(Object obj, short val)
{
try
{
field.setShort(obj, val);
}
catch(IllegalAccessException x)
{
throw new InternalError(x.getMessage());
}
}
final void setIntField(Object obj, int val)
{
try
{
field.setInt(obj, val);
}
catch(IllegalAccessException x)
{
throw new InternalError(x.getMessage());
}
}
final void setLongField(Object obj, long val)
{
try
{
field.setLong(obj, val);
}
catch(IllegalAccessException x)
{
throw new InternalError(x.getMessage());
}
}
final void setFloatField(Object obj, float val)
{
try
{
field.setFloat(obj, val);
}
catch(IllegalAccessException x)
{
throw new InternalError(x.getMessage());
}
}
final void setDoubleField(Object obj, double val)
{
try
{
field.setDouble(obj, val);
}
catch(IllegalAccessException x)
{
throw new InternalError(x.getMessage());
}
}
final void setObjectField(Object obj, Object val)
{
try
{
field.set(obj, val);
}
catch(IllegalAccessException x)
{
throw new InternalError(x.getMessage());
}
}
}