This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

FYI: More serialization merges


Hi,

Unfortunately some serialization classes are still not fully merge. But
ObjectStreamClass is now, so the special override can be removed. And I
ported two patches from classpath to ObjectInputStream to at least fix
the Mauve failures for Proxy and readResolve we were seeing after the
0.19 merge.

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.

There is more merging to do here, but I committed these already.

Cheers,

Mark
Index: Makefile.in
===================================================================
--- Makefile.in	(revision 107084)
+++ Makefile.in	(working copy)
@@ -2612,7 +2612,7 @@
 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 \
Index: sources.am
===================================================================
--- sources.am	(revision 107084)
+++ sources.am	(working copy)
@@ -2748,7 +2748,7 @@
 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 \
Index: java/io/ObjectInputStream.java
===================================================================
--- java/io/ObjectInputStream.java	(revision 107084)
+++ java/io/ObjectInputStream.java	(working copy)
@@ -113,7 +113,10 @@
    * <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 @@
 	      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 @@
 	      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 @@
 	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;
 	  }
       }
 
Index: java/io/ObjectStreamClass.java
===================================================================
--- java/io/ObjectStreamClass.java	(revision 107084)
+++ java/io/ObjectStreamClass.java	(working copy)
@@ -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;
-    }
-  }
-}

Attachment: signature.asc
Description: This is a digitally signed message part


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]