View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  
20  package org.eclipse.jetty.util;
21  
22  import java.io.IOException;
23  import java.io.ObjectInputStream;
24  import java.lang.reflect.Modifier;
25  import java.lang.reflect.Proxy;
26  
27  
28  /**
29   * ClassLoadingObjectInputStream
30   *
31   * For re-inflating serialized objects, this class uses the thread context classloader
32   * rather than the jvm's default classloader selection.
33   * 
34   */
35  public class ClassLoadingObjectInputStream extends ObjectInputStream
36  {
37      /* ------------------------------------------------------------ */
38      public ClassLoadingObjectInputStream(java.io.InputStream in) throws IOException
39      {
40          super(in);
41      }
42  
43      /* ------------------------------------------------------------ */
44      public ClassLoadingObjectInputStream () throws IOException
45      {
46          super();
47      }
48  
49      /* ------------------------------------------------------------ */
50      @Override
51      public Class<?> resolveClass (java.io.ObjectStreamClass cl) throws IOException, ClassNotFoundException
52      {
53          try
54          {
55              return Class.forName(cl.getName(), false, Thread.currentThread().getContextClassLoader());
56          }
57          catch (ClassNotFoundException e)
58          {
59              return super.resolveClass(cl);
60          }
61      }
62      
63      /* ------------------------------------------------------------ */
64      @Override
65      protected Class<?> resolveProxyClass(String[] interfaces)
66              throws IOException, ClassNotFoundException
67      {
68          ClassLoader loader = Thread.currentThread().getContextClassLoader();
69  
70          ClassLoader nonPublicLoader = null;
71          boolean hasNonPublicInterface = false;
72  
73          // define proxy in class loader of non-public interface(s), if any
74          Class<?>[] classObjs = new Class[interfaces.length];
75          for (int i = 0; i < interfaces.length; i++) 
76          {
77              Class<?> cl = Class.forName(interfaces[i], false, loader);
78              if ((cl.getModifiers() & Modifier.PUBLIC) == 0) 
79              {
80                  if (hasNonPublicInterface) 
81                  {
82                      if (nonPublicLoader != cl.getClassLoader()) 
83                      {
84                          throw new IllegalAccessError(
85                                  "conflicting non-public interface class loaders");
86                      }
87                  } 
88                  else 
89                  {
90                      nonPublicLoader = cl.getClassLoader();
91                      hasNonPublicInterface = true;
92                  }
93              }
94              classObjs[i] = cl;
95          }
96          try 
97          {
98              return Proxy.getProxyClass(hasNonPublicInterface ? nonPublicLoader : loader,classObjs);
99          } 
100         catch (IllegalArgumentException e) 
101         {
102             throw new ClassNotFoundException(null, e);
103         }    
104     }
105 }