1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.catalina.util;
19
20 import java.io.InputStream;
21 import java.io.IOException;
22 import java.io.ObjectInputStream;
23 import java.io.ObjectStreamClass;
24 import java.lang.reflect.Proxy;
25
26 /**
27 * Custom subclass of <code>ObjectInputStream</code> that loads from the
28 * class loader for this web application. This allows classes defined only
29 * with the web application to be found correctly.
30 *
31 * @author Craig R. McClanahan
32 * @author Bip Thelin
33 * @version $Revision: 467222 $, $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
34 */
35
36 public final class CustomObjectInputStream
37 extends ObjectInputStream {
38
39
40 /**
41 * The class loader we will use to resolve classes.
42 */
43 private ClassLoader classLoader = null;
44
45
46 /**
47 * Construct a new instance of CustomObjectInputStream
48 *
49 * @param stream The input stream we will read from
50 * @param classLoader The class loader used to instantiate objects
51 *
52 * @exception IOException if an input/output error occurs
53 */
54 public CustomObjectInputStream(InputStream stream,
55 ClassLoader classLoader)
56 throws IOException {
57
58 super(stream);
59 this.classLoader = classLoader;
60 }
61
62
63 /**
64 * Load the local class equivalent of the specified stream class
65 * description, by using the class loader assigned to this Context.
66 *
67 * @param classDesc Class description from the input stream
68 *
69 * @exception ClassNotFoundException if this class cannot be found
70 * @exception IOException if an input/output error occurs
71 */
72 public Class resolveClass(ObjectStreamClass classDesc)
73 throws ClassNotFoundException, IOException {
74 try {
75 return Class.forName(classDesc.getName(), false, classLoader);
76 } catch (ClassNotFoundException e) {
77 // Try also the superclass because of primitive types
78 return super.resolveClass(classDesc);
79 }
80 }
81
82
83 /**
84 * Return a proxy class that implements the interfaces named in a proxy
85 * class descriptor. Do this using the class loader assigned to this
86 * Context.
87 */
88 protected Class resolveProxyClass(String[] interfaces)
89 throws IOException, ClassNotFoundException {
90
91 Class[] cinterfaces = new Class[interfaces.length];
92 for (int i = 0; i < interfaces.length; i++)
93 cinterfaces[i] = classLoader.loadClass(interfaces[i]);
94
95 try {
96 return Proxy.getProxyClass(classLoader, cinterfaces);
97 } catch (IllegalArgumentException e) {
98 throw new ClassNotFoundException(null, e);
99 }
100 }
101
102 }