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

« back to all changes in this revision

Viewing changes to src/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'