1 /* 2 * Javassist, a Java-bytecode translator toolkit. 3 * Copyright (C) 1999-2010 Shigeru Chiba. All Rights Reserved. 4 * 5 * The contents of this file are subject to the Mozilla Public License Version 6 * 1.1 (the "License"); you may not use this file except in compliance with 7 * the License. Alternatively, the contents of this file may be used under 8 * the terms of the GNU Lesser General Public License Version 2.1 or later. 9 * 10 * Software distributed under the License is distributed on an "AS IS" basis, 11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 12 * for the specific language governing rights and limitations under the 13 * License. 14 */ 15 16 package javassist.util.proxy; 17 18 import java.io.IOException; 19 import java.io.InputStream; 20 import java.io.ObjectInputStream; 21 import java.io.ObjectStreamClass; 22 23 /** 24 * An input stream class which knows how to deserialize proxies created via {@link ProxyFactory} and 25 * serializedo via a {@link ProxyObjectOutputStream}. It must be used when deserialising proxies created 26 * from a proxy factory configured with {@link ProxyFactory#useWriteReplace} set to false. 27 * 28 * @author Andrew Dinn 29 */ 30 public class ProxyObjectInputStream extends ObjectInputStream 31 { 32 /** 33 * create an input stream which can be used to deserialize an object graph which includes proxies created 34 * using class ProxyFactory. the classloader used to resolve proxy superclass and interface names 35 * read from the input stream will default to the current thread's context class loader or the system 36 * classloader if the context class loader is null. 37 * @param in 38 * @throws java.io.StreamCorruptedException whenever ObjectInputStream would also do so 39 * @throws IOException whenever ObjectInputStream would also do so 40 * @throws SecurityException whenever ObjectInputStream would also do so 41 * @throws NullPointerException if in is null 42 */ ProxyObjectInputStream(InputStream in)43 public ProxyObjectInputStream(InputStream in) throws IOException 44 { 45 super(in); 46 loader = Thread.currentThread().getContextClassLoader(); 47 if (loader == null) { 48 loader = ClassLoader.getSystemClassLoader(); 49 } 50 } 51 52 /** 53 * Reset the loader to be 54 * @param loader 55 */ setClassLoader(ClassLoader loader)56 public void setClassLoader(ClassLoader loader) 57 { 58 if (loader != null) { 59 this.loader = loader; 60 } else { 61 loader = ClassLoader.getSystemClassLoader(); 62 } 63 } 64 readClassDescriptor()65 protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException { 66 boolean isProxy = readBoolean(); 67 if (isProxy) { 68 String name = (String)readObject(); 69 Class superClass = loader.loadClass(name); 70 int length = readInt(); 71 Class[] interfaces = new Class[length]; 72 for (int i = 0; i < length; i++) { 73 name = (String)readObject(); 74 interfaces[i] = loader.loadClass(name); 75 } 76 length = readInt(); 77 byte[] signature = new byte[length]; 78 read(signature); 79 ProxyFactory factory = new ProxyFactory(); 80 // we must always use the cache and never use writeReplace when using 81 // ProxyObjectOutputStream and ProxyObjectInputStream 82 factory.setUseCache(true); 83 factory.setUseWriteReplace(false); 84 factory.setSuperclass(superClass); 85 factory.setInterfaces(interfaces); 86 Class proxyClass = factory.createClass(signature); 87 return ObjectStreamClass.lookup(proxyClass); 88 } else { 89 return super.readClassDescriptor(); 90 } 91 } 92 93 /** 94 * the loader to use to resolve classes for proxy superclass and interface names read 95 * from the stream. defaults to the context class loader of the thread which creates 96 * the input stream or the system class loader if the context class loader is null. 97 */ 98 private ClassLoader loader; 99 }