KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > io > ObjectInputStream


1 /*
2  * @(#)ObjectInputStream.java 1.157 06/04/05
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.io;
9
10 import java.io.ObjectStreamClass.WeakClassKey JavaDoc;
11 import java.lang.ref.ReferenceQueue JavaDoc;
12 import java.lang.reflect.Array JavaDoc;
13 import java.lang.reflect.Modifier JavaDoc;
14 import java.lang.reflect.Proxy JavaDoc;
15 import java.security.AccessController JavaDoc;
16 import java.security.PrivilegedAction JavaDoc;
17 import java.util.Arrays JavaDoc;
18 import java.util.HashMap JavaDoc;
19 import java.util.concurrent.ConcurrentHashMap JavaDoc;
20 import java.util.concurrent.ConcurrentMap JavaDoc;
21 import java.util.concurrent.atomic.AtomicBoolean JavaDoc;
22 import static java.io.ObjectStreamClass.processQueue JavaDoc;
23
24 /**
25  * An ObjectInputStream deserializes primitive data and objects previously
26  * written using an ObjectOutputStream.
27  *
28  * <p>ObjectOutputStream and ObjectInputStream can provide an application with
29  * persistent storage for graphs of objects when used with a FileOutputStream
30  * and FileInputStream respectively. ObjectInputStream is used to recover
31  * those objects previously serialized. Other uses include passing objects
32  * between hosts using a socket stream or for marshaling and unmarshaling
33  * arguments and parameters in a remote communication system.
34  *
35  * <p>ObjectInputStream ensures that the types of all objects in the graph
36  * created from the stream match the classes present in the Java Virtual
37  * Machine. Classes are loaded as required using the standard mechanisms.
38  *
39  * <p>Only objects that support the java.io.Serializable or
40  * java.io.Externalizable interface can be read from streams.
41  *
42  * <p>The method <code>readObject</code> is used to read an object from the
43  * stream. Java's safe casting should be used to get the desired type. In
44  * Java, strings and arrays are objects and are treated as objects during
45  * serialization. When read they need to be cast to the expected type.
46  *
47  * <p>Primitive data types can be read from the stream using the appropriate
48  * method on DataInput.
49  *
50  * <p>The default deserialization mechanism for objects restores the contents
51  * of each field to the value and type it had when it was written. Fields
52  * declared as transient or static are ignored by the deserialization process.
53  * References to other objects cause those objects to be read from the stream
54  * as necessary. Graphs of objects are restored correctly using a reference
55  * sharing mechanism. New objects are always allocated when deserializing,
56  * which prevents existing objects from being overwritten.
57  *
58  * <p>Reading an object is analogous to running the constructors of a new
59  * object. Memory is allocated for the object and initialized to zero (NULL).
60  * No-arg constructors are invoked for the non-serializable classes and then
61  * the fields of the serializable classes are restored from the stream starting
62  * with the serializable class closest to java.lang.object and finishing with
63  * the object's most specific class.
64  *
65  * <p>For example to read from a stream as written by the example in
66  * ObjectOutputStream:
67  * <br>
68  * <pre>
69  * FileInputStream fis = new FileInputStream("t.tmp");
70  * ObjectInputStream ois = new ObjectInputStream(fis);
71  *
72  * int i = ois.readInt();
73  * String today = (String) ois.readObject();
74  * Date date = (Date) ois.readObject();
75  *
76  * ois.close();
77  * </pre>
78  *
79  * <p>Classes control how they are serialized by implementing either the
80  * java.io.Serializable or java.io.Externalizable interfaces.
81  *
82  * <p>Implementing the Serializable interface allows object serialization to
83  * save and restore the entire state of the object and it allows classes to
84  * evolve between the time the stream is written and the time it is read. It
85  * automatically traverses references between objects, saving and restoring
86  * entire graphs.
87  *
88  * <p>Serializable classes that require special handling during the
89  * serialization and deserialization process should implement the following
90  * methods:<p>
91  *
92  * <pre>
93  * private void writeObject(java.io.ObjectOutputStream stream)
94  * throws IOException;
95  * private void readObject(java.io.ObjectInputStream stream)
96  * throws IOException, ClassNotFoundException;
97  * private void readObjectNoData()
98  * throws ObjectStreamException;
99  * </pre>
100  *
101  * <p>The readObject method is responsible for reading and restoring the state
102  * of the object for its particular class using data written to the stream by
103  * the corresponding writeObject method. The method does not need to concern
104  * itself with the state belonging to its superclasses or subclasses. State is
105  * restored by reading data from the ObjectInputStream for the individual
106  * fields and making assignments to the appropriate fields of the object.
107  * Reading primitive data types is supported by DataInput.
108  *
109  * <p>Any attempt to read object data which exceeds the boundaries of the
110  * custom data written by the corresponding writeObject method will cause an
111  * OptionalDataException to be thrown with an eof field value of true.
112  * Non-object reads which exceed the end of the allotted data will reflect the
113  * end of data in the same way that they would indicate the end of the stream:
114  * bytewise reads will return -1 as the byte read or number of bytes read, and
115  * primitive reads will throw EOFExceptions. If there is no corresponding
116  * writeObject method, then the end of default serialized data marks the end of
117  * the allotted data.
118  *
119  * <p>Primitive and object read calls issued from within a readExternal method
120  * behave in the same manner--if the stream is already positioned at the end of
121  * data written by the corresponding writeExternal method, object reads will
122  * throw OptionalDataExceptions with eof set to true, bytewise reads will
123  * return -1, and primitive reads will throw EOFExceptions. Note that this
124  * behavior does not hold for streams written with the old
125  * <code>ObjectStreamConstants.PROTOCOL_VERSION_1</code> protocol, in which the
126  * end of data written by writeExternal methods is not demarcated, and hence
127  * cannot be detected.
128  *
129  * <p>The readObjectNoData method is responsible for initializing the state of
130  * the object for its particular class in the event that the serialization
131  * stream does not list the given class as a superclass of the object being
132  * deserialized. This may occur in cases where the receiving party uses a
133  * different version of the deserialized instance's class than the sending
134  * party, and the receiver's version extends classes that are not extended by
135  * the sender's version. This may also occur if the serialization stream has
136  * been tampered; hence, readObjectNoData is useful for initializing
137  * deserialized objects properly despite a "hostile" or incomplete source
138  * stream.
139  *
140  * <p>Serialization does not read or assign values to the fields of any object
141  * that does not implement the java.io.Serializable interface. Subclasses of
142  * Objects that are not serializable can be serializable. In this case the
143  * non-serializable class must have a no-arg constructor to allow its fields to
144  * be initialized. In this case it is the responsibility of the subclass to
145  * save and restore the state of the non-serializable class. It is frequently
146  * the case that the fields of that class are accessible (public, package, or
147  * protected) or that there are get and set methods that can be used to restore
148  * the state.
149  *
150  * <p>Any exception that occurs while deserializing an object will be caught by
151  * the ObjectInputStream and abort the reading process.
152  *
153  * <p>Implementing the Externalizable interface allows the object to assume
154  * complete control over the contents and format of the object's serialized
155  * form. The methods of the Externalizable interface, writeExternal and
156  * readExternal, are called to save and restore the objects state. When
157  * implemented by a class they can write and read their own state using all of
158  * the methods of ObjectOutput and ObjectInput. It is the responsibility of
159  * the objects to handle any versioning that occurs.
160  *
161  * <p>Enum constants are deserialized differently than ordinary serializable or
162  * externalizable objects. The serialized form of an enum constant consists
163  * solely of its name; field values of the constant are not transmitted. To
164  * deserialize an enum constant, ObjectInputStream reads the constant name from
165  * the stream; the deserialized constant is then obtained by calling the static
166  * method <code>Enum.valueOf(Class, String)</code> with the enum constant's
167  * base type and the received constant name as arguments. Like other
168  * serializable or externalizable objects, enum constants can function as the
169  * targets of back references appearing subsequently in the serialization
170  * stream. The process by which enum constants are deserialized cannot be
171  * customized: any class-specific readObject, readObjectNoData, and readResolve
172  * methods defined by enum types are ignored during deserialization.
173  * Similarly, any serialPersistentFields or serialVersionUID field declarations
174  * are also ignored--all enum types have a fixed serialVersionUID of 0L.
175  *
176  * @author Mike Warres
177  * @author Roger Riggs
178  * @version 1.157, 06/04/05
179  * @see java.io.DataInput
180  * @see java.io.ObjectOutputStream
181  * @see java.io.Serializable
182  * @see <a HREF="../../../guide/serialization/spec/input.doc.html"> Object Serialization Specification, Section 3, Object Input Classes</a>
183  * @since JDK1.1
184  */

185 public class ObjectInputStream
186     extends InputStream JavaDoc implements ObjectInput JavaDoc, ObjectStreamConstants JavaDoc
187 {
188     /** handle value representing null */
189     private static final int NULL_HANDLE = -1;
190     
191     /** marker for unshared objects in internal handle table */
192     private static final Object JavaDoc unsharedMarker = new Object JavaDoc();
193     
194     /** table mapping primitive type names to corresponding class objects */
195     private static final HashMap JavaDoc primClasses = new HashMap JavaDoc(8, 1.0F);
196     static {
197     primClasses.put("boolean", boolean.class);
198     primClasses.put("byte", byte.class);
199     primClasses.put("char", char.class);
200     primClasses.put("short", short.class);
201     primClasses.put("int", int.class);
202     primClasses.put("long", long.class);
203     primClasses.put("float", float.class);
204     primClasses.put("double", double.class);
205     primClasses.put("void", void.class);
206     }
207
208     private static class Caches {
209     /** cache of subclass security audit results */
210     static final ConcurrentMap JavaDoc<WeakClassKey,Boolean JavaDoc> subclassAudits =
211         new ConcurrentHashMap JavaDoc<WeakClassKey,Boolean JavaDoc>();
212
213     /** queue for WeakReferences to audited subclasses */
214     static final ReferenceQueue JavaDoc<Class JavaDoc<?>> subclassAuditsQueue =
215         new ReferenceQueue JavaDoc<Class JavaDoc<?>>();
216     }
217
218     /** filter stream for handling block data conversion */
219     private final BlockDataInputStream bin;
220     /** validation callback list */
221     private final ValidationList vlist;
222     /** recursion depth */
223     private int depth;
224     /** whether stream is closed */
225     private boolean closed;
226     
227     /** wire handle -> obj/exception map */
228     private final HandleTable handles;
229     /** scratch field for passing handle values up/down call stack */
230     private int passHandle = NULL_HANDLE;
231     /** flag set when at end of field value block with no TC_ENDBLOCKDATA */
232     private boolean defaultDataEnd = false;
233
234     /** buffer for reading primitive field values */
235     private byte[] primVals;
236     
237     /** if true, invoke readObjectOverride() instead of readObject() */
238     private final boolean enableOverride;
239     /** if true, invoke resolveObject() */
240     private boolean enableResolve;
241     
242     /**
243      * Context during upcalls to class-defined readObject methods; holds
244      * object currently being deserialized and descriptor for current class.
245      * Null when not during readObject upcall.
246      */

247     private CallbackContext curContext;
248
249     /**
250      * Creates an ObjectInputStream that reads from the specified InputStream.
251      * A serialization stream header is read from the stream and verified.
252      * This constructor will block until the corresponding ObjectOutputStream
253      * has written and flushed the header.
254      *
255      * <p>If a security manager is installed, this constructor will check for
256      * the "enableSubclassImplementation" SerializablePermission when invoked
257      * directly or indirectly by the constructor of a subclass which overrides
258      * the ObjectInputStream.readFields or ObjectInputStream.readUnshared
259      * methods.
260      *
261      * @param in input stream to read from
262      * @throws StreamCorruptedException if the stream header is incorrect
263      * @throws IOException if an I/O error occurs while reading stream header
264      * @throws SecurityException if untrusted subclass illegally overrides
265      * security-sensitive methods
266      * @throws NullPointerException if <code>in</code> is <code>null</code>
267      * @see ObjectInputStream#ObjectInputStream()
268      * @see ObjectInputStream#readFields()
269      * @see ObjectOutputStream#ObjectOutputStream(OutputStream)
270      */

271     public ObjectInputStream(InputStream JavaDoc in) throws IOException JavaDoc {
272     verifySubclass();
273     bin = new BlockDataInputStream(in);
274     handles = new HandleTable(10);
275     vlist = new ValidationList();
276     enableOverride = false;
277     readStreamHeader();
278     bin.setBlockDataMode(true);
279     }
280
281     /**
282      * Provide a way for subclasses that are completely reimplementing
283      * ObjectInputStream to not have to allocate private data just used by this
284      * implementation of ObjectInputStream.
285      *
286      * <p>If there is a security manager installed, this method first calls the
287      * security manager's <code>checkPermission</code> method with the
288      * <code>SerializablePermission("enableSubclassImplementation")</code>
289      * permission to ensure it's ok to enable subclassing.
290      *
291      * @throws SecurityException if a security manager exists and its
292      * <code>checkPermission</code> method denies enabling
293      * subclassing.
294      * @see SecurityManager#checkPermission
295      * @see java.io.SerializablePermission
296      */

297     protected ObjectInputStream() throws IOException JavaDoc, SecurityException JavaDoc {
298     SecurityManager JavaDoc sm = System.getSecurityManager();
299     if (sm != null) {
300         sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
301     }
302     bin = null;
303     handles = null;
304     vlist = null;
305     enableOverride = true;
306     }
307
308     /**
309      * Read an object from the ObjectInputStream. The class of the object, the
310      * signature of the class, and the values of the non-transient and
311      * non-static fields of the class and all of its supertypes are read.
312      * Default deserializing for a class can be overriden using the writeObject
313      * and readObject methods. Objects referenced by this object are read
314      * transitively so that a complete equivalent graph of objects is
315      * reconstructed by readObject.
316      *
317      * <p>The root object is completely restored when all of its fields and the
318      * objects it references are completely restored. At this point the object
319      * validation callbacks are executed in order based on their registered
320      * priorities. The callbacks are registered by objects (in the readObject
321      * special methods) as they are individually restored.
322      *
323      * <p>Exceptions are thrown for problems with the InputStream and for
324      * classes that should not be deserialized. All exceptions are fatal to
325      * the InputStream and leave it in an indeterminate state; it is up to the
326      * caller to ignore or recover the stream state.
327      *
328      * @throws ClassNotFoundException Class of a serialized object cannot be
329      * found.
330      * @throws InvalidClassException Something is wrong with a class used by
331      * serialization.
332      * @throws StreamCorruptedException Control information in the
333      * stream is inconsistent.
334      * @throws OptionalDataException Primitive data was found in the
335      * stream instead of objects.
336      * @throws IOException Any of the usual Input/Output related exceptions.
337      */

338     public final Object JavaDoc readObject()
339     throws IOException JavaDoc, ClassNotFoundException JavaDoc
340     {
341     if (enableOverride) {
342         return readObjectOverride();
343     }
344
345     // if nested read, passHandle contains handle of enclosing object
346
int outerHandle = passHandle;
347     try {
348         Object JavaDoc obj = readObject0(false);
349         handles.markDependency(outerHandle, passHandle);
350         ClassNotFoundException JavaDoc ex = handles.lookupException(passHandle);
351         if (ex != null) {
352         throw ex;
353         }
354         if (depth == 0) {
355         vlist.doCallbacks();
356         }
357         return obj;
358     } finally {
359         passHandle = outerHandle;
360         if (closed && depth == 0) {
361         clear();
362         }
363     }
364     }
365
366     /**
367      * This method is called by trusted subclasses of ObjectOutputStream that
368      * constructed ObjectOutputStream using the protected no-arg constructor.
369      * The subclass is expected to provide an override method with the modifier
370      * "final".
371      *
372      * @return the Object read from the stream.
373      * @throws ClassNotFoundException Class definition of a serialized object
374      * cannot be found.
375      * @throws OptionalDataException Primitive data was found in the stream
376      * instead of objects.
377      * @throws IOException if I/O errors occurred while reading from the
378      * underlying stream
379      * @see #ObjectInputStream()
380      * @see #readObject()
381      * @since 1.2
382      */

383     protected Object JavaDoc readObjectOverride()
384     throws IOException JavaDoc, ClassNotFoundException JavaDoc
385     {
386     return null;
387     }
388  
389     /**
390      * Reads an "unshared" object from the ObjectInputStream. This method is
391      * identical to readObject, except that it prevents subsequent calls to
392      * readObject and readUnshared from returning additional references to the
393      * deserialized instance obtained via this call. Specifically:
394      * <ul>
395      * <li>If readUnshared is called to deserialize a back-reference (the
396      * stream representation of an object which has been written
397      * previously to the stream), an ObjectStreamException will be
398      * thrown.
399      *
400      * <li>If readUnshared returns successfully, then any subsequent attempts
401      * to deserialize back-references to the stream handle deserialized
402      * by readUnshared will cause an ObjectStreamException to be thrown.
403      * </ul>
404      * Deserializing an object via readUnshared invalidates the stream handle
405      * associated with the returned object. Note that this in itself does not
406      * always guarantee that the reference returned by readUnshared is unique;
407      * the deserialized object may define a readResolve method which returns an
408      * object visible to other parties, or readUnshared may return a Class
409      * object or enum constant obtainable elsewhere in the stream or through
410      * external means.
411      *
412      * <p>However, for objects which are not enum constants or instances of
413      * java.lang.Class and do not define readResolve methods, readUnshared
414      * guarantees that the returned object reference is unique and cannot be
415      * obtained a second time from the ObjectInputStream that created it, even
416      * if the underlying data stream has been manipulated. This guarantee
417      * applies only to the base-level object returned by readUnshared, and not
418      * to any transitively referenced sub-objects in the returned object graph.
419      *
420      * <p>ObjectInputStream subclasses which override this method can only be
421      * constructed in security contexts possessing the
422      * "enableSubclassImplementation" SerializablePermission; any attempt to
423      * instantiate such a subclass without this permission will cause a
424      * SecurityException to be thrown.
425      *
426      * @return reference to deserialized object
427      * @throws ClassNotFoundException if class of an object to deserialize
428      * cannot be found
429      * @throws StreamCorruptedException if control information in the stream
430      * is inconsistent
431      * @throws ObjectStreamException if object to deserialize has already
432      * appeared in stream
433      * @throws OptionalDataException if primitive data is next in stream
434      * @throws IOException if an I/O error occurs during deserialization
435      */

436     public Object JavaDoc readUnshared() throws IOException JavaDoc, ClassNotFoundException JavaDoc {
437     // if nested read, passHandle contains handle of enclosing object
438
int outerHandle = passHandle;
439     try {
440         Object JavaDoc obj = readObject0(true);
441         handles.markDependency(outerHandle, passHandle);
442         ClassNotFoundException JavaDoc ex = handles.lookupException(passHandle);
443         if (ex != null) {
444         throw ex;
445         }
446         if (depth == 0) {
447         vlist.doCallbacks();
448         }
449         return obj;
450     } finally {
451         passHandle = outerHandle;
452         if (closed && depth == 0) {
453         clear();
454         }
455     }
456     }
457
458     /**
459      * Read the non-static and non-transient fields of the current class from
460      * this stream. This may only be called from the readObject method of the
461      * class being deserialized. It will throw the NotActiveException if it is
462      * called otherwise.
463      *
464      * @throws ClassNotFoundException if the class of a serialized object
465      * could not be found.
466      * @throws IOException if an I/O error occurs.
467      * @throws NotActiveException if the stream is not currently reading
468      * objects.
469      */

470     public void defaultReadObject()
471     throws IOException JavaDoc, ClassNotFoundException JavaDoc
472     {
473     if (curContext == null) {
474         throw new NotActiveException JavaDoc("not in call to readObject");
475     }
476     Object JavaDoc curObj = curContext.getObj();
477     ObjectStreamClass JavaDoc curDesc = curContext.getDesc();
478     bin.setBlockDataMode(false);
479     defaultReadFields(curObj, curDesc);
480     bin.setBlockDataMode(true);
481     if (!curDesc.hasWriteObjectData()) {
482         /*
483          * Fix for 4360508: since stream does not contain terminating
484          * TC_ENDBLOCKDATA tag, set flag so that reading code elsewhere
485          * knows to simulate end-of-custom-data behavior.
486          */

487         defaultDataEnd = true;
488     }
489     ClassNotFoundException JavaDoc ex = handles.lookupException(passHandle);
490     if (ex != null) {
491         throw ex;
492     }
493     }
494     
495     /**
496      * Reads the persistent fields from the stream and makes them available by
497      * name.
498      *
499      * @return the <code>GetField</code> object representing the persistent
500      * fields of the object being deserialized
501      * @throws ClassNotFoundException if the class of a serialized object
502      * could not be found.
503      * @throws IOException if an I/O error occurs.
504      * @throws NotActiveException if the stream is not currently reading
505      * objects.
506      * @since 1.2
507      */

508     public ObjectInputStream.GetField JavaDoc readFields()
509         throws IOException JavaDoc, ClassNotFoundException JavaDoc
510     {
511     if (curContext == null) {
512         throw new NotActiveException JavaDoc("not in call to readObject");
513     }
514     Object JavaDoc curObj = curContext.getObj();
515     ObjectStreamClass JavaDoc curDesc = curContext.getDesc();
516     bin.setBlockDataMode(false);
517     GetFieldImpl getField = new GetFieldImpl(curDesc);
518     getField.readFields();
519     bin.setBlockDataMode(true);
520     if (!curDesc.hasWriteObjectData()) {
521         /*
522          * Fix for 4360508: since stream does not contain terminating
523          * TC_ENDBLOCKDATA tag, set flag so that reading code elsewhere
524          * knows to simulate end-of-custom-data behavior.
525          */

526         defaultDataEnd = true;
527     }
528
529     return getField;
530     }
531
532     /**
533      * Register an object to be validated before the graph is returned. While
534      * similar to resolveObject these validations are called after the entire
535      * graph has been reconstituted. Typically, a readObject method will
536      * register the object with the stream so that when all of the objects are
537      * restored a final set of validations can be performed.
538      *
539      * @param obj the object to receive the validation callback.
540      * @param prio controls the order of callbacks;zero is a good default.
541      * Use higher numbers to be called back earlier, lower numbers for
542      * later callbacks. Within a priority, callbacks are processed in
543      * no particular order.
544      * @throws NotActiveException The stream is not currently reading objects
545      * so it is invalid to register a callback.
546      * @throws InvalidObjectException The validation object is null.
547      */

548     public void registerValidation(ObjectInputValidation JavaDoc obj, int prio)
549     throws NotActiveException JavaDoc, InvalidObjectException JavaDoc
550     {
551     if (depth == 0) {
552         throw new NotActiveException JavaDoc("stream inactive");
553     }
554     vlist.register(obj, prio);
555     }
556
557     /**
558      * Load the local class equivalent of the specified stream class
559      * description. Subclasses may implement this method to allow classes to
560      * be fetched from an alternate source.
561      *
562      * <p>The corresponding method in <code>ObjectOutputStream</code> is
563      * <code>annotateClass</code>. This method will be invoked only once for
564      * each unique class in the stream. This method can be implemented by
565      * subclasses to use an alternate loading mechanism but must return a
566      * <code>Class</code> object. Once returned, the serialVersionUID of the
567      * class is compared to the serialVersionUID of the serialized class. If
568      * there is a mismatch, the deserialization fails and an exception is
569      * raised.
570      *
571      * <p>By default the class name is resolved relative to the class that
572      * called <code>readObject</code>.
573      *
574      * @param desc an instance of class <code>ObjectStreamClass</code>
575      * @return a <code>Class</code> object corresponding to <code>desc</code>
576      * @throws IOException any of the usual input/output exceptions
577      * @throws ClassNotFoundException if class of a serialized object cannot
578      * be found
579      */

580     protected Class JavaDoc<?> resolveClass(ObjectStreamClass JavaDoc desc)
581     throws IOException JavaDoc, ClassNotFoundException JavaDoc
582     {
583     String JavaDoc name = desc.getName();
584     try {
585         return Class.forName(name, false, latestUserDefinedLoader());
586     } catch (ClassNotFoundException JavaDoc ex) {
587         Class JavaDoc cl = (Class JavaDoc) primClasses.get(name);
588         if (cl != null) {
589         return cl;
590         } else {
591         throw ex;
592         }
593     }
594     }
595
596     /**
597      * Returns a proxy class that implements the interfaces named in a proxy
598      * class descriptor; subclasses may implement this method to read custom
599      * data from the stream along with the descriptors for dynamic proxy
600      * classes, allowing them to use an alternate loading mechanism for the
601      * interfaces and the proxy class.
602      *
603      * <p>This method is called exactly once for each unique proxy class
604      * descriptor in the stream.
605      *
606      * <p>The corresponding method in <code>ObjectOutputStream</code> is
607      * <code>annotateProxyClass</code>. For a given subclass of
608      * <code>ObjectInputStream</code> that overrides this method, the
609      * <code>annotateProxyClass</code> method in the corresponding subclass of
610      * <code>ObjectOutputStream</code> must write any data or objects read by
611      * this method.
612      *
613      * <p>The default implementation of this method in
614      * <code>ObjectInputStream</code> returns the result of calling
615      * <code>Proxy.getProxyClass</code> with the list of <code>Class</code>
616      * objects for the interfaces that are named in the <code>interfaces</code>
617      * parameter. The <code>Class</code> object for each interface name
618      * <code>i</code> is the value returned by calling
619      * <pre>
620      * Class.forName(i, false, loader)
621      * </pre>
622      * where <code>loader</code> is that of the first non-<code>null</code>
623      * class loader up the execution stack, or <code>null</code> if no
624      * non-<code>null</code> class loaders are on the stack (the same class
625      * loader choice used by the <code>resolveClass</code> method). Unless any
626      * of the resolved interfaces are non-public, this same value of
627      * <code>loader</code> is also the class loader passed to
628      * <code>Proxy.getProxyClass</code>; if non-public interfaces are present,
629      * their class loader is passed instead (if more than one non-public
630      * interface class loader is encountered, an
631      * <code>IllegalAccessError</code> is thrown).
632      * If <code>Proxy.getProxyClass</code> throws an
633      * <code>IllegalArgumentException</code>, <code>resolveProxyClass</code>
634      * will throw a <code>ClassNotFoundException</code> containing the
635      * <code>IllegalArgumentException</code>.
636      *
637      * @param interfaces the list of interface names that were
638      * deserialized in the proxy class descriptor
639      * @return a proxy class for the specified interfaces
640      * @throws IOException any exception thrown by the underlying
641      * <code>InputStream</code>
642      * @throws ClassNotFoundException if the proxy class or any of the
643      * named interfaces could not be found
644      * @see ObjectOutputStream#annotateProxyClass(Class)
645      * @since 1.3
646      */

647     protected Class JavaDoc<?> resolveProxyClass(String JavaDoc[] interfaces)
648     throws IOException JavaDoc, ClassNotFoundException JavaDoc
649     {
650     ClassLoader JavaDoc latestLoader = latestUserDefinedLoader();
651     ClassLoader JavaDoc nonPublicLoader = null;
652     boolean hasNonPublicInterface = false;
653
654     // define proxy in class loader of non-public interface(s), if any
655
Class JavaDoc[] classObjs = new Class JavaDoc[interfaces.length];
656     for (int i = 0; i < interfaces.length; i++) {
657         Class JavaDoc cl = Class.forName(interfaces[i], false, latestLoader);
658         if ((cl.getModifiers() & Modifier.PUBLIC) == 0) {
659         if (hasNonPublicInterface) {
660             if (nonPublicLoader != cl.getClassLoader()) {
661             throw new IllegalAccessError JavaDoc(
662                 "conflicting non-public interface class loaders");
663             }
664         } else {
665             nonPublicLoader = cl.getClassLoader();
666             hasNonPublicInterface = true;
667         }
668         }
669         classObjs[i] = cl;
670     }
671     try {
672         return Proxy.getProxyClass(
673         hasNonPublicInterface ? nonPublicLoader : latestLoader,
674         classObjs);
675     } catch (IllegalArgumentException JavaDoc e) {
676         throw new ClassNotFoundException JavaDoc(null, e);
677     }
678     }
679
680     /**
681      * This method will allow trusted subclasses of ObjectInputStream to
682      * substitute one object for another during deserialization. Replacing
683      * objects is disabled until enableResolveObject is called. The
684      * enableResolveObject method checks that the stream requesting to resolve
685      * object can be trusted. Every reference to serializable objects is passed
686      * to resolveObject. To insure that the private state of objects is not
687      * unintentionally exposed only trusted streams may use resolveObject.
688      *
689      * <p>This method is called after an object has been read but before it is
690      * returned from readObject. The default resolveObject method just returns
691      * the same object.
692      *
693      * <p>When a subclass is replacing objects it must insure that the
694      * substituted object is compatible with every field where the reference
695      * will be stored. Objects whose type is not a subclass of the type of the
696      * field or array element abort the serialization by raising an exception
697      * and the object is not be stored.
698      *
699      * <p>This method is called only once when each object is first
700      * encountered. All subsequent references to the object will be redirected
701      * to the new object.
702      *
703      * @param obj object to be substituted
704      * @return the substituted object
705      * @throws IOException Any of the usual Input/Output exceptions.
706      */

707     protected Object JavaDoc resolveObject(Object JavaDoc obj) throws IOException JavaDoc {
708     return obj;
709     }
710
711     /**
712      * Enable the stream to allow objects read from the stream to be replaced.
713      * When enabled, the resolveObject method is called for every object being
714      * deserialized.
715      *
716      * <p>If <i>enable</i> is true, and there is a security manager installed,
717      * this method first calls the security manager's
718      * <code>checkPermission</code> method with the
719      * <code>SerializablePermission("enableSubstitution")</code> permission to
720      * ensure it's ok to enable the stream to allow objects read from the
721      * stream to be replaced.
722      *
723      * @param enable true for enabling use of <code>resolveObject</code> for
724      * every object being deserialized
725      * @return the previous setting before this method was invoked
726      * @throws SecurityException if a security manager exists and its
727      * <code>checkPermission</code> method denies enabling the stream
728      * to allow objects read from the stream to be replaced.
729      * @see SecurityManager#checkPermission
730      * @see java.io.SerializablePermission
731      */

732     protected boolean enableResolveObject(boolean enable)
733     throws SecurityException JavaDoc
734     {
735     if (enable == enableResolve) {
736         return enable;
737     }
738     if (enable) {
739         SecurityManager JavaDoc sm = System.getSecurityManager();
740         if (sm != null) {
741         sm.checkPermission(SUBSTITUTION_PERMISSION);
742         }
743     }
744     enableResolve = enable;
745     return !enableResolve;
746     }
747
748     /**
749      * The readStreamHeader method is provided to allow subclasses to read and
750      * verify their own stream headers. It reads and verifies the magic number
751      * and version number.
752      *
753      * @throws IOException if there are I/O errors while reading from the
754      * underlying <code>InputStream</code>
755      * @throws StreamCorruptedException if control information in the stream
756      * is inconsistent
757      */

758     protected void readStreamHeader()
759     throws IOException JavaDoc, StreamCorruptedException JavaDoc
760     {
761     if (bin.readShort() != STREAM_MAGIC ||
762         bin.readShort() != STREAM_VERSION)
763     {
764         throw new StreamCorruptedException JavaDoc("invalid stream header");
765     }
766     }
767
768     /**
769      * Read a class descriptor from the serialization stream. This method is
770      * called when the ObjectInputStream expects a class descriptor as the next
771      * item in the serialization stream. Subclasses of ObjectInputStream may
772      * override this method to read in class descriptors that have been written
773      * in non-standard formats (by subclasses of ObjectOutputStream which have
774      * overridden the <code>writeClassDescriptor</code> method). By default,
775      * this method reads class descriptors according to the format defined in
776      * the Object Serialization specification.
777      *
778      * @return the class descriptor read
779      * @throws IOException If an I/O error has occurred.
780      * @throws ClassNotFoundException If the Class of a serialized object used
781      * in the class descriptor representation cannot be found
782      * @see java.io.ObjectOutputStream#writeClassDescriptor(java.io.ObjectStreamClass)
783      * @since 1.3
784      */

785     protected ObjectStreamClass JavaDoc readClassDescriptor()
786     throws IOException JavaDoc, ClassNotFoundException JavaDoc
787     {
788     ObjectStreamClass JavaDoc desc = new ObjectStreamClass JavaDoc();
789     desc.readNonProxy(this);
790     return desc;
791     }
792
793     /**
794      * Reads a byte of data. This method will block if no input is available.
795      *
796      * @return the byte read, or -1 if the end of the stream is reached.
797      * @throws IOException If an I/O error has occurred.
798      */

799     public int read() throws IOException JavaDoc {
800     return bin.read();
801     }
802     
803     /**
804      * Reads into an array of bytes. This method will block until some input
805      * is available. Consider using java.io.DataInputStream.readFully to read
806      * exactly 'length' bytes.
807      *
808      * @param buf the buffer into which the data is read
809      * @param off the start offset of the data
810      * @param len the maximum number of bytes read
811      * @return the actual number of bytes read, -1 is returned when the end of
812      * the stream is reached.
813      * @throws IOException If an I/O error has occurred.
814      * @see java.io.DataInputStream#readFully(byte[],int,int)
815      */

816     public int read(byte[] buf, int off, int len) throws IOException JavaDoc {
817     if (buf == null) {
818         throw new NullPointerException JavaDoc();
819     }
820     int endoff = off + len;
821     if (off < 0 || len < 0 || endoff > buf.length || endoff < 0) {
822         throw new IndexOutOfBoundsException JavaDoc();
823     }
824     return bin.read(buf, off, len, false);
825     }
826
827     /**
828      * Returns the number of bytes that can be read without blocking.
829      *
830      * @return the number of available bytes.
831      * @throws IOException if there are I/O errors while reading from the
832      * underlying <code>InputStream</code>
833      */

834     public int available() throws IOException JavaDoc {
835     return bin.available();
836     }
837
838     /**
839      * Closes the input stream. Must be called to release any resources
840      * associated with the stream.
841      *
842      * @throws IOException If an I/O error has occurred.
843      */

844     public void close() throws IOException JavaDoc {
845     /*
846      * Even if stream already closed, propagate redundant close to
847      * underlying stream to stay consistent with previous implementations.
848      */

849     closed = true;
850     if (depth == 0) {
851         clear();
852     }
853     bin.close();
854     }
855
856     /**
857      * Reads in a boolean.
858      *
859      * @return the boolean read.
860      * @throws EOFException If end of file is reached.
861      * @throws IOException If other I/O error has occurred.
862      */

863     public boolean readBoolean() throws IOException JavaDoc {
864     return bin.readBoolean();
865     }
866
867     /**
868      * Reads an 8 bit byte.
869      *
870      * @return the 8 bit byte read.
871      * @throws EOFException If end of file is reached.
872      * @throws IOException If other I/O error has occurred.
873      */

874     public byte readByte() throws IOException JavaDoc {
875     return bin.readByte();
876     }
877
878     /**
879      * Reads an unsigned 8 bit byte.
880      *
881      * @return the 8 bit byte read.
882      * @throws EOFException If end of file is reached.
883      * @throws IOException If other I/O error has occurred.
884      */

885     public int readUnsignedByte() throws IOException JavaDoc {
886     return bin.readUnsignedByte();
887     }
888
889     /**
890      * Reads a 16 bit char.
891      *
892      * @return the 16 bit char read.
893      * @throws EOFException If end of file is reached.
894      * @throws IOException If other I/O error has occurred.
895      */

896     public char readChar() throws IOException JavaDoc {
897     return bin.readChar();
898     }
899
900     /**
901      * Reads a 16 bit short.
902      *
903      * @return the 16 bit short read.
904      * @throws EOFException If end of file is reached.
905      * @throws IOException If other I/O error has occurred.
906      */

907     public short readShort() throws IOException JavaDoc {
908     return bin.readShort();
909     }
910
911     /**
912      * Reads an unsigned 16 bit short.
913      *
914      * @return the 16 bit short read.
915      * @throws EOFException If end of file is reached.
916      * @throws IOException If other I/O error has occurred.
917      */

918     public int readUnsignedShort() throws IOException JavaDoc {
919     return bin.readUnsignedShort();
920     }
921
922     /**
923      * Reads a 32 bit int.
924      *
925      * @return the 32 bit integer read.
926      * @throws EOFException If end of file is reached.
927      * @throws IOException If other I/O error has occurred.
928      */

929     public int readInt() throws IOException JavaDoc {
930     return bin.readInt();
931     }
932
933     /**
934