001
014
015 package com.liferay.portal.kernel.util;
016
017 import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayInputStream;
018 import com.liferay.portal.kernel.io.unsync.UnsyncByteArrayOutputStream;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021
022 import java.io.ObjectInputStream;
023 import java.io.ObjectOutputStream;
024
025 import java.lang.reflect.InvocationTargetException;
026 import java.lang.reflect.Method;
027
028
031 public class ClassLoaderProxy {
032
033 public ClassLoaderProxy(Object obj, ClassLoader classLoader) {
034 this(obj, obj.getClass().getName(), classLoader);
035 }
036
037 public ClassLoaderProxy(
038 Object obj, String className, ClassLoader classLoader) {
039
040 _obj = obj;
041 _className = className;
042 _classLoader = classLoader;
043 }
044
045 public ClassLoader getClassLoader() {
046 return _classLoader;
047 }
048
049 public String getClassName() {
050 return _className;
051 }
052
053 public Object invoke(MethodHandler methodHandler) throws Throwable {
054 Thread currentThread = Thread.currentThread();
055
056 ClassLoader contextClassLoader = currentThread.getContextClassLoader();
057
058 try {
059 currentThread.setContextClassLoader(_classLoader);
060
061 return _invoke(methodHandler);
062 }
063 catch (InvocationTargetException ite) {
064 throw translateThrowable(ite.getCause(), contextClassLoader);
065 }
066 catch (Throwable t) {
067 _log.error(t, t);
068
069 throw t;
070 }
071 finally {
072 currentThread.setContextClassLoader(contextClassLoader);
073 }
074 }
075
076 protected Throwable translateThrowable(
077 Throwable throwable, ClassLoader contextClassLoader) {
078
079 try {
080 UnsyncByteArrayOutputStream unsyncByteArrayOutputStream =
081 new UnsyncByteArrayOutputStream();
082
083 try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(
084 unsyncByteArrayOutputStream)) {
085
086 objectOutputStream.writeObject(throwable);
087
088 objectOutputStream.flush();
089 }
090
091 UnsyncByteArrayInputStream unsyncByteArrayInputStream =
092 new UnsyncByteArrayInputStream(
093 unsyncByteArrayOutputStream.unsafeGetByteArray(), 0,
094 unsyncByteArrayOutputStream.size());
095
096 try (ObjectInputStream objectInputStream =
097 new ClassLoaderObjectInputStream(
098 unsyncByteArrayInputStream, contextClassLoader)) {
099
100 return (Throwable)objectInputStream.readObject();
101 }
102 }
103 catch (Throwable throwable2) {
104 _log.error(throwable2, throwable2);
105
106 return throwable2;
107 }
108 }
109
110 private Object _invoke(MethodHandler methodHandler) throws Exception {
111 try {
112 return methodHandler.invoke(_obj);
113 }
114 catch (NoSuchMethodException nsme) {
115 MethodKey methodKey = methodHandler.getMethodKey();
116
117 String name = methodKey.getMethodName();
118
119 Class<?>[] parameterTypes = methodKey.getParameterTypes();
120
121 Class<?> clazz = Class.forName(_className, true, _classLoader);
122
123 for (Method method : clazz.getMethods()) {
124 String curName = method.getName();
125 Class<?>[] curParameterTypes = method.getParameterTypes();
126
127 if (!curName.equals(name) ||
128 (curParameterTypes.length != parameterTypes.length)) {
129
130 continue;
131 }
132
133 boolean correctParams = true;
134
135 for (int j = 0; j < parameterTypes.length; j++) {
136 Class<?> a = parameterTypes[j];
137 Class<?> b = curParameterTypes[j];
138
139 if (!ClassUtil.isSubclass(a, b.getName())) {
140 correctParams = false;
141
142 break;
143 }
144 }
145
146 if (correctParams) {
147 return method.invoke(_obj, methodHandler.getArguments());
148 }
149 }
150
151 throw nsme;
152 }
153 }
154
155 private static final Log _log = LogFactoryUtil.getLog(
156 ClassLoaderProxy.class);
157
158 private final ClassLoader _classLoader;
159 private final String _className;
160 private final Object _obj;
161
162 }