~ubuntu-branches/ubuntu/oneiric/libjboss-remoting-java/oneiric

« back to all changes in this revision

Viewing changes to src/main/org/jboss/remoting/loading/ObjectInputStreamWithClassLoader.java

  • Committer: Package Import Robot
  • Author(s): Torsten Werner
  • Date: 2011-09-09 14:01:03 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: package-import@ubuntu.com-20110909140103-hqokx61534tas9rg
Tags: 2.5.3.SP1-1
* Newer but not newest upstream release. Do not build samples.
* Change debian/watch to upstream's svn repo.
* Add patch to fix compile error caused by tomcat update.
  (Closes: #628303)
* Switch to source format 3.0.
* Switch to debhelper level 7.
* Remove useless Depends.
* Update Standards-Version: 3.9.2.
* Update README.source.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
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.
 
6
*
 
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.
 
11
*
 
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.
 
16
*
 
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.
 
21
*/
 
22
 
 
23
package org.jboss.remoting.loading;
 
24
 
 
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;
 
33
 
 
34
import org.jboss.logging.Logger;
 
35
import org.jboss.remoting.util.SecurityUtility;
 
36
 
 
37
 
 
38
/**
 
39
 * ObjectInputStreamWithClassLoader
 
40
 *
 
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 $
 
44
 */
 
45
public class ObjectInputStreamWithClassLoader extends ObjectInputStream
 
46
{
 
47
 
 
48
   protected static Method clearMethod;
 
49
 
 
50
   protected static final Logger log = Logger.getLogger(ObjectInputStreamWithClassLoader.class);
 
51
 
 
52
 
 
53
 
 
54
   static
 
55
   {
 
56
      try
 
57
      {
 
58
         clearMethod = getDeclaredMethod(ObjectInputStream.class, "clear", new Class[]{});
 
59
         
 
60
      } catch (SecurityException e) {
 
61
         log.error(e.getMessage(), e);
 
62
      } catch (NoSuchMethodException e) {
 
63
         log.error(e.getMessage(), e);
 
64
      }
 
65
   }
 
66
 
 
67
   private ClassLoader cl;
 
68
 
 
69
   // EJBTHREE-440
 
70
   /** table mapping primitive type names to corresponding class objects */
 
71
   private static final HashMap primClasses = new HashMap(8, 1.0F);
 
72
   static {
 
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);
 
82
   }
 
83
 
 
84
   /**
 
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
 
89
    * header.
 
90
    *
 
91
    * @param in the underlying <code>InputStream</code> from which to read
 
92
    * @throws java.io.StreamCorruptedException
 
93
    *                             The version or magic number are
 
94
    *                             incorrect.
 
95
    * @throws java.io.IOException An exception occurred in the underlying stream.
 
96
    */
 
97
   public ObjectInputStreamWithClassLoader(java.io.InputStream in, ClassLoader cl)
 
98
         throws IOException, StreamCorruptedException
 
99
   {
 
100
      super(in);
 
101
      this.cl = cl;
 
102
   }
 
103
 
 
104
   /**
 
105
    * Set the classloader that the stream will used when deserializing class.  This will
 
106
    * allow plugging in of classloaders based on invocation context.
 
107
    *
 
108
    * @param cl
 
109
    */
 
110
   public void setClassLoader(ClassLoader cl)
 
111
   {
 
112
      this.cl = cl;
 
113
   }
 
114
 
 
115
   /**
 
116
    * Gets the pluggable classloader that will be used for classloading when deserializing
 
117
    * objects.
 
118
    *
 
119
    * @return
 
120
    */
 
121
   public ClassLoader getClassLoader()
 
122
   {
 
123
      return cl;
 
124
   }
 
125
   
 
126
   public void clearCache()
 
127
   {
 
128
       try
 
129
       {
 
130
           clearMethod.invoke(this, new Object[]{});
 
131
       }
 
132
       catch (Throwable e)
 
133
       {
 
134
           log.error(e.getMessage(), e);
 
135
       }
 
136
       
 
137
   }
 
138
 
 
139
   /**
 
140
    * Load the local class equivalent of the specified stream class description.
 
141
    * <p/>
 
142
    * Subclasses may implement this method to allow classes to be
 
143
    * fetched from an alternate source.
 
144
    * <p/>
 
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
 
152
    * is raised. <p>
 
153
    * <p/>
 
154
    * By default the class name is resolved relative to the class
 
155
    * that called readObject. <p>
 
156
    * <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>
 
159
    *
 
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
 
164
    *                             If class of
 
165
    *                             a serialized object cannot be found.
 
166
    */
 
167
   protected Class resolveClass(java.io.ObjectStreamClass v)
 
168
         throws java.io.IOException, ClassNotFoundException
 
169
   {
 
170
      if(cl == null)
 
171
      {
 
172
         return super.resolveClass(v);
 
173
      }
 
174
      else
 
175
      {
 
176
         // EJBTHREE-440 & JBREM-508
 
177
         try
 
178
         {
 
179
            return Class.forName(v.getName(), false, cl);
 
180
         }
 
181
         catch(ClassNotFoundException ex)
 
182
         {
 
183
            Class cl = (Class) primClasses.get(v.getName());
 
184
            if (cl != null) {
 
185
               return cl;
 
186
            } else {
 
187
               throw ex;
 
188
            }
 
189
         }
 
190
      }
 
191
   }
 
192
 
 
193
   /**
 
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.
 
199
    * <p/>
 
200
    * <p>This method is called exactly once for each unique proxy class
 
201
    * descriptor in the stream.
 
202
    * <p/>
 
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.
 
209
    * <p/>
 
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
 
217
    * <pre>
 
218
    *     Class.forName(i, false, loader)
 
219
    * </pre>
 
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>.
 
230
    *
 
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
 
238
    * @since 1.3
 
239
    * @see java.io.ObjectOutputStream#annotateProxyClass(java.lang.Class)
 
240
    */
 
241
   protected Class resolveProxyClass(String[] interfaces)
 
242
         throws java.io.IOException, ClassNotFoundException
 
243
   {
 
244
      if(cl == null)
 
245
      {
 
246
         return super.resolveProxyClass(interfaces);
 
247
      }
 
248
      else
 
249
      {
 
250
         Class[] classObjs = new Class[interfaces.length];
 
251
         for(int i = 0; i < interfaces.length; i++)
 
252
         {
 
253
            classObjs[i] = Class.forName(interfaces[i], false, cl);
 
254
         }
 
255
         try
 
256
         {
 
257
            return java.lang.reflect.Proxy.getProxyClass(cl, classObjs);
 
258
         }
 
259
         catch(IllegalArgumentException e)
 
260
         {
 
261
            throw new ClassNotFoundException(null, e);
 
262
         }
 
263
      }
 
264
   }
 
265
   
 
266
   static private Method getDeclaredMethod(final Class c, final String name, final Class[] parameterTypes)
 
267
   throws NoSuchMethodException
 
268
   {
 
269
      if (SecurityUtility.skipAccessControl())
 
270
      {
 
271
         Method m = c.getDeclaredMethod(name, parameterTypes);
 
272
         m.setAccessible(true);
 
273
         return m;
 
274
      }
 
275
 
 
276
      try
 
277
      {
 
278
         return (Method) AccessController.doPrivileged( new PrivilegedExceptionAction()
 
279
         {
 
280
            public Object run() throws NoSuchMethodException
 
281
            {
 
282
               Method m = c.getDeclaredMethod(name, parameterTypes);
 
283
               m.setAccessible(true);
 
284
               return m;
 
285
            }
 
286
         });
 
287
      }
 
288
      catch (PrivilegedActionException e)
 
289
      {
 
290
         throw (NoSuchMethodException) e.getCause();
 
291
      }
 
292
   }
 
293
}
 
 
b'\\ No newline at end of file'