diff options
author | mark <mark@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-11-16 16:30:03 +0000 |
---|---|---|
committer | mark <mark@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-11-16 16:30:03 +0000 |
commit | 9ba35eac69022998573b5e2b21022708fd9a0f11 (patch) | |
tree | 0fda62a6586bb15fee6065d0863f3e58790cd0b5 /libjava/java | |
parent | 25e54dbac3e7c96f3c8b6c1f09c387ec0030976f (diff) | |
download | ppe42-gcc-9ba35eac69022998573b5e2b21022708fd9a0f11.tar.gz ppe42-gcc-9ba35eac69022998573b5e2b21022708fd9a0f11.zip |
2005-11-15 Jeroen Frijters <jeroen@frijters.net>
* java/io/ObjectInputStream.java
(parseContent): Removed bogus println and fixed bug #24422.
2005-11-15 Mark Wielaard <mark@klomp.org>
* java/io/ObjectStreamClass.java: Removed, fully merged now.
* sources.am: Regenerated.
* Makefile.in: Regenerated.
2005-11-15 Wolfgang Baer <WBaer@gmx.de>
* 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
Diffstat (limited to 'libjava/java')
-rw-r--r-- | libjava/java/io/ObjectInputStream.java | 30 | ||||
-rw-r--r-- | libjava/java/io/ObjectStreamClass.java | 977 |
2 files changed, 27 insertions, 980 deletions
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 * <code>private void readObject (ObjectInputStream)</code>. * * 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 <code>ObjectStreamClass</code> for <code>cl</code>. - * If <code>cl</code> is null, or is not <code>Serializable</code>, - * null is returned. <code>ObjectStreamClass</code>'s are memorized; - * later calls to this method with the same class will return the - * same <code>ObjectStreamClass</code> 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 - * <code>ObjectStreamClass</code> represents. - * - * @return the name of the class. - */ - public String getName() - { - return name; - } - - /** - * Returns the class that this <code>ObjectStreamClass</code> - * represents. Null could be returned if this - * <code>ObjectStreamClass</code> was read from an - * <code>ObjectInputStream</code> 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 <code>ObjectStreamClass</code>. This SUID is - * either defined by the class as <code>static final long - * serialVersionUID</code> 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 - * <code>ObjectStreamClass</code> 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 <code>ObjectStreamClass</code> that represents the - // class that is the superclass of the class this - // <code>ObjectStreamClass</code> 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<fields.length;i++,k++) - { - fields[i].setPersistent(false); - fields[i].setToSet(false); - newFieldList[k] = fields[i]; - } - else - if (j < exportedFields.length) - for (;j<exportedFields.length;j++,k++) - { - exportedFields[j].setPersistent(true); - exportedFields[j].setToSet(false); - newFieldList[k] = exportedFields[j]; - } - - fields = new ObjectStreamField[k]; - System.arraycopy(newFieldList, 0, fields, 0, k); - } - catch (NoSuchFieldException ignore) - { - return; - } - catch (IllegalAccessException ignore) - { - return; - } - } - - void setSuperclass (ObjectStreamClass osc) - { - superClass = osc; - } - - void calculateOffsets() - { - int i; - ObjectStreamField field; - primFieldSize = 0; - int fcount = fields.length; - for (i = 0; i < fcount; ++ i) - { - field = fields[i]; - - if (! field.isPrimitive()) - break; - - field.setOffset(primFieldSize); - switch (field.getTypeCode()) - { - case 'B': - case 'Z': - ++ primFieldSize; - break; - case 'C': - case 'S': - primFieldSize += 2; - break; - case 'I': - case 'F': - primFieldSize += 4; - break; - case 'D': - case 'J': - primFieldSize += 8; - break; - } - } - - for (objectFieldCount = 0; i < fcount; ++ i) - fields[i].setOffset(objectFieldCount++); - } - - private Method findMethod(Method[] methods, String name, Class[] params, - Class returnType, boolean mustBePrivate) - { -outer: - for (int i = 0; i < methods.length; i++) - { - final Method m = methods[i]; - int mods = m.getModifiers(); - if (Modifier.isStatic(mods) - || (mustBePrivate && !Modifier.isPrivate(mods))) - { - continue; - } - - if (m.getName().equals(name) - && m.getReturnType() == returnType) - { - Class[] mp = m.getParameterTypes(); - if (mp.length == params.length) - { - for (int j = 0; j < mp.length; j++) - { - if (mp[j] != params[j]) - { - continue outer; - } - } - AccessController.doPrivileged(new SetAccessibleAction(m)); - return m; - } - } - } - return null; - } - - private static boolean inSamePackage(Class c1, Class c2) - { - String name1 = c1.getName(); - String name2 = c2.getName(); - - int id1 = name1.lastIndexOf('.'); - int id2 = name2.lastIndexOf('.'); - - // Handle the default package - if (id1 == -1 || id2 == -1) - return id1 == id2; - - String package1 = name1.substring(0, id1); - String package2 = name2.substring(0, id2); - - return package1.equals(package2); - } - - final static Class[] noArgs = new Class[0]; - - private static Method findAccessibleMethod(String name, Class from) - { - for (Class c = from; c != null; c = c.getSuperclass()) - { - try - { - Method res = c.getDeclaredMethod(name, noArgs); - int mods = res.getModifiers(); - - if (c == from - || Modifier.isProtected(mods) - || Modifier.isPublic(mods) - || (! Modifier.isPrivate(mods) && inSamePackage(c, from))) - { - AccessController.doPrivileged(new SetAccessibleAction(res)); - return res; - } - } - catch (NoSuchMethodException e) - { - } - } - - return null; - } - - private void cacheMethods() - { - Method[] methods = forClass().getDeclaredMethods(); - - readObjectMethod = findMethod(methods, "readObject", - new Class[] { ObjectInputStream.class }, - Void.TYPE, true); - writeObjectMethod = findMethod(methods, "writeObject", - new Class[] { ObjectOutputStream.class }, - Void.TYPE, true); - - // readResolve and writeReplace can be in parent classes, as long as they - // are accessible from this class. - readResolveMethod = findAccessibleMethod("readResolve", forClass()); - writeReplaceMethod = findAccessibleMethod("writeReplace", forClass()); - } - - private ObjectStreamClass(Class cl) - { - uid = 0; - flags = 0; - isProxyClass = Proxy.isProxyClass(cl); - - clazz = cl; - cacheMethods(); - name = cl.getName(); - setFlags(cl); - setFields(cl); - // to those class nonserializable, its uid field is 0 - if ( (Serializable.class).isAssignableFrom(cl) && !isProxyClass) - uid = getClassUID(cl); - superClass = lookup(cl.getSuperclass()); - } - - - // Sets bits in flags according to features of CL. - private void setFlags(Class cl) - { - if ((java.io.Externalizable.class).isAssignableFrom(cl)) - flags |= ObjectStreamConstants.SC_EXTERNALIZABLE; - else if ((java.io.Serializable.class).isAssignableFrom(cl)) - // only set this bit if CL is NOT Externalizable - flags |= ObjectStreamConstants.SC_SERIALIZABLE; - - if (writeObjectMethod != null) - flags |= ObjectStreamConstants.SC_WRITE_METHOD; - } - - - // Sets fields to be a sorted array of the serializable fields of - // clazz. - private void setFields(Class cl) - { - SetAccessibleAction setAccessible = new SetAccessibleAction(); - - if (!isSerializable() || isExternalizable()) - { - fields = NO_FIELDS; - return; - } - - try - { - final Field f = - cl.getDeclaredField("serialPersistentFields"); - setAccessible.setMember(f); - AccessController.doPrivileged(setAccessible); - int modifiers = f.getModifiers(); - - if (Modifier.isStatic(modifiers) - && Modifier.isFinal(modifiers) - && Modifier.isPrivate(modifiers)) - { - fields = getSerialPersistentFields(cl); - if (fields != null) - { - Arrays.sort (fields); - // Retrieve field reference. - for (int i=0; i < fields.length; i++) - { - try - { - fields[i].lookupField(cl); - } - catch (NoSuchFieldException _) - { - fields[i].setToSet(false); - } - } - - calculateOffsets(); - return; - } - } - } - catch (NoSuchFieldException ignore) - { - } - catch (IllegalAccessException ignore) - { - } - - int num_good_fields = 0; - Field[] all_fields = cl.getDeclaredFields(); - - int modifiers; - // set non-serializable fields to null in all_fields - for (int i = 0; i < all_fields.length; i++) - { - modifiers = all_fields[i].getModifiers(); - if (Modifier.isTransient(modifiers) - || Modifier.isStatic(modifiers)) - all_fields[i] = null; - else - num_good_fields++; - } - - // make a copy of serializable (non-null) fields - fields = new ObjectStreamField[ num_good_fields ]; - for (int from = 0, to = 0; from < all_fields.length; from++) - if (all_fields[from] != null) - { - final Field f = all_fields[from]; - setAccessible.setMember(f); - AccessController.doPrivileged(setAccessible); - 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(); - } - - // Returns the serial version UID defined by class, or if that - // isn't present, calculates value of serial version UID. - private long getClassUID(Class cl) - { - 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. - final Field suid = cl.getDeclaredField("serialVersionUID"); - SetAccessibleAction setAccessible = new SetAccessibleAction(suid); - AccessController.doPrivileged(setAccessible); - int modifiers = suid.getModifiers(); - - 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; - try - { - md = MessageDigest.getInstance("SHA"); - } - catch (NoSuchAlgorithmException e) - { - // If a provider already provides SHA, use it; otherwise, use this. - Gnu gnuProvider = new Gnu(); - Security.addProvider(gnuProvider); - md = MessageDigest.getInstance("SHA"); - } - - DigestOutputStream digest_out = - new DigestOutputStream(nullOutputStream, md); - DataOutputStream data_out = new DataOutputStream(digest_out); - - data_out.writeUTF(cl.getName()); - - int modifiers = cl.getModifiers(); - // just look at interesting bits - modifiers = modifiers & (Modifier.ABSTRACT | Modifier.FINAL - | Modifier.INTERFACE | Modifier.PUBLIC); - data_out.writeInt(modifiers); - - // Pretend that an array has no interfaces, because when array - // serialization was defined (JDK 1.1), arrays didn't have it. - if (! cl.isArray()) - { - Class[] interfaces = cl.getInterfaces(); - Arrays.sort(interfaces, interfaceComparator); - for (int i = 0; i < interfaces.length; i++) - data_out.writeUTF(interfaces[i].getName()); - } - - Field field; - Field[] fields = cl.getDeclaredFields(); - Arrays.sort(fields, memberComparator); - for (int i = 0; i < fields.length; i++) - { - field = fields[i]; - modifiers = field.getModifiers(); - if (Modifier.isPrivate(modifiers) - && (Modifier.isStatic(modifiers) - || Modifier.isTransient(modifiers))) - continue; - - data_out.writeUTF(field.getName()); - data_out.writeInt(modifiers); - data_out.writeUTF(TypeSignature.getEncodingOfClass (field.getType())); - } - - // write class initializer method if present - if (VMObjectStreamClass.hasClassInitializer(cl)) - { - data_out.writeUTF("<clinit>"); - 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("<init>"); - 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; - } - } -} |