KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > remoting > loading > ObjectInputStreamWithClassLoader


1 /***************************************
2  * *
3  * JBoss: The OpenSource J2EE WebOS *
4  * *
5  * Distributable under LGPL license. *
6  * See terms of license at gnu.org. *
7  * *
8  ***************************************/

9 package org.jboss.remoting.loading;
10
11 import java.io.IOException JavaDoc;
12 import java.io.ObjectInputStream JavaDoc;
13 import java.io.StreamCorruptedException JavaDoc;
14
15
16 /**
17  * ObjectInputStreamWithClassLoader
18  *
19  * @author <a HREF="mailto:jhaynie@vocalocity.net">Jeff Haynie</a>
20  * @author <a HREF="mailto:tom@jboss.org">Tom Elrod</a>
21  * @version $Revision: 1.1.1.1 $
22  */

23 public class ObjectInputStreamWithClassLoader extends ObjectInputStream JavaDoc
24 {
25    private ClassLoader JavaDoc cl;
26
27    /**
28     * Create an ObjectInputStream that reads from the specified InputStream.
29     * The stream header containing the magic number and version number
30     * are read from the stream and verified. This method will block
31     * until the corresponding ObjectOutputStream has written and flushed the
32     * header.
33     *
34     * @param in the underlying <code>InputStream</code> from which to read
35     * @throws java.io.StreamCorruptedException
36     * The version or magic number are
37     * incorrect.
38     * @throws java.io.IOException An exception occurred in the underlying stream.
39     */

40    public ObjectInputStreamWithClassLoader(java.io.InputStream JavaDoc in, ClassLoader JavaDoc cl)
41          throws IOException JavaDoc, StreamCorruptedException JavaDoc
42    {
43       super(in);
44       this.cl = cl;
45    }
46
47    /**
48     * Set the classloader that the stream will used when deserializing class. This will
49     * allow plugging in of classloaders based on invocation context.
50     *
51     * @param cl
52     */

53    public void setClassLoader(ClassLoader JavaDoc cl)
54    {
55       this.cl = cl;
56    }
57
58    /**
59     * Gets the pluggable classloader that will be used for classloading when deserializing
60     * objects.
61     *
62     * @return
63     */

64    public ClassLoader JavaDoc getClassLoader()
65    {
66       return cl;
67    }
68
69    /**
70     * Load the local class equivalent of the specified stream class description.
71     * <p/>
72     * Subclasses may implement this method to allow classes to be
73     * fetched from an alternate source.
74     * <p/>
75     * The corresponding method in ObjectOutputStream is
76     * annotateClass. This method will be invoked only once for each
77     * unique class in the stream. This method can be implemented by
78     * subclasses to use an alternate loading mechanism but must
79     * return a Class object. Once returned, the serialVersionUID of the
80     * class is compared to the serialVersionUID of the serialized class.
81     * If there is a mismatch, the deserialization fails and an exception
82     * is raised. <p>
83     * <p/>
84     * By default the class name is resolved relative to the class
85     * that called readObject. <p>
86     * <p/>
87     * Will use the classloader explicitly set if it exists. If it does not exist,
88     * will used its default classloader (that loader this instance).<p>
89     *
90     * @param v an instance of class ObjectStreamClass
91     * @return a Class object corresponding to <code>v</code>
92     * @throws java.io.IOException Any of the usual Input/Output exceptions.
93     * @throws java.lang.ClassNotFoundException
94     * If class of
95     * a serialized object cannot be found.
96     */

97    protected Class JavaDoc resolveClass(java.io.ObjectStreamClass JavaDoc v)
98          throws java.io.IOException JavaDoc, ClassNotFoundException JavaDoc
99    {
100       if(cl == null)
101       {
102          return super.resolveClass(v);
103       }
104       else
105       {
106          return cl.loadClass(v.getName());
107       }
108    }
109
110    /**
111     * Returns a proxy class that implements the interfaces named in a
112     * proxy class descriptor; subclasses may implement this method to
113     * read custom data from the stream along with the descriptors for
114     * dynamic proxy classes, allowing them to use an alternate loading
115     * mechanism for the interfaces and the proxy class.
116     * <p/>
117     * <p>This method is called exactly once for each unique proxy class
118     * descriptor in the stream.
119     * <p/>
120     * <p>The corresponding method in <code>ObjectOutputStream</code> is
121     * <code>annotateProxyClass</code>. For a given subclass of
122     * <code>ObjectInputStream</code> that overrides this method, the
123     * <code>annotateProxyClass</code> method in the corresponding
124     * subclass of <code>ObjectOutputStream</code> must write any data or
125     * objects read by this method.
126     * <p/>
127     * <p>The default implementation of this method in
128     * <code>ObjectInputStream</code> returns the result of calling
129     * <code>Proxy.getProxyClass</code> with the list of
130     * <code>Class</code> objects for the interfaces that are named in
131     * the <code>interfaces</code> parameter. The <code>Class</code>
132     * object for each interface name <code>i</code> is the value
133     * returned by calling
134     * <pre>
135     * Class.forName(i, false, loader)
136     * </pre>
137     * where <code>loader</code> is that of the first non-null class
138     * loader up the execution stack, or <code>null</code> if no non-null
139     * class loaders are on the stack (the same class loader choice used
140     * by the <code>resolveClass</code> method). This same value of
141     * <code>loader</code> is also the class loader passed to
142     * <code>Proxy.getProxyClass</code>. If <code>Proxy.getProxyClass</code>
143     * throws an <code>IllegalArgumentException</code>,
144     * <code>resolveProxyClass</code> will throw a
145     * <code>ClassNotFoundException</code> containing the
146     * <code>IllegalArgumentException</code>.
147     *
148     * @return a proxy class for the specified interfaces
149     * @param interfaces the list of interface names that were
150     * deserialized in the proxy class descriptor
151     * @throws java.io.IOException any exception thrown by the underlying
152     * <code>InputStream</code>
153     * @throws java.lang.ClassNotFoundException if the proxy class or any of the
154     * named interfaces could not be found
155     * @since 1.3
156     * @see java.io.ObjectOutputStream#annotateProxyClass(java.lang.Class)
157     */

158    protected Class JavaDoc resolveProxyClass(String JavaDoc[] interfaces)
159          throws java.io.IOException JavaDoc, ClassNotFoundException JavaDoc
160    {
161       if(cl == null)
162       {
163          return super.resolveProxyClass(interfaces);
164       }
165       else
166       {
167          Class JavaDoc[] classObjs = new Class JavaDoc[interfaces.length];
168          for(int i = 0; i < interfaces.length; i++)
169          {
170             classObjs[i] = cl.loadClass(interfaces[i]);
171          }
172          try
173          {
174             return java.lang.reflect.Proxy.getProxyClass(cl, classObjs);
175          }
176          catch(IllegalArgumentException JavaDoc e)
177          {
178             throw new ClassNotFoundException JavaDoc(null, e);
179          }
180       }
181    }
182 }
183
Popular Tags