2
* JBoss, Home of Professional Open Source
3
* Copyright 2005, JBoss Inc., and individual contributors as indicated
4
* by the @authors tag. See the copyright.txt in the distribution for a
5
* full listing of individual contributors.
7
* This is free software; you can redistribute it and/or modify it
8
* under the terms of the GNU Lesser General Public License as
9
* published by the Free Software Foundation; either version 2.1 of
10
* the License, or (at your option) any later version.
12
* This software is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this software; if not, write to the Free
19
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
23
package org.jboss.remoting.loading;
25
import java.io.IOException;
26
import java.io.ObjectInputStream;
27
import java.io.StreamCorruptedException;
28
import java.lang.reflect.Method;
29
import java.security.AccessController;
30
import java.security.PrivilegedActionException;
31
import java.security.PrivilegedExceptionAction;
32
import java.util.HashMap;
34
import org.jboss.logging.Logger;
35
import org.jboss.remoting.util.SecurityUtility;
39
* ObjectInputStreamWithClassLoader
41
* @author <a href="mailto:jhaynie@vocalocity.net">Jeff Haynie</a>
42
* @author <a href="mailto:tom@jboss.org">Tom Elrod</a>
43
* @version $Revision: 5003 $
45
public class ObjectInputStreamWithClassLoader extends ObjectInputStream
48
protected static Method clearMethod;
50
protected static final Logger log = Logger.getLogger(ObjectInputStreamWithClassLoader.class);
58
clearMethod = getDeclaredMethod(ObjectInputStream.class, "clear", new Class[]{});
60
} catch (SecurityException e) {
61
log.error(e.getMessage(), e);
62
} catch (NoSuchMethodException e) {
63
log.error(e.getMessage(), e);
67
private ClassLoader cl;
70
/** table mapping primitive type names to corresponding class objects */
71
private static final HashMap primClasses = new HashMap(8, 1.0F);
73
primClasses.put("boolean", boolean.class);
74
primClasses.put("byte", byte.class);
75
primClasses.put("char", char.class);
76
primClasses.put("short", short.class);
77
primClasses.put("int", int.class);
78
primClasses.put("long", long.class);
79
primClasses.put("float", float.class);
80
primClasses.put("double", double.class);
81
primClasses.put("void", void.class);
85
* Create an ObjectInputStream that reads from the specified InputStream.
86
* The stream header containing the magic number and version number
87
* are read from the stream and verified. This method will block
88
* until the corresponding ObjectOutputStream has written and flushed the
91
* @param in the underlying <code>InputStream</code> from which to read
92
* @throws java.io.StreamCorruptedException
93
* The version or magic number are
95
* @throws java.io.IOException An exception occurred in the underlying stream.
97
public ObjectInputStreamWithClassLoader(java.io.InputStream in, ClassLoader cl)
98
throws IOException, StreamCorruptedException
105
* Set the classloader that the stream will used when deserializing class. This will
106
* allow plugging in of classloaders based on invocation context.
110
public void setClassLoader(ClassLoader cl)
116
* Gets the pluggable classloader that will be used for classloading when deserializing
121
public ClassLoader getClassLoader()
126
public void clearCache()
130
clearMethod.invoke(this, new Object[]{});
134
log.error(e.getMessage(), e);
140
* Load the local class equivalent of the specified stream class description.
142
* Subclasses may implement this method to allow classes to be
143
* fetched from an alternate source.
145
* The corresponding method in ObjectOutputStream is
146
* annotateClass. This method will be invoked only once for each
147
* unique class in the stream. This method can be implemented by
148
* subclasses to use an alternate loading mechanism but must
149
* return a Class object. Once returned, the serialVersionUID of the
150
* class is compared to the serialVersionUID of the serialized class.
151
* If there is a mismatch, the deserialization fails and an exception
154
* By default the class name is resolved relative to the class
155
* that called readObject. <p>
157
* Will use the classloader explicitly set if it exists. If it does not exist,
158
* will used its default classloader (that loader this instance).<p>
160
* @param v an instance of class ObjectStreamClass
161
* @return a Class object corresponding to <code>v</code>
162
* @throws java.io.IOException Any of the usual Input/Output exceptions.
163
* @throws java.lang.ClassNotFoundException
165
* a serialized object cannot be found.
167
protected Class resolveClass(java.io.ObjectStreamClass v)
168
throws java.io.IOException, ClassNotFoundException
172
return super.resolveClass(v);
176
// EJBTHREE-440 & JBREM-508
179
return Class.forName(v.getName(), false, cl);
181
catch(ClassNotFoundException ex)
183
Class cl = (Class) primClasses.get(v.getName());
194
* Returns a proxy class that implements the interfaces named in a
195
* proxy class descriptor; subclasses may implement this method to
196
* read custom data from the stream along with the descriptors for
197
* dynamic proxy classes, allowing them to use an alternate loading
198
* mechanism for the interfaces and the proxy class.
200
* <p>This method is called exactly once for each unique proxy class
201
* descriptor in the stream.
203
* <p>The corresponding method in <code>ObjectOutputStream</code> is
204
* <code>annotateProxyClass</code>. For a given subclass of
205
* <code>ObjectInputStream</code> that overrides this method, the
206
* <code>annotateProxyClass</code> method in the corresponding
207
* subclass of <code>ObjectOutputStream</code> must write any data or
208
* objects read by this method.
210
* <p>The default implementation of this method in
211
* <code>ObjectInputStream</code> returns the result of calling
212
* <code>Proxy.getProxyClass</code> with the list of
213
* <code>Class</code> objects for the interfaces that are named in
214
* the <code>interfaces</code> parameter. The <code>Class</code>
215
* object for each interface name <code>i</code> is the value
216
* returned by calling
218
* Class.forName(i, false, loader)
220
* where <code>loader</code> is that of the first non-null class
221
* loader up the execution stack, or <code>null</code> if no non-null
222
* class loaders are on the stack (the same class loader choice used
223
* by the <code>resolveClass</code> method). This same value of
224
* <code>loader</code> is also the class loader passed to
225
* <code>Proxy.getProxyClass</code>. If <code>Proxy.getProxyClass</code>
226
* throws an <code>IllegalArgumentException</code>,
227
* <code>resolveProxyClass</code> will throw a
228
* <code>ClassNotFoundException</code> containing the
229
* <code>IllegalArgumentException</code>.
231
* @return a proxy class for the specified interfaces
232
* @param interfaces the list of interface names that were
233
* deserialized in the proxy class descriptor
234
* @throws java.io.IOException any exception thrown by the underlying
235
* <code>InputStream</code>
236
* @throws java.lang.ClassNotFoundException if the proxy class or any of the
237
* named interfaces could not be found
239
* @see java.io.ObjectOutputStream#annotateProxyClass(java.lang.Class)
241
protected Class resolveProxyClass(String[] interfaces)
242
throws java.io.IOException, ClassNotFoundException
246
return super.resolveProxyClass(interfaces);
250
Class[] classObjs = new Class[interfaces.length];
251
for(int i = 0; i < interfaces.length; i++)
253
classObjs[i] = Class.forName(interfaces[i], false, cl);
257
return java.lang.reflect.Proxy.getProxyClass(cl, classObjs);
259
catch(IllegalArgumentException e)
261
throw new ClassNotFoundException(null, e);
266
static private Method getDeclaredMethod(final Class c, final String name, final Class[] parameterTypes)
267
throws NoSuchMethodException
269
if (SecurityUtility.skipAccessControl())
271
Method m = c.getDeclaredMethod(name, parameterTypes);
272
m.setAccessible(true);
278
return (Method) AccessController.doPrivileged( new PrivilegedExceptionAction()
280
public Object run() throws NoSuchMethodException
282
Method m = c.getDeclaredMethod(name, parameterTypes);
283
m.setAccessible(true);
288
catch (PrivilegedActionException e)
290
throw (NoSuchMethodException) e.getCause();
b'\\ No newline at end of file'