AbstractObjectInputStream.java revision 12745:f068a4ffddd2
1/* 2 * Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24/* 25 * 26 */ 27 28import java.io.*; 29import java.util.Vector; 30import java.util.Stack; 31import java.util.Hashtable; 32import java.lang.Math; 33import java.lang.reflect.InvocationTargetException; 34import java.lang.reflect.Method; 35import java.lang.reflect.Modifier; 36 37/** 38 * This abstract class enables one to subclass ObjectInputStream 39 * for the purpose of re-implementing serialization while preserving the 40 * existing public serialization API. A complimentary subclass of 41 * AbstractObjectInputStream must also be implemented.<p> 42 * 43 * Since serialization must override java access rules in order to 44 * access private, protected and package accessible Serializable fields, 45 * only trusted classes are allowed to subclass AbstractObjectInputStream. 46 * Subclasses of AbstractObjectInputStream must define SerializablePermission 47 * "enableAbstractSubclass" within a security policy file or this 48 * constructor will throw a SecurityException. Implementations of this 49 * class should protect themselves from being subclassed in a way that will 50 * provide access to object references and other sensitive info. 51 * Specifically, readObjectOverride() should be made final. 52 * <p> 53 * 54 * A subclass of AbstractObjectInputStream deserializes primitive data and 55 * objects previously written by a subclass of AbstractObjectOutputStream. 56 * The subclass ensures that the types of all objects in the graph created 57 * from the stream match the classes present in the Java Virtual Machine. 58 * Classes are loaded as required using the standard mechanisms. <p> 59 * 60 * Only objects that support the java.io.Serializable or 61 * java.io.Externalizable interface can be read from streams. 62 * 63 * The method <STRONG>readObjectOverride</STRONG> is used to read an object 64 * from the stream. Java's safe casting should be used to get the 65 * desired type. In Java, strings and arrays are objects and are 66 * treated as objects during serialization. When read with readObject() 67 * they need to be cast to the expected type.<p> 68 * 69 * Primitive data types can be read from the stream using the appropriate 70 * method on DataInput. <p> 71 * 72 * The default deserialization mechanism for objects restores the 73 * contents of each field to the value and type it had when it was written. 74 * References to other objects cause those 75 * objects to be read from the stream as necessary. Graphs of objects 76 * are restored correctly using a reference sharing mechanism. New 77 * objects are always allocated when deserializing, which prevents 78 * existing objects from being overwritten. <p> 79 * 80 * Reading an object is analogous to running the constructors of a new 81 * object. Memory is allocated for the object and initialized to zero 82 * (NULL). No-arg constructors are invoked for the first non-serializable 83 * super class and then the fields of the serializable classes are 84 * restored from the stream starting with the serializable class closest to 85 * java.lang.object and finishing with the object's most specifiec 86 * class. <p> 87 * 88 * Classes control how they are serialized by implementing either the 89 * java.io.Serializable or java.io.Externalizable interfaces.<P> 90 * 91 * Implementing the Serializable interface allows object serialization 92 * to save and restore the entire state of the object and it allows 93 * classes to evolve between the time the stream is written and the time it is 94 * read. It automatically traverses references between objects, 95 * saving and restoring entire graphs. 96 * 97 * Serializable classes that require special handling during the 98 * serialization and deserialization process should implement both 99 * of these methods:<p> 100 * 101 * <PRE> 102 * private void writeObject(java.io.ObjectOutputStream stream) 103 * throws IOException; 104 * private void readObject(java.io.ObjectInputStream stream) 105 * throws IOException, ClassNotFoundException; 106 * </PRE><p> 107 * 108 * The readObject method is responsible for reading and restoring the 109 * state of the object for its particular class using data written to 110 * the stream by the corresponding writeObject method. The method 111 * does not need to concern itself with the state belonging to its 112 * superclasses or subclasses. State is restored by reading data from 113 * the ObjectInputStream for the individual fields and making 114 * assignments to the appropriate fields of the object. Reading 115 * primitive data types is supported by DataInput. <p> 116 * 117 * Serialization does not read or assign values to the fields of any 118 * object that does not implement the java.io.Serializable interface. 119 * Subclasses of Objects that are not serializable can be 120 * serializable. In this case the non-serializable class must have an 121 * accessible no-arg constructor to allow its fields to be initialized. 122 * In this case it is the responsibility of the subclass to save and restore 123 * the state of the non-serializable class. It is frequently the case that 124 * the fields of that class are accessible (public, package, or 125 * protected) or that there are get and set methods that can be used 126 * to restore the state. <p> 127 * 128 * Implementing the Externalizable interface allows the object to 129 * assume complete control over the contents and format of the object's 130 * serialized form. The methods of the Externalizable interface, 131 * writeExternal and readExternal, are called to save and restore the 132 * objects state. When implemented by a class they can write and read 133 * their own state using all of the methods of ObjectOutput and 134 * ObjectInput. It is the responsibility of the objects to handle any 135 * versioning that occurs. 136 * 137 * @author Joe Fialli 138 * 139 * @see java.io.ObjectInputStream 140 * @see java.io.DataInput 141 * @see java.io.Serializable 142 * @see java.io.Externalizable 143 * @see java.io.ext.AbstractObjectOutputStream 144 * @since JDK1.2 145 */ 146public abstract class AbstractObjectInputStream extends ObjectInputStream 147{ 148 protected InputStream in; 149 /** 150 * Create an ObjectInputStream that reads from the specified InputStream.<p> 151 * 152 * Add the following line to the security policy file to enable 153 * subclassing. 154 * 155 * <PRE> 156 * permission SerializablePermission "enableAbstractSubclass" ; 157 * </PRE><p> 158 * 159 * @exception StreamCorruptedException The version or magic number are incorrect. 160 * @exception IOException An exception occurred in the underlying stream. 161 * @exception SecurityException if subclass does not have SerializablePermiision 162 * "enableAbstractSubclass". 163 */ 164 public AbstractObjectInputStream(InputStream in) 165 throws IOException, StreamCorruptedException 166 { 167 this.in = in; 168 } 169 170 public abstract void close() throws IOException; 171 172 /***************************************************************/ 173 /* Read an object from the stream. */ 174 175 /** 176 * Read an object from the ObjectInputStream.<p> 177 * 178 * NOTE: The override method of this class should have the modifier final.<p> 179 * 180 * Default deserializing for a class can be 181 * overriden by defining a readObject method for the Serializable class. 182 * Objects referenced by this object are read transitively so 183 * that a complete equivalent graph of objects is reconstructed by 184 * readObject. <p> 185 * 186 * The root object is completely restored when all of its fields 187 * and the objects it references are completely restored. At this 188 * point the object validation callbacks are executed in order 189 * based on their registered priorities. The callbacks are 190 * registered by objects (in the readObject special methods) 191 * as they are individually restored. <p> 192 * 193 * For security's sake, any overrides of this method should be final. 194 * Serialization typically needs to disable java access rules 195 * to serialize private, protected and package accessible Serializable 196 * fields. This method gets called for ALL Serializable objects. 197 * 198 * @exception java.lang.ClassNotFoundException Class of a serialized object 199 * cannot be found. 200 * @exception InvalidClassException Something is wrong with a class used by 201 * serialization. 202 * @exception StreamCorruptedException Control information in the 203 * stream is inconsistent. 204 * @exception OptionalDataException Primitive data was found in the 205 * stream instead of objects. 206 * @exception IOException Any of the usual Input/Output related exceptions. 207 * 208 * @see java.io.ObjectInputStream#resolveObject(Object) 209 * @see java.io.Resolvable 210 * @see java.io.Externalizable 211 * @see java.io.ObjectInputValidation 212 * @see #registerValidation(ObjectInputValidation, int) 213 * @see java.io.ObjectInputStream#resolveClass(ObjectStreamClass) 214 */ 215 protected Object readObjectOverride() 216 throws OptionalDataException, ClassNotFoundException, IOException { 217 return null; 218 } 219 220 /** 221 * Read the Serializable fields of the current object from this stream.<p> 222 * 223 * Note: The object being deserialized is not passed to this method. 224 * For security purposes, the initial implementation maintained 225 * the state of the last object to be read by readObject 226 * only allowed this method to be invoked for this object.<p> 227 * 228 * @exception NotActiveException Thrown if a readObject method is not 229 * active. 230 * @exception ClassNotFoundException if no corresponding local class can be 231 * found in the local JVM. 232 */ 233 public abstract void defaultReadObject() 234 throws IOException, ClassNotFoundException, NotActiveException; 235 236 /** 237 * Enable allocation for subclass reimplementing serialization.<p> 238 * 239 * Note: Default allocation does not have the java access priviledges 240 * to invoke package and protected constructors.<p> 241 * 242 * Security alert: this JVM native method is private within ObjectInputStream; however, 243 * it was anticipated that re-implementors of serialization would need 244 * access to this method. Is this allocator considered a security problem? <p> 245 * 246 * @param ctorClass is the same class or a superclass of <STRONG>ofClass</STRONG> 247 * @param ofClass the type of the object to allocate. 248 * @return an object of <STRONG>ofClass</STRONG> type. 249 * 250 * @exception IllegalAccessException if no-arg constructor of 251 * <STRONG>ctorClass</STRONG> is not accessible from 252 * <STRONG>ofClass</STRONG>. 253 * @exception InstantiationException TBD. 254 */ 255 protected final native Object 256 allocateNewObject(Class ofClass, Class ctorClass) 257 throws InstantiationException, IllegalAccessException; 258 259 /** 260 * Enable allocation for subclass reimplementing serialization.<p> 261 * 262 * Note: Default allocation does not have the java access priviledges 263 * to invoke package and protected constructors.<p> 264 * 265 * Security alert: this JVM native method is private within ObjectInputStream; however, 266 * it was anticipated that re-implementors of serialization would need 267 * access to this method. Is this allocator considered a security problem?<p> 268 * 269 * 270 * @exception IllegalAccessException TBD. 271 * @exception InstantiationException TBD. 272 */ 273 protected final native Object 274 allocateNewArray(Class componentClass, int length) 275 throws InstantiationException, IllegalAccessException; 276 277 /** 278 * Reads the Serializable fields from the stream into a buffer 279 * and makes the fields available by name. 280 * 281 * @exception java.lang.ClassNotFoundException if the class of a serialized 282 * object could not be found. 283 * @exception IOException if an I/O error occurs. 284 * @exception NotActiveException if readObject() is not currently active. 285 */ 286 public abstract ObjectInputStream.GetField readFields() 287 throws IOException, ClassNotFoundException, NotActiveException; 288 289 protected abstract boolean enableResolveObject(boolean enable) throws SecurityException; 290 291 public abstract void registerValidation(ObjectInputValidation obj, 292 int prio) 293 throws NotActiveException, InvalidObjectException; 294 295 296 /****************************************************************/ 297 298 /* Use DataInput methods to read primitive data from the stream. */ 299 300 public abstract int read() throws IOException; 301 public abstract int read(byte[] data, int offset, int length) 302 throws IOException; 303 public abstract boolean readBoolean() throws IOException; 304 public abstract byte readByte() throws IOException; 305 public abstract int readUnsignedByte() throws IOException; 306 public abstract short readShort() throws IOException; 307 public abstract int readUnsignedShort() throws IOException; 308 public abstract char readChar() throws IOException; 309 public abstract int readInt() throws IOException; 310 public abstract long readLong() throws IOException; 311 public abstract float readFloat() throws IOException; 312 public abstract double readDouble() throws IOException; 313 public abstract void readFully(byte[] data) throws IOException; 314 public abstract void readFully(byte[] data, int offset, int size) throws IOException; 315 public abstract String readUTF() throws IOException; 316 public abstract int available() throws IOException; 317 public abstract int skipBytes(int len) throws IOException; 318 319 /* @deprecated */ 320 public abstract String readLine() throws IOException; 321}; 322