new ObjectStreamField(field_name, class_name, callersClassLoader);
new ObjectStreamField(field_name, class_name);
  protected ObjectStreamClass readClassDescriptor()    throws ClassNotFoundException, IOException  {    if(dump) dumpElement("CLASSDESC NAME=");    String name = this.realInputStream.readUTF();    if(dump) dumpElement(name + "; UID=");    long uid = this.realInputStream.readLong ();    if(dump) dumpElement(Long.toHexString(uid) + "; FLAGS=");    byte flags = this.realInputStream.readByte ();    if(dump) dumpElement(Integer.toHexString(flags) + "; FIELD COUNT=");    short field_count = this.realInputStream.readShort();    if(dump) dumpElementln(Short.toString(field_count));    ObjectStreamField[] fields = new ObjectStreamField[field_count];    ObjectStreamClass osc = new ObjectStreamClass(name, uid,						  flags, fields);    assignNewHandle(osc);    ClassLoader callersClassLoader = currentLoader();	          for (int i = 0; i < field_count; i++)      {	if(dump) dumpElement("  TYPE CODE=");	char type_code = (char)this.realInputStream.readByte();	if(dump) dumpElement(type_code + "; FIELD NAME=");	String field_name = this.realInputStream.readUTF();	if(dump) dumpElementln(field_name);	String class_name;		  	// If the type code is an array or an object we must	// decode a String here. In the other case we convert	// the type code and pass it to ObjectStreamField.	// Type codes are decoded by gnu.java.lang.reflect.TypeSignature.	if (type_code == 'L' || type_code == '[')	  class_name = (String)readObject();	else	  class_name = String.valueOf(type_code);		  	fields[i] =	  new ObjectStreamField(field_name, class_name, callersClassLoader);      }	          /* Now that fields have been read we may resolve the class     * (and read annotation if needed). */    Class clazz = resolveClass(osc);    boolean oldmode = setBlockDataMode(true);    osc.setClass(clazz, lookupClass(clazz.getSuperclass()));    classLookupTable.put(clazz, osc);    setBlockDataMode(oldmode);    // find the first non-serializable, non-abstract    // class in clazz's inheritance hierarchy    Class first_nonserial = clazz.getSuperclass();    // Maybe it is a primitive class, those don't have a super class,    // or Object itself.  Otherwise we can keep getting the superclass    // till we hit the Object class, or some other non-serializable class.    if (first_nonserial == null)      first_nonserial = clazz;    else      while (Serializable.class.isAssignableFrom(first_nonserial)	     || Modifier.isAbstract(first_nonserial.getModifiers()))	first_nonserial = first_nonserial.getSuperclass();    final Class local_constructor_class = first_nonserial;    osc.firstNonSerializableParentConstructor =        (Constructor)AccessController.doPrivileged(new PrivilegedAction()          {            public Object run()            {              try                {                  Constructor c = local_constructor_class.                                    getDeclaredConstructor(new Class[0]);                  if (Modifier.isPrivate(c.getModifiers()))                    return null;                  return c;                }              catch (NoSuchMethodException e)                {                  // error will be reported later, in newObject()                  return null;                }            }          });    osc.realClassIsSerializable = Serializable.class.isAssignableFrom(clazz);    osc.realClassIsExternalizable = Externalizable.class.isAssignableFrom(clazz);    ObjectStreamField[] stream_fields = osc.fields;    ObjectStreamField[] real_fields = ObjectStreamClass.lookupForClassObject(clazz).fields;    ObjectStreamField[] fieldmapping = new ObjectStreamField[2 * Math.max(stream_fields.length, real_fields.length)];    int stream_idx = 0;    int real_idx = 0;    int map_idx = 0;    /*     * Check that there is no type inconsistencies between the lists.     * A special checking must be done for the two groups: primitive types and     * not primitive types.      */    checkTypeConsistency(name, real_fields, stream_fields);    checkTypeConsistency(name, stream_fields, real_fields);        while (stream_idx < stream_fields.length	   || real_idx < real_fields.length)      {	ObjectStreamField stream_field = null;	ObjectStreamField real_field = null;	if (stream_idx == stream_fields.length)	  {	    real_field = real_fields[real_idx++];	  }	else if (real_idx == real_fields.length)	  {	    stream_field = stream_fields[stream_idx++];	  }	else	  {	    int comp_val =	      real_fields[real_idx].compareTo (stream_fields[stream_idx]);	    if (comp_val < 0)	      {		real_field = real_fields[real_idx++];	      }	    else if (comp_val > 0)	      {		stream_field = stream_fields[stream_idx++];	      }	    else	      {		stream_field = stream_fields[stream_idx++];		real_field = real_fields[real_idx++];		if (stream_field.getType() != real_field.getType())		  throw new InvalidClassException		    ("invalid field type for " + real_field.getName() +		     " in class " + name);	      }	  }	/* If some of stream_fields does not correspond to any of real_fields,	 * or the opposite, then fieldmapping will go short.	 */	if (map_idx == fieldmapping.length)	  {	    ObjectStreamField[] newfieldmapping =	      new ObjectStreamField[fieldmapping.length + 2];	    System.arraycopy(fieldmapping, 0,			     newfieldmapping, 0, fieldmapping.length);	    fieldmapping = newfieldmapping;	  }	fieldmapping[map_idx++] = stream_field;	fieldmapping[map_idx++] = real_field;      }    osc.fieldMapping = fieldmapping;    return osc;  }