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