From 9ba35eac69022998573b5e2b21022708fd9a0f11 Mon Sep 17 00:00:00 2001 From: mark Date: Wed, 16 Nov 2005 16:30:03 +0000 Subject: [PATCH] 2005-11-15 Jeroen Frijters * java/io/ObjectInputStream.java (parseContent): Removed bogus println and fixed bug #24422. 2005-11-15 Mark Wielaard * java/io/ObjectStreamClass.java: Removed, fully merged now. * sources.am: Regenerated. * Makefile.in: Regenerated. 2005-11-15 Wolfgang Baer * java/io/ObjectInputStream.java (processResolution): Pass Error, RuntimeException and ObjectStreamException through to the caller. (readObject): Documentation update. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@107088 138bc75d-0d04-0410-961f-82ee72b054a4 --- libjava/ChangeLog | 18 + libjava/Makefile.in | 2 +- libjava/java/io/ObjectInputStream.java | 30 +- libjava/java/io/ObjectStreamClass.java | 977 --------------------------------- libjava/sources.am | 2 +- 5 files changed, 47 insertions(+), 982 deletions(-) delete mode 100644 libjava/java/io/ObjectStreamClass.java diff --git a/libjava/ChangeLog b/libjava/ChangeLog index c7b541a5dca..86042d8eadc 100644 --- a/libjava/ChangeLog +++ b/libjava/ChangeLog @@ -1,3 +1,21 @@ +2005-11-15 Jeroen Frijters + + * java/io/ObjectInputStream.java + (parseContent): Removed bogus println and fixed bug #24422. + +2005-11-15 Mark Wielaard + + * java/io/ObjectStreamClass.java: Removed, fully merged now. + * sources.am: Regenerated. + * Makefile.in: Regenerated. + +2005-11-15 Wolfgang Baer + + * java/io/ObjectInputStream.java + (processResolution): Pass Error, RuntimeException and + ObjectStreamException through to the caller. + (readObject): Documentation update. + 2005-11-15 Mark Wielaard Imported GNU Classpath 0.19 + gcj-import-20051115. diff --git a/libjava/Makefile.in b/libjava/Makefile.in index 77f11cc2348..22287d09ef4 100644 --- a/libjava/Makefile.in +++ b/libjava/Makefile.in @@ -2612,7 +2612,7 @@ java/io/ObjectInputStream.java \ classpath/java/io/ObjectInputValidation.java \ classpath/java/io/ObjectOutput.java \ classpath/java/io/ObjectOutputStream.java \ -java/io/ObjectStreamClass.java \ +classpath/java/io/ObjectStreamClass.java \ classpath/java/io/ObjectStreamConstants.java \ classpath/java/io/ObjectStreamException.java \ classpath/java/io/ObjectStreamField.java \ diff --git a/libjava/java/io/ObjectInputStream.java b/libjava/java/io/ObjectInputStream.java index 47fd0789306..54661a9bc53 100644 --- a/libjava/java/io/ObjectInputStream.java +++ b/libjava/java/io/ObjectInputStream.java @@ -113,7 +113,10 @@ public class ObjectInputStream extends InputStream * private void readObject (ObjectInputStream). * * If an exception is thrown from this method, the stream is left in - * an undefined state. + * an undefined state. This method can also throw Errors and + * RuntimeExceptions if caused by existing readResolve() user code. + * + * @return The object read from the underlying stream. * * @exception ClassNotFoundException The class that an object being * read in belongs to cannot be found. @@ -199,7 +202,6 @@ public class ObjectInputStream extends InputStream for (int i = 0; i < n_intf; i++) { intfs[i] = this.realInputStream.readUTF(); - System.out.println(intfs[i]); } boolean oldmode = setBlockDataMode(true); @@ -207,6 +209,21 @@ public class ObjectInputStream extends InputStream setBlockDataMode(oldmode); ObjectStreamClass osc = lookupClass(cl); + if (osc.firstNonSerializableParentConstructor == null) + { + osc.realClassIsSerializable = true; + osc.fields = osc.fieldMapping = new ObjectStreamField[0]; + try + { + osc.firstNonSerializableParentConstructor = + Object.class.getConstructor(new Class[0]); + } + catch (NoSuchMethodException x) + { + throw (InternalError) + new InternalError("Object ctor missing").initCause(x); + } + } assignNewHandle(osc); if (!is_consumed) @@ -1558,8 +1575,15 @@ public class ObjectInputStream extends InputStream catch (IllegalAccessException ignore) { } - catch (InvocationTargetException ignore) + catch (InvocationTargetException exception) { + Throwable cause = exception.getCause(); + if (cause instanceof ObjectStreamException) + throw (ObjectStreamException) cause; + else if (cause instanceof RuntimeException) + throw (RuntimeException) cause; + else if (cause instanceof Error) + throw (Error) cause; } } diff --git a/libjava/java/io/ObjectStreamClass.java b/libjava/java/io/ObjectStreamClass.java deleted file mode 100644 index 975dbfc66d0..00000000000 --- a/libjava/java/io/ObjectStreamClass.java +++ /dev/null @@ -1,977 +0,0 @@ -/* ObjectStreamClass.java -- Class used to write class information - about serialized objects. - Copyright (C) 1998, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package java.io; - -import gnu.java.io.NullOutputStream; -import gnu.java.lang.reflect.TypeSignature; -import gnu.java.security.action.SetAccessibleAction; -import gnu.java.security.provider.Gnu; - -import java.lang.reflect.Constructor; -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.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; -import java.util.Hashtable; -import java.util.Vector; - -public class ObjectStreamClass implements Serializable -{ - /** - * Returns the ObjectStreamClass for cl. - * If cl is null, or is not Serializable, - * null is returned. ObjectStreamClass's are memorized; - * later calls to this method with the same class will return the - * same ObjectStreamClass object and no recalculation - * will be done. - * - * @see java.io.Serializable - */ - public static ObjectStreamClass lookup(Class cl) - { - if (cl == null) - return null; - 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) - return osc; - else - { - osc = new ObjectStreamClass(cl); - classLookupTable.put(cl, osc); - return osc; - } - } - - /** - * Returns the name of the class that this - * ObjectStreamClass represents. - * - * @return the name of the class. - */ - public String getName() - { - return name; - } - - /** - * Returns the class that this ObjectStreamClass - * represents. Null could be returned if this - * ObjectStreamClass was read from an - * ObjectInputStream and the class it represents cannot - * be found or loaded. - * - * @see java.io.ObjectInputStream - */ - public Class forClass() - { - return clazz; - } - - /** - * Returns the serial version stream-unique identifier for the class - * represented by this ObjectStreamClass. This SUID is - * either defined by the class as static final long - * serialVersionUID or is calculated as specified in - * Javasoft's "Object Serialization Specification" XXX: add reference - * - * @return the serial version UID. - */ - public long getSerialVersionUID() - { - return uid; - } - - /** - * Returns the serializable (non-static and non-transient) Fields - * of the class represented by this ObjectStreamClass. The Fields - * are sorted by name. - * - * @return the fields. - */ - public ObjectStreamField[] getFields() - { - ObjectStreamField[] copy = new ObjectStreamField[ fields.length ]; - System.arraycopy(fields, 0, copy, 0, fields.length); - return copy; - } - - // XXX doc - // Can't do binary search since fields is sorted by name and - // primitiveness. - public ObjectStreamField getField (String name) - { - for (int i = 0; i < fields.length; i++) - if (fields[i].getName().equals(name)) - return fields[i]; - return null; - } - - /** - * Returns a textual representation of this - * ObjectStreamClass object including the name of the - * class it represents as well as that class's serial version - * stream-unique identifier. - * - * @see #getSerialVersionUID() - * @see #getName() - */ - public String toString() - { - return "java.io.ObjectStreamClass< " + name + ", " + uid + " >"; - } - - // Returns true iff the class that this ObjectStreamClass represents - // has the following method: - // - // private void writeObject (ObjectOutputStream) - // - // This method is used by the class to override default - // serialization behavior. - boolean hasWriteMethod() - { - return (flags & ObjectStreamConstants.SC_WRITE_METHOD) != 0; - } - - // Returns true iff the class that this ObjectStreamClass represents - // implements Serializable but does *not* implement Externalizable. - boolean isSerializable() - { - return (flags & ObjectStreamConstants.SC_SERIALIZABLE) != 0; - } - - - // Returns true iff the class that this ObjectStreamClass represents - // implements Externalizable. - boolean isExternalizable() - { - return (flags & ObjectStreamConstants.SC_EXTERNALIZABLE) != 0; - } - - - // Returns the ObjectStreamClass that represents the - // class that is the superclass of the class this - // ObjectStreamClass represents. If the superclass is - // not Serializable, null is returned. - ObjectStreamClass getSuper() - { - return superClass; - } - - - // returns an array of ObjectStreamClasses that represent the super - // classes of CLAZZ and CLAZZ itself in order from most super to - // CLAZZ. ObjectStreamClass[0] is the highest superclass of CLAZZ - // that is serializable. - static ObjectStreamClass[] getObjectStreamClasses(Class clazz) - { - ObjectStreamClass osc = ObjectStreamClass.lookup(clazz); - - if (osc == null) - return new ObjectStreamClass[0]; - else - { - Vector oscs = new Vector(); - - while (osc != null) - { - oscs.addElement (osc); - osc = osc.getSuper(); - } - - int count = oscs.size(); - ObjectStreamClass[] sorted_oscs = new ObjectStreamClass[ count ]; - - for (int i = count - 1; i >= 0; i--) - sorted_oscs[ count - i - 1 ] = (ObjectStreamClass) oscs.elementAt(i); - - return sorted_oscs; - } - } - - - // Returns an integer that consists of bit-flags that indicate - // properties of the class represented by this ObjectStreamClass. - // The bit-flags that could be present are those defined in - // ObjectStreamConstants that begin with `SC_' - int getFlags() - { - return flags; - } - - - ObjectStreamClass(String name, long uid, byte flags, - ObjectStreamField[] fields) - { - this.name = name; - this.uid = uid; - this.flags = flags; - this.fields = fields; - } - - /** - * This method builds the internal description corresponding to a Java Class. - * As the constructor only assign a name to the current ObjectStreamClass instance, - * that method sets the serial UID, chose the fields which will be serialized, - * and compute the position of the fields in the serialized stream. - * - * @param cl The Java class which is used as a reference for building the descriptor. - * @param superClass The descriptor of the super class for this class descriptor. - * @throws InvalidClassException if an incompatibility between computed UID and - * already set UID is found. - */ - void setClass(Class cl, ObjectStreamClass superClass) throws InvalidClassException - { - this.clazz = cl; - - cacheMethods(); - - long class_uid = getClassUID(cl); - if (uid == 0) - uid = class_uid; - else - { - // 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); - this.superClass = superClass; - calculateOffsets(); - - try - { - ObjectStreamField[] exportedFields = getSerialPersistentFields (clazz); - - if (exportedFields == null) - return; - - ObjectStreamField[] newFieldList = new ObjectStreamField[exportedFields.length + fields.length]; - int i, j, k; - - /* We now check the import fields against the exported fields. - * There should not be contradiction (e.g. int x and String x) - * but extra virtual fields can be added to the class. - */ - - Arrays.sort(exportedFields); - - i = 0; j = 0; k = 0; - while (i < fields.length && j < exportedFields.length) - { - int comp = fields[i].compareTo(exportedFields[j]); - - if (comp < 0) - { - newFieldList[k] = fields[i]; - fields[i].setPersistent(false); - fields[i].setToSet(false); - i++; - } - else if (comp > 0) - { - /* field not found in imported fields. We add it - * in the list of supported fields. - */ - newFieldList[k] = exportedFields[j]; - newFieldList[k].setPersistent(true); - newFieldList[k].setToSet(false); - try - { - newFieldList[k].lookupField(clazz); - newFieldList[k].checkFieldType(); - } - catch (NoSuchFieldException _) - { - } - j++; - } - else - { - try - { - exportedFields[j].lookupField(clazz); - exportedFields[j].checkFieldType(); - } - catch (NoSuchFieldException _) - { - } - - if (!fields[i].getType().equals(exportedFields[j].getType())) - throw new InvalidClassException - ("serialPersistentFields must be compatible with" + - " imported fields (about " + fields[i].getName() + ")"); - newFieldList[k] = fields[i]; - fields[i].setPersistent(true); - i++; - j++; - } - k++; - } - - if (i < fields.length) - for (;i"); - data_out.writeInt(Modifier.STATIC); - data_out.writeUTF("()V"); - } - - Constructor constructor; - Constructor[] constructors = cl.getDeclaredConstructors(); - Arrays.sort (constructors, memberComparator); - for (int i = 0; i < constructors.length; i++) - { - constructor = constructors[i]; - modifiers = constructor.getModifiers(); - if (Modifier.isPrivate(modifiers)) - continue; - - data_out.writeUTF(""); - data_out.writeInt(modifiers); - - // the replacement of '/' with '.' was needed to make computed - // SUID's agree with those computed by JDK - data_out.writeUTF - (TypeSignature.getEncodingOfConstructor(constructor).replace('/','.')); - } - - Method method; - Method[] methods = cl.getDeclaredMethods(); - Arrays.sort(methods, memberComparator); - for (int i = 0; i < methods.length; i++) - { - method = methods[i]; - modifiers = method.getModifiers(); - if (Modifier.isPrivate(modifiers)) - continue; - - data_out.writeUTF(method.getName()); - data_out.writeInt(modifiers); - - // the replacement of '/' with '.' was needed to make computed - // SUID's agree with those computed by JDK - data_out.writeUTF - (TypeSignature.getEncodingOfMethod(method).replace('/', '.')); - } - - data_out.close(); - byte[] sha = md.digest(); - long result = 0; - int len = sha.length < 8 ? sha.length : 8; - for (int i = 0; i < len; i++) - result += (long) (sha[i] & 0xFF) << (8 * i); - - return result; - } - catch (NoSuchAlgorithmException e) - { - throw new RuntimeException - ("The SHA algorithm was not found to use in computing the Serial Version UID for class " - + cl.getName(), e); - } - catch (IOException ioe) - { - throw new RuntimeException(ioe); - } - } - - /** - * Returns the value of CLAZZ's private static final field named - * `serialPersistentFields'. It performs some sanity checks before - * returning the real array. Besides, the returned array is a clean - * copy of the original. So it can be modified. - * - * @param clazz Class to retrieve 'serialPersistentFields' from. - * @return The content of 'serialPersistentFields'. - */ - private ObjectStreamField[] getSerialPersistentFields(Class clazz) - throws NoSuchFieldException, IllegalAccessException - { - ObjectStreamField[] fieldsArray = null; - ObjectStreamField[] o; - - // Use getDeclaredField rather than getField for the same reason - // as above in getDefinedSUID. - Field f = clazz.getDeclaredField("serialPersistentFields"); - f.setAccessible(true); - - int modifiers = f.getModifiers(); - if (!(Modifier.isStatic(modifiers) && - Modifier.isFinal(modifiers) && - Modifier.isPrivate(modifiers))) - return null; - - o = (ObjectStreamField[]) f.get(null); - - if (o == null) - return null; - - fieldsArray = new ObjectStreamField[ o.length ]; - System.arraycopy(o, 0, fieldsArray, 0, o.length); - - return fieldsArray; - } - - /** - * Returns a new instance of the Class this ObjectStreamClass corresponds - * to. - * Note that this should only be used for Externalizable classes. - * - * @return A new instance. - */ - Externalizable newInstance() throws InvalidClassException - { - synchronized(this) - { - if (constructor == null) - { - try - { - final Constructor c = clazz.getConstructor(new Class[0]); - - AccessController.doPrivileged(new PrivilegedAction() - { - public Object run() - { - c.setAccessible(true); - return null; - } - }); - - constructor = c; - } - catch(NoSuchMethodException x) - { - throw new InvalidClassException(clazz.getName(), - "No public zero-argument constructor"); - } - } - } - - try - { - return (Externalizable)constructor.newInstance(null); - } - catch(Exception x) - { - throw (InvalidClassException) - new InvalidClassException(clazz.getName(), - "Unable to instantiate").initCause(x); - } - } - - public static final ObjectStreamField[] NO_FIELDS = {}; - - private static Hashtable classLookupTable = new Hashtable(); - private static final NullOutputStream nullOutputStream = new NullOutputStream(); - private static final Comparator interfaceComparator = new InterfaceComparator(); - private static final Comparator memberComparator = new MemberComparator(); - private static final - Class[] writeMethodArgTypes = { java.io.ObjectOutputStream.class }; - - private ObjectStreamClass superClass; - private Class clazz; - private String name; - private long uid; - private byte flags; - - // this field is package protected so that ObjectInputStream and - // ObjectOutputStream can access it directly - ObjectStreamField[] fields; - - // these are accessed by ObjectIn/OutputStream - int primFieldSize = -1; // -1 if not yet calculated - int objectFieldCount; - - Method readObjectMethod; - Method readResolveMethod; - Method writeReplaceMethod; - Method writeObjectMethod; - boolean realClassIsSerializable; - boolean realClassIsExternalizable; - ObjectStreamField[] fieldMapping; - Constructor firstNonSerializableParentConstructor; - private Constructor constructor; // default constructor for Externalizable - - 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; - - - // interfaces are compared only by name - private static final class InterfaceComparator implements Comparator - { - public int compare(Object o1, Object o2) - { - return ((Class) o1).getName().compareTo(((Class) o2).getName()); - } - } - - - // Members (Methods and Constructors) are compared first by name, - // conflicts are resolved by comparing type signatures - private static final class MemberComparator implements Comparator - { - public int compare(Object o1, Object o2) - { - Member m1 = (Member) o1; - Member m2 = (Member) o2; - - int comp = m1.getName().compareTo(m2.getName()); - - if (comp == 0) - return TypeSignature.getEncodingOfMember(m1). - compareTo(TypeSignature.getEncodingOfMember(m2)); - else - return comp; - } - } -} diff --git a/libjava/sources.am b/libjava/sources.am index a4600e0ea5d..146c67e2120 100644 --- a/libjava/sources.am +++ b/libjava/sources.am @@ -2748,7 +2748,7 @@ java/io/ObjectInputStream.java \ classpath/java/io/ObjectInputValidation.java \ classpath/java/io/ObjectOutput.java \ classpath/java/io/ObjectOutputStream.java \ -java/io/ObjectStreamClass.java \ +classpath/java/io/ObjectStreamClass.java \ classpath/java/io/ObjectStreamConstants.java \ classpath/java/io/ObjectStreamException.java \ classpath/java/io/ObjectStreamField.java \ -- 2.11.4.GIT