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 }