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