src/share/classes/java/io/ObjectInputStream.java

Print this page




  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.io;
  27 
  28 import java.io.ObjectStreamClass.WeakClassKey;
  29 import java.lang.ref.ReferenceQueue;
  30 import java.lang.reflect.Array;
  31 import java.lang.reflect.Modifier;
  32 import java.lang.reflect.Proxy;
  33 import java.security.AccessControlContext;
  34 import java.security.AccessController;
  35 import java.security.PrivilegedAction;
  36 import java.security.PrivilegedActionException;
  37 import java.security.PrivilegedExceptionAction;
  38 import java.util.Arrays;
  39 import java.util.HashMap;
  40 import java.util.concurrent.ConcurrentHashMap;
  41 import java.util.concurrent.ConcurrentMap;
  42 import java.util.concurrent.atomic.AtomicBoolean;
  43 import static java.io.ObjectStreamClass.processQueue;
  44 import sun.reflect.misc.ReflectUtil;
  45 
  46 /**
  47  * An ObjectInputStream deserializes primitive data and objects previously
  48  * written using an ObjectOutputStream.
  49  *
  50  * <p>ObjectOutputStream and ObjectInputStream can provide an application with
  51  * persistent storage for graphs of objects when used with a FileOutputStream
  52  * and FileInputStream respectively.  ObjectInputStream is used to recover
  53  * those objects previously serialized. Other uses include passing objects
  54  * between hosts using a socket stream or for marshaling and unmarshaling
  55  * arguments and parameters in a remote communication system.
  56  *
  57  * <p>ObjectInputStream ensures that the types of all objects in the graph
  58  * created from the stream match the classes present in the Java Virtual
  59  * Machine.  Classes are loaded as required using the standard mechanisms.
  60  *
  61  * <p>Only objects that support the java.io.Serializable or
  62  * java.io.Externalizable interface can be read from streams.


 517     /**
 518      * Reads the persistent fields from the stream and makes them available by
 519      * name.
 520      *
 521      * @return  the <code>GetField</code> object representing the persistent
 522      *          fields of the object being deserialized
 523      * @throws  ClassNotFoundException if the class of a serialized object
 524      *          could not be found.
 525      * @throws  IOException if an I/O error occurs.
 526      * @throws  NotActiveException if the stream is not currently reading
 527      *          objects.
 528      * @since 1.2
 529      */
 530     public ObjectInputStream.GetField readFields()
 531         throws IOException, ClassNotFoundException
 532     {
 533         SerialCallbackContext ctx = curContext;
 534         if (ctx == null) {
 535             throw new NotActiveException("not in call to readObject");
 536         }
 537         Object curObj = ctx.getObj();
 538         ObjectStreamClass curDesc = ctx.getDesc();
 539         bin.setBlockDataMode(false);
 540         GetFieldImpl getField = new GetFieldImpl(curDesc);
 541         getField.readFields();
 542         bin.setBlockDataMode(true);
 543         if (!curDesc.hasWriteObjectData()) {
 544             /*
 545              * Fix for 4360508: since stream does not contain terminating
 546              * TC_ENDBLOCKDATA tag, set flag so that reading code elsewhere
 547              * knows to simulate end-of-custom-data behavior.
 548              */
 549             defaultDataEnd = true;
 550         }
 551 
 552         return getField;
 553     }
 554 
 555     /**
 556      * Register an object to be validated before the graph is returned.  While
 557      * similar to resolveObject these validations are called after the entire


1580         return desc;
1581     }
1582 
1583     /**
1584      * Reads in and returns class descriptor for a class that is not a dynamic
1585      * proxy class.  Sets passHandle to class descriptor's assigned handle.  If
1586      * class descriptor cannot be resolved to a class in the local VM, a
1587      * ClassNotFoundException is associated with the descriptor's handle.
1588      */
1589     private ObjectStreamClass readNonProxyDesc(boolean unshared)
1590         throws IOException
1591     {
1592         if (bin.readByte() != TC_CLASSDESC) {
1593             throw new InternalError();
1594         }
1595 
1596         ObjectStreamClass desc = new ObjectStreamClass();
1597         int descHandle = handles.assign(unshared ? unsharedMarker : desc);
1598         passHandle = NULL_HANDLE;
1599 
1600         ObjectStreamClass readDesc = null;
1601         try {
1602             readDesc = readClassDescriptor();
1603         } catch (ClassNotFoundException ex) {
1604             throw (IOException) new InvalidClassException(
1605                 "failed to read class descriptor").initCause(ex);
1606         }
1607 
1608         Class<?> cl = null;
1609         ClassNotFoundException resolveEx = null;
1610         bin.setBlockDataMode(true);
1611         final boolean checksRequired = isCustomSubclass();
1612         try {
1613             if ((cl = resolveClass(readDesc)) == null) {
1614                 resolveEx = new ClassNotFoundException("null class");
1615             } else if (checksRequired) {
1616                 ReflectUtil.checkPackageAccess(cl);
1617             }
1618         } catch (ClassNotFoundException ex) {
1619             resolveEx = ex;
1620         }


1959                     readObject0(false);
1960                     break;
1961             }
1962         }
1963     }
1964 
1965     /**
1966      * Reads in values of serializable fields declared by given class
1967      * descriptor.  If obj is non-null, sets field values in obj.  Expects that
1968      * passHandle is set to obj's handle before this method is called.
1969      */
1970     private void defaultReadFields(Object obj, ObjectStreamClass desc)
1971         throws IOException
1972     {
1973         Class<?> cl = desc.forClass();
1974         if (cl != null && obj != null && !cl.isInstance(obj)) {
1975             throw new ClassCastException();
1976         }
1977 
1978         int primDataSize = desc.getPrimDataSize();

1979         if (primVals == null || primVals.length < primDataSize) {
1980             primVals = new byte[primDataSize];
1981         }
1982         bin.readFully(primVals, 0, primDataSize, false);
1983         if (obj != null) {
1984             desc.setPrimFieldValues(obj, primVals);
1985         }

1986 


1987         int objHandle = passHandle;
1988         ObjectStreamField[] fields = desc.getFields(false);
1989         Object[] objVals = new Object[desc.getNumObjFields()];
1990         int numPrimFields = fields.length - objVals.length;
1991         for (int i = 0; i < objVals.length; i++) {
1992             ObjectStreamField f = fields[numPrimFields + i];
1993             objVals[i] = readObject0(f.isUnshared());
1994             if (f.getField() != null) {
1995                 handles.markDependency(objHandle, passHandle);
1996             }
1997         }
1998         if (obj != null) {
1999             desc.setObjFieldValues(obj, objVals);
2000         }
2001         passHandle = objHandle;

2002     }
2003 
2004     /**
2005      * Reads in and returns IOException that caused serialization to abort.
2006      * All stream state is discarded prior to reading in fatal exception.  Sets
2007      * passHandle to fatal exception's handle.
2008      */
2009     private IOException readFatalException() throws IOException {
2010         if (bin.readByte() != TC_EXCEPTION) {
2011             throw new InternalError();
2012         }
2013         clear();
2014         return (IOException) readObject0(false);
2015     }
2016 
2017     /**
2018      * If recursion depth is 0, clears internal data structures; otherwise,
2019      * throws a StreamCorruptedException.  This method is called when a
2020      * TC_RESET typecode is encountered.
2021      */




  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.io;
  27 
  28 import java.io.ObjectStreamClass.WeakClassKey;
  29 import java.lang.ref.ReferenceQueue;
  30 import java.lang.reflect.Array;
  31 import java.lang.reflect.Modifier;
  32 import java.lang.reflect.Proxy;
  33 import java.security.AccessControlContext;
  34 import java.security.AccessController;
  35 import java.security.PrivilegedAction;
  36 import java.security.PrivilegedActionException;
  37 import java.security.PrivilegedExceptionAction;
  38 import java.util.Arrays;
  39 import java.util.HashMap;
  40 import java.util.concurrent.ConcurrentHashMap;
  41 import java.util.concurrent.ConcurrentMap;

  42 import static java.io.ObjectStreamClass.processQueue;
  43 import sun.reflect.misc.ReflectUtil;
  44 
  45 /**
  46  * An ObjectInputStream deserializes primitive data and objects previously
  47  * written using an ObjectOutputStream.
  48  *
  49  * <p>ObjectOutputStream and ObjectInputStream can provide an application with
  50  * persistent storage for graphs of objects when used with a FileOutputStream
  51  * and FileInputStream respectively.  ObjectInputStream is used to recover
  52  * those objects previously serialized. Other uses include passing objects
  53  * between hosts using a socket stream or for marshaling and unmarshaling
  54  * arguments and parameters in a remote communication system.
  55  *
  56  * <p>ObjectInputStream ensures that the types of all objects in the graph
  57  * created from the stream match the classes present in the Java Virtual
  58  * Machine.  Classes are loaded as required using the standard mechanisms.
  59  *
  60  * <p>Only objects that support the java.io.Serializable or
  61  * java.io.Externalizable interface can be read from streams.


 516     /**
 517      * Reads the persistent fields from the stream and makes them available by
 518      * name.
 519      *
 520      * @return  the <code>GetField</code> object representing the persistent
 521      *          fields of the object being deserialized
 522      * @throws  ClassNotFoundException if the class of a serialized object
 523      *          could not be found.
 524      * @throws  IOException if an I/O error occurs.
 525      * @throws  NotActiveException if the stream is not currently reading
 526      *          objects.
 527      * @since 1.2
 528      */
 529     public ObjectInputStream.GetField readFields()
 530         throws IOException, ClassNotFoundException
 531     {
 532         SerialCallbackContext ctx = curContext;
 533         if (ctx == null) {
 534             throw new NotActiveException("not in call to readObject");
 535         }
 536         ctx.checkAndSetUsed();
 537         ObjectStreamClass curDesc = ctx.getDesc();
 538         bin.setBlockDataMode(false);
 539         GetFieldImpl getField = new GetFieldImpl(curDesc);
 540         getField.readFields();
 541         bin.setBlockDataMode(true);
 542         if (!curDesc.hasWriteObjectData()) {
 543             /*
 544              * Fix for 4360508: since stream does not contain terminating
 545              * TC_ENDBLOCKDATA tag, set flag so that reading code elsewhere
 546              * knows to simulate end-of-custom-data behavior.
 547              */
 548             defaultDataEnd = true;
 549         }
 550 
 551         return getField;
 552     }
 553 
 554     /**
 555      * Register an object to be validated before the graph is returned.  While
 556      * similar to resolveObject these validations are called after the entire


1579         return desc;
1580     }
1581 
1582     /**
1583      * Reads in and returns class descriptor for a class that is not a dynamic
1584      * proxy class.  Sets passHandle to class descriptor's assigned handle.  If
1585      * class descriptor cannot be resolved to a class in the local VM, a
1586      * ClassNotFoundException is associated with the descriptor's handle.
1587      */
1588     private ObjectStreamClass readNonProxyDesc(boolean unshared)
1589         throws IOException
1590     {
1591         if (bin.readByte() != TC_CLASSDESC) {
1592             throw new InternalError();
1593         }
1594 
1595         ObjectStreamClass desc = new ObjectStreamClass();
1596         int descHandle = handles.assign(unshared ? unsharedMarker : desc);
1597         passHandle = NULL_HANDLE;
1598 
1599         ObjectStreamClass readDesc;
1600         try {
1601             readDesc = readClassDescriptor();
1602         } catch (ClassNotFoundException ex) {
1603             throw (IOException) new InvalidClassException(
1604                 "failed to read class descriptor").initCause(ex);
1605         }
1606 
1607         Class<?> cl = null;
1608         ClassNotFoundException resolveEx = null;
1609         bin.setBlockDataMode(true);
1610         final boolean checksRequired = isCustomSubclass();
1611         try {
1612             if ((cl = resolveClass(readDesc)) == null) {
1613                 resolveEx = new ClassNotFoundException("null class");
1614             } else if (checksRequired) {
1615                 ReflectUtil.checkPackageAccess(cl);
1616             }
1617         } catch (ClassNotFoundException ex) {
1618             resolveEx = ex;
1619         }


1958                     readObject0(false);
1959                     break;
1960             }
1961         }
1962     }
1963 
1964     /**
1965      * Reads in values of serializable fields declared by given class
1966      * descriptor.  If obj is non-null, sets field values in obj.  Expects that
1967      * passHandle is set to obj's handle before this method is called.
1968      */
1969     private void defaultReadFields(Object obj, ObjectStreamClass desc)
1970         throws IOException
1971     {
1972         Class<?> cl = desc.forClass();
1973         if (cl != null && obj != null && !cl.isInstance(obj)) {
1974             throw new ClassCastException();
1975         }
1976 
1977         int primDataSize = desc.getPrimDataSize();
1978         if (primDataSize > 0) {
1979             if (primVals == null || primVals.length < primDataSize) {
1980                 primVals = new byte[primDataSize];
1981             }
1982             bin.readFully(primVals, 0, primDataSize, false);
1983             if (obj != null) {
1984                 desc.setPrimFieldValues(obj, primVals);
1985             }
1986         }
1987 
1988         int numObjFields = desc.getNumObjFields();
1989         if (numObjFields > 0) {
1990             int objHandle = passHandle;
1991             ObjectStreamField[] fields = desc.getFields(false);
1992             Object[] objVals = new Object[numObjFields];
1993             int numPrimFields = fields.length - objVals.length;
1994             for (int i = 0; i < objVals.length; i++) {
1995                 ObjectStreamField f = fields[numPrimFields + i];
1996                 objVals[i] = readObject0(f.isUnshared());
1997                 if (f.getField() != null) {
1998                     handles.markDependency(objHandle, passHandle);
1999                 }
2000             }
2001             if (obj != null) {
2002                 desc.setObjFieldValues(obj, objVals);
2003             }
2004             passHandle = objHandle;
2005         }
2006     }
2007 
2008     /**
2009      * Reads in and returns IOException that caused serialization to abort.
2010      * All stream state is discarded prior to reading in fatal exception.  Sets
2011      * passHandle to fatal exception's handle.
2012      */
2013     private IOException readFatalException() throws IOException {
2014         if (bin.readByte() != TC_EXCEPTION) {
2015             throw new InternalError();
2016         }
2017         clear();
2018         return (IOException) readObject0(false);
2019     }
2020 
2021     /**
2022      * If recursion depth is 0, clears internal data structures; otherwise,
2023      * throws a StreamCorruptedException.  This method is called when a
2024      * TC_RESET typecode is encountered.
2025      */