1
14
15 package com.liferay.portal.kernel.util;
16
17 import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
18 import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
19 import com.liferay.portal.kernel.log.Log;
20 import com.liferay.portal.kernel.log.LogFactoryUtil;
21
22 import java.io.ObjectInputStream;
23 import java.io.ObjectOutputStream;
24
25 import java.lang.Object;
26 import java.lang.reflect.InvocationTargetException;
27 import java.lang.reflect.Method;
28
29 import java.util.ArrayList;
30 import java.util.List;
31
32
37 public class ClassLoaderProxy {
38
39 public ClassLoaderProxy(Object obj, ClassLoader classLoader) {
40 _obj = obj;
41 _classLoader = classLoader;
42 }
43
44 public ClassLoader getClassLoader() {
45 return _classLoader;
46 }
47
48 public Object invoke(String methodName, Object[] args) throws Throwable {
49 Thread currentThread = Thread.currentThread();
50
51 ClassLoader contextClassLoader = currentThread.getContextClassLoader();
52
53 try {
54 currentThread.setContextClassLoader(_classLoader);
55
56 Class<?> classObj = Class.forName(
57 _obj.getClass().getName(), true, _classLoader);
58
59 List<Class<?>> parameterTypes = new ArrayList<Class<?>>();
60
61 for (int i = 0; i < args.length; i++) {
62 Object arg = args[i];
63
64 Class<?> argClass = Class.forName(
65 arg.getClass().getName(), true, _classLoader);
66
67 if (ClassUtil.isSubclass(argClass, PrimitiveWrapper.class)) {
68 MethodKey methodKey = new MethodKey(
69 argClass.getName(), "getValue", null);
70
71 Method method = MethodCache.get(methodKey);
72
73 args[i] = method.invoke(arg, (Object[])null);
74
75 argClass = (Class<?>)argClass.getField("TYPE").get(arg);
76 }
77
78 if (ClassUtil.isSubclass(argClass, NullWrapper.class)) {
79 NullWrapper nullWrapper = (NullWrapper)arg;
80
81 argClass = Class.forName(
82 nullWrapper.getClassName(), true, _classLoader);
83
84 args[i] = null;
85 }
86
87 parameterTypes.add(argClass);
88 }
89
90 Method method = null;
91
92 try {
93 method = classObj.getMethod(
94 methodName,
95 parameterTypes.toArray(new Class[parameterTypes.size()]));
96 }
97 catch (NoSuchMethodException nsme) {
98 Method[] methods = ((Class<?>)classObj).getMethods();
99
100 for (int i = 0; i < methods.length; i++) {
101 Class<?>[] methodParameterTypes =
102 methods[i].getParameterTypes();
103
104 if (methods[i].getName().equals(methodName) &&
105 methodParameterTypes.length == parameterTypes.size()) {
106
107 boolean correctParams = true;
108
109 for (int j = 0; j < parameterTypes.size(); j++) {
110 Class<?> a = parameterTypes.get(j);
111 Class<?> b = methodParameterTypes[j];
112
113 if (!ClassUtil.isSubclass(a, b)) {
114 correctParams = false;
115
116 break;
117 }
118 }
119
120 if (correctParams) {
121 method = methods[i];
122
123 break;
124 }
125 }
126 }
127
128 if (method == null) {
129 throw nsme;
130 }
131 }
132
133 return method.invoke(_obj, args);
134 }
135 catch (InvocationTargetException ite) {
136 throw translateThrowable(ite.getCause(), contextClassLoader);
137 }
138 catch (Throwable t) {
139 _log.error(t, t);
140
141 throw t;
142 }
143 finally {
144 currentThread.setContextClassLoader(contextClassLoader);
145 }
146 }
147
148 protected Throwable translateThrowable(
149 Throwable t1, ClassLoader contextClassLoader) {
150
151 try {
152 UnsyncByteArrayOutputStream ubaos =
153 new UnsyncByteArrayOutputStream();
154 ObjectOutputStream oos = new ObjectOutputStream(ubaos);
155
156 oos.writeObject(t1);
157
158 oos.flush();
159 oos.close();
160
161 UnsyncByteArrayInputStream bais = new UnsyncByteArrayInputStream(
162 ubaos.unsafeGetByteArray(), 0, ubaos.size());
163 ObjectInputStream ois = new ClassLoaderObjectInputStream(
164 bais, contextClassLoader);
165
166 t1 = (Throwable)ois.readObject();
167
168 ois.close();
169
170 return t1;
171 }
172 catch (Throwable t2) {
173 _log.error(t2, t2);
174
175 return t2;
176 }
177 }
178
179 private static Log _log = LogFactoryUtil.getLog(ClassLoaderProxy.class);
180
181 private Object _obj;
182 private ClassLoader _classLoader;
183
184 }