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

Print this page




  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.
  62  *


 251     private int passHandle = NULL_HANDLE;
 252     /** flag set when at end of field value block with no TC_ENDBLOCKDATA */
 253     private boolean defaultDataEnd = false;
 254 
 255     /** buffer for reading primitive field values */
 256     private byte[] primVals;
 257 
 258     /** if true, invoke readObjectOverride() instead of readObject() */
 259     private final boolean enableOverride;
 260     /** if true, invoke resolveObject() */
 261     private boolean enableResolve;
 262 
 263     /**
 264      * Context during upcalls to class-defined readObject methods; holds
 265      * object currently being deserialized and descriptor for current class.
 266      * Null when not during readObject upcall.
 267      */
 268     private SerialCallbackContext curContext;
 269 
 270     /**






 271      * Creates an ObjectInputStream that reads from the specified InputStream.
 272      * A serialization stream header is read from the stream and verified.
 273      * This constructor will block until the corresponding ObjectOutputStream
 274      * has written and flushed the header.
 275      *
 276      * <p>If a security manager is installed, this constructor will check for
 277      * the "enableSubclassImplementation" SerializablePermission when invoked
 278      * directly or indirectly by the constructor of a subclass which overrides
 279      * the ObjectInputStream.readFields or ObjectInputStream.readUnshared
 280      * methods.
 281      *
 282      * @param   in input stream to read from
 283      * @throws  StreamCorruptedException if the stream header is incorrect
 284      * @throws  IOException if an I/O error occurs while reading stream header
 285      * @throws  SecurityException if untrusted subclass illegally overrides
 286      *          security-sensitive methods
 287      * @throws  NullPointerException if <code>in</code> is <code>null</code>
 288      * @see     ObjectInputStream#ObjectInputStream()
 289      * @see     ObjectInputStream#readFields()
 290      * @see     ObjectOutputStream#ObjectOutputStream(OutputStream)


 356      * @throws  OptionalDataException Primitive data was found in the
 357      *          stream instead of objects.
 358      * @throws  IOException Any of the usual Input/Output related exceptions.
 359      */
 360     public final Object readObject()
 361         throws IOException, ClassNotFoundException
 362     {
 363         if (enableOverride) {
 364             return readObjectOverride();
 365         }
 366 
 367         // if nested read, passHandle contains handle of enclosing object
 368         int outerHandle = passHandle;
 369         try {
 370             Object obj = readObject0(false);
 371             handles.markDependency(outerHandle, passHandle);
 372             ClassNotFoundException ex = handles.lookupException(passHandle);
 373             if (ex != null) {
 374                 throw ex;
 375             }



 376             if (depth == 0) {
 377                 vlist.doCallbacks();
 378             }
 379             return obj;
 380         } finally {
 381             passHandle = outerHandle;
 382             if (closed && depth == 0) {
 383                 clear();
 384             }
 385         }
 386     }
 387 
 388     /**
 389      * This method is called by trusted subclasses of ObjectOutputStream that
 390      * constructed ObjectOutputStream using the protected no-arg constructor.
 391      * The subclass is expected to provide an override method with the modifier
 392      * "final".
 393      *
 394      * @return  the Object read from the stream.
 395      * @throws  ClassNotFoundException Class definition of a serialized object


 446      * @throws  ClassNotFoundException if class of an object to deserialize
 447      *          cannot be found
 448      * @throws  StreamCorruptedException if control information in the stream
 449      *          is inconsistent
 450      * @throws  ObjectStreamException if object to deserialize has already
 451      *          appeared in stream
 452      * @throws  OptionalDataException if primitive data is next in stream
 453      * @throws  IOException if an I/O error occurs during deserialization
 454      * @since   1.4
 455      */
 456     public Object readUnshared() throws IOException, ClassNotFoundException {
 457         // if nested read, passHandle contains handle of enclosing object
 458         int outerHandle = passHandle;
 459         try {
 460             Object obj = readObject0(true);
 461             handles.markDependency(outerHandle, passHandle);
 462             ClassNotFoundException ex = handles.lookupException(passHandle);
 463             if (ex != null) {
 464                 throw ex;
 465             }



 466             if (depth == 0) {
 467                 vlist.doCallbacks();
 468             }
 469             return obj;
 470         } finally {
 471             passHandle = outerHandle;
 472             if (closed && depth == 0) {
 473                 clear();
 474             }
 475         }
 476     }
 477 
 478     /**
 479      * Read the non-static and non-transient fields of the current class from
 480      * this stream.  This may only be called from the readObject method of the
 481      * class being deserialized. It will throw the NotActiveException if it is
 482      * called otherwise.
 483      *
 484      * @throws  ClassNotFoundException if the class of a serialized object
 485      *          could not be found.


1863          * consumed.  Since there's no "correct" action to take in this case,
1864          * we mimic the behavior of past serialization implementations and
1865          * blindly hope that the stream is in sync; if it isn't and additional
1866          * externalizable data remains in the stream, a subsequent read will
1867          * most likely throw a StreamCorruptedException.
1868          */
1869     }
1870 
1871     /**
1872      * Reads (or attempts to skip, if obj is null or is tagged with a
1873      * ClassNotFoundException) instance data for each serializable class of
1874      * object in stream, from superclass to subclass.  Expects that passHandle
1875      * is set to obj's handle before this method is called.
1876      */
1877     private void readSerialData(Object obj, ObjectStreamClass desc)
1878         throws IOException
1879     {
1880         ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout();
1881         for (int i = 0; i < slots.length; i++) {
1882             ObjectStreamClass slotDesc = slots[i].desc;



1883 
1884             if (slots[i].hasData) {
1885                 if (obj != null &&
1886                     slotDesc.hasReadObjectMethod() &&
1887                     handles.lookupException(passHandle) == null)
1888                 {
1889                     SerialCallbackContext oldContext = curContext;
1890 
1891                     try {
1892                         curContext = new SerialCallbackContext(obj, slotDesc);
1893 
1894                         bin.setBlockDataMode(true);
1895                         slotDesc.invokeReadObject(obj, this);
1896                     } catch (ClassNotFoundException ex) {
1897                         /*
1898                          * In most cases, the handle table has already
1899                          * propagated a CNFException to passHandle at this
1900                          * point; this mark call is included to address cases
1901                          * where the custom readObject method has cons'ed and
1902                          * thrown a new CNFException of its own.


2338         public long skip(long n) throws IOException {
2339             if (n <= 0) {
2340                 return 0;
2341             }
2342             int skipped = 0;
2343             if (peekb >= 0) {
2344                 peekb = -1;
2345                 skipped++;
2346                 n--;
2347             }
2348             return skipped + in.skip(n);
2349         }
2350 
2351         public int available() throws IOException {
2352             return in.available() + ((peekb >= 0) ? 1 : 0);
2353         }
2354 
2355         public void close() throws IOException {
2356             in.close();
2357         }









2358     }
2359 
2360     /**
2361      * Input stream with two modes: in default mode, inputs data written in the
2362      * same format as DataOutputStream; in "block data" mode, inputs data
2363      * bracketed by block data markers (see object serialization specification
2364      * for details).  Buffering depends on block data mode: when in default
2365      * mode, no data is buffered in advance; when in block data mode, all data
2366      * for the current data block is read in at once (and buffered).
2367      */
2368     private class BlockDataInputStream
2369         extends InputStream implements DataInput
2370     {
2371         /** maximum data block length */
2372         private static final int MAX_BLOCK_SIZE = 1024;
2373         /** maximum data block header length */
2374         private static final int MAX_HEADER_SIZE = 5;
2375         /** (tunable) length of char buffer (for reading strings) */
2376         private static final int CHAR_BUF_SIZE = 256;
2377         /** readBlockHeader() return value indicating header read may block */




  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.misc.Unsafe;
  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.
  63  *


 252     private int passHandle = NULL_HANDLE;
 253     /** flag set when at end of field value block with no TC_ENDBLOCKDATA */
 254     private boolean defaultDataEnd = false;
 255 
 256     /** buffer for reading primitive field values */
 257     private byte[] primVals;
 258 
 259     /** if true, invoke readObjectOverride() instead of readObject() */
 260     private final boolean enableOverride;
 261     /** if true, invoke resolveObject() */
 262     private boolean enableResolve;
 263 
 264     /**
 265      * Context during upcalls to class-defined readObject methods; holds
 266      * object currently being deserialized and descriptor for current class.
 267      * Null when not during readObject upcall.
 268      */
 269     private SerialCallbackContext curContext;
 270 
 271     /**
 272      * Tracks whether any object in the graph has a final field, and therefore
 273      * requires a freeze action before publishing.
 274      */
 275     private boolean requiresFreeze;
 276 
 277     /**
 278      * Creates an ObjectInputStream that reads from the specified InputStream.
 279      * A serialization stream header is read from the stream and verified.
 280      * This constructor will block until the corresponding ObjectOutputStream
 281      * has written and flushed the header.
 282      *
 283      * <p>If a security manager is installed, this constructor will check for
 284      * the "enableSubclassImplementation" SerializablePermission when invoked
 285      * directly or indirectly by the constructor of a subclass which overrides
 286      * the ObjectInputStream.readFields or ObjectInputStream.readUnshared
 287      * methods.
 288      *
 289      * @param   in input stream to read from
 290      * @throws  StreamCorruptedException if the stream header is incorrect
 291      * @throws  IOException if an I/O error occurs while reading stream header
 292      * @throws  SecurityException if untrusted subclass illegally overrides
 293      *          security-sensitive methods
 294      * @throws  NullPointerException if <code>in</code> is <code>null</code>
 295      * @see     ObjectInputStream#ObjectInputStream()
 296      * @see     ObjectInputStream#readFields()
 297      * @see     ObjectOutputStream#ObjectOutputStream(OutputStream)


 363      * @throws  OptionalDataException Primitive data was found in the
 364      *          stream instead of objects.
 365      * @throws  IOException Any of the usual Input/Output related exceptions.
 366      */
 367     public final Object readObject()
 368         throws IOException, ClassNotFoundException
 369     {
 370         if (enableOverride) {
 371             return readObjectOverride();
 372         }
 373 
 374         // if nested read, passHandle contains handle of enclosing object
 375         int outerHandle = passHandle;
 376         try {
 377             Object obj = readObject0(false);
 378             handles.markDependency(outerHandle, passHandle);
 379             ClassNotFoundException ex = handles.lookupException(passHandle);
 380             if (ex != null) {
 381                 throw ex;
 382             }
 383             if (requiresFreeze) {
 384                 freeze();
 385             }
 386             if (depth == 0) {
 387                 vlist.doCallbacks();
 388             }
 389             return obj;
 390         } finally {
 391             passHandle = outerHandle;
 392             if (closed && depth == 0) {
 393                 clear();
 394             }
 395         }
 396     }
 397 
 398     /**
 399      * This method is called by trusted subclasses of ObjectOutputStream that
 400      * constructed ObjectOutputStream using the protected no-arg constructor.
 401      * The subclass is expected to provide an override method with the modifier
 402      * "final".
 403      *
 404      * @return  the Object read from the stream.
 405      * @throws  ClassNotFoundException Class definition of a serialized object


 456      * @throws  ClassNotFoundException if class of an object to deserialize
 457      *          cannot be found
 458      * @throws  StreamCorruptedException if control information in the stream
 459      *          is inconsistent
 460      * @throws  ObjectStreamException if object to deserialize has already
 461      *          appeared in stream
 462      * @throws  OptionalDataException if primitive data is next in stream
 463      * @throws  IOException if an I/O error occurs during deserialization
 464      * @since   1.4
 465      */
 466     public Object readUnshared() throws IOException, ClassNotFoundException {
 467         // if nested read, passHandle contains handle of enclosing object
 468         int outerHandle = passHandle;
 469         try {
 470             Object obj = readObject0(true);
 471             handles.markDependency(outerHandle, passHandle);
 472             ClassNotFoundException ex = handles.lookupException(passHandle);
 473             if (ex != null) {
 474                 throw ex;
 475             }
 476             if (requiresFreeze) {
 477                 freeze();
 478             }
 479             if (depth == 0) {
 480                 vlist.doCallbacks();
 481             }
 482             return obj;
 483         } finally {
 484             passHandle = outerHandle;
 485             if (closed && depth == 0) {
 486                 clear();
 487             }
 488         }
 489     }
 490 
 491     /**
 492      * Read the non-static and non-transient fields of the current class from
 493      * this stream.  This may only be called from the readObject method of the
 494      * class being deserialized. It will throw the NotActiveException if it is
 495      * called otherwise.
 496      *
 497      * @throws  ClassNotFoundException if the class of a serialized object
 498      *          could not be found.


1876          * consumed.  Since there's no "correct" action to take in this case,
1877          * we mimic the behavior of past serialization implementations and
1878          * blindly hope that the stream is in sync; if it isn't and additional
1879          * externalizable data remains in the stream, a subsequent read will
1880          * most likely throw a StreamCorruptedException.
1881          */
1882     }
1883 
1884     /**
1885      * Reads (or attempts to skip, if obj is null or is tagged with a
1886      * ClassNotFoundException) instance data for each serializable class of
1887      * object in stream, from superclass to subclass.  Expects that passHandle
1888      * is set to obj's handle before this method is called.
1889      */
1890     private void readSerialData(Object obj, ObjectStreamClass desc)
1891         throws IOException
1892     {
1893         ObjectStreamClass.ClassDataSlot[] slots = desc.getClassDataLayout();
1894         for (int i = 0; i < slots.length; i++) {
1895             ObjectStreamClass slotDesc = slots[i].desc;
1896             if (!requiresFreeze && slotDesc.hasFinalField()) {
1897                 requiresFreeze = true;
1898             }
1899 
1900             if (slots[i].hasData) {
1901                 if (obj != null &&
1902                     slotDesc.hasReadObjectMethod() &&
1903                     handles.lookupException(passHandle) == null)
1904                 {
1905                     SerialCallbackContext oldContext = curContext;
1906 
1907                     try {
1908                         curContext = new SerialCallbackContext(obj, slotDesc);
1909 
1910                         bin.setBlockDataMode(true);
1911                         slotDesc.invokeReadObject(obj, this);
1912                     } catch (ClassNotFoundException ex) {
1913                         /*
1914                          * In most cases, the handle table has already
1915                          * propagated a CNFException to passHandle at this
1916                          * point; this mark call is included to address cases
1917                          * where the custom readObject method has cons'ed and
1918                          * thrown a new CNFException of its own.


2354         public long skip(long n) throws IOException {
2355             if (n <= 0) {
2356                 return 0;
2357             }
2358             int skipped = 0;
2359             if (peekb >= 0) {
2360                 peekb = -1;
2361                 skipped++;
2362                 n--;
2363             }
2364             return skipped + in.skip(n);
2365         }
2366 
2367         public int available() throws IOException {
2368             return in.available() + ((peekb >= 0) ? 1 : 0);
2369         }
2370 
2371         public void close() throws IOException {
2372             in.close();
2373         }
2374     }
2375 
2376     private static final Unsafe UNSAFE = Unsafe.getUnsafe();
2377 
2378     private void freeze() {
2379         // Issue a storestore|storeload fence, which is at least sufficient
2380         // to provide final-freeze semantics. 
2381         UNSAFE.storeFence();
2382         requiresFreeze = false;
2383     }
2384 
2385     /**
2386      * Input stream with two modes: in default mode, inputs data written in the
2387      * same format as DataOutputStream; in "block data" mode, inputs data
2388      * bracketed by block data markers (see object serialization specification
2389      * for details).  Buffering depends on block data mode: when in default
2390      * mode, no data is buffered in advance; when in block data mode, all data
2391      * for the current data block is read in at once (and buffered).
2392      */
2393     private class BlockDataInputStream
2394         extends InputStream implements DataInput
2395     {
2396         /** maximum data block length */
2397         private static final int MAX_BLOCK_SIZE = 1024;
2398         /** maximum data block header length */
2399         private static final int MAX_HEADER_SIZE = 5;
2400         /** (tunable) length of char buffer (for reading strings) */
2401         private static final int CHAR_BUF_SIZE = 256;
2402         /** readBlockHeader() return value indicating header read may block */