• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }