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.lang.reflect.InvocationTargetException;
29 import java.lang.reflect.Method;
30
31 import java.util.ArrayList;
32 import java.util.Collection;
33 import java.util.List;
34
35
41 public class AggregateClassLoader extends ClassLoader {
42
43 public static ClassLoader getAggregateClassLoader(
44 ClassLoader parentClassLoader, ClassLoader[] classLoaders) {
45
46 if ((classLoaders == null) || (classLoaders.length == 0)) {
47 return null;
48 }
49
50 if (classLoaders.length == 1) {
51 return classLoaders[0];
52 }
53
54 AggregateClassLoader aggregateClassLoader = new AggregateClassLoader(
55 parentClassLoader);
56
57 for (ClassLoader classLoader : classLoaders) {
58 aggregateClassLoader.addClassLoader(classLoader);
59 }
60
61 return aggregateClassLoader;
62 }
63
64 public static ClassLoader getAggregateClassLoader(
65 ClassLoader[] classLoaders) {
66
67 if ((classLoaders == null) || (classLoaders.length == 0)) {
68 return null;
69 }
70
71 return getAggregateClassLoader(classLoaders[0], classLoaders);
72 }
73
74 public AggregateClassLoader(ClassLoader classLoader) {
75 super(classLoader);
76 }
77
78 public void addClassLoader(ClassLoader classLoader) {
79 if (_classLoaders.contains(classLoader)) {
80 return;
81 }
82
83 if ((classLoader instanceof AggregateClassLoader) &&
84 (classLoader.getParent().equals(getParent()))){
85
86 AggregateClassLoader aggregateClassLoader =
87 (AggregateClassLoader)classLoader;
88
89 for (ClassLoader curClassLoader :
90 aggregateClassLoader.getClassLoaders()) {
91
92 addClassLoader(curClassLoader);
93 }
94 }
95 else {
96 if (classLoader instanceof ClassLoaderWrapper) {
97 _classLoaders.add((ClassLoaderWrapper)classLoader);
98 }
99 else {
100 _classLoaders.add(new ClassLoaderWrapper(classLoader));
101 }
102 }
103 }
104
105 public void addClassLoader(ClassLoader... classLoaders) {
106 for (ClassLoader classLoader : classLoaders) {
107 addClassLoader(classLoader);
108 }
109 }
110
111 public void addClassLoader(Collection<ClassLoader> classLoaders) {
112 for (ClassLoader classLoader : classLoaders) {
113 addClassLoader(classLoader);
114 }
115 }
116
117 public boolean equals(Object obj) {
118 if (this == obj) {
119 return true;
120 }
121
122 if (!(obj instanceof AggregateClassLoader)) {
123 return false;
124 }
125
126 AggregateClassLoader aggregateClassLoader = (AggregateClassLoader)obj;
127
128 if (_classLoaders.equals(aggregateClassLoader._classLoaders) &&
129 (((getParent() == null) &&
130 (aggregateClassLoader.getParent() == null)) ||
131 ((getParent() != null) &&
132 (getParent().equals(aggregateClassLoader.getParent()))))) {
133
134 return true;
135 }
136
137 return false;
138 }
139
140 public List<ClassLoaderWrapper> getClassLoaders() {
141 return _classLoaders;
142 }
143
144 public int hashCode() {
145 if (_classLoaders != null) {
146 return _classLoaders.hashCode();
147 }
148 else {
149 return 0;
150 }
151 }
152
153 protected Class<?> findClass(String name) throws ClassNotFoundException {
154 for (ClassLoaderWrapper classLoader : _classLoaders) {
155 try {
156 return classLoader.findClass(name);
157 }
158 catch (ClassNotFoundException cnfe) {
159 }
160 }
161
162 throw new ClassNotFoundException("Unable to find class " + name);
163 }
164
165 protected Class<?> loadClass(String name, boolean resolve)
166 throws ClassNotFoundException {
167
168 Class<?> loadedClass = null;
169
170 for (ClassLoaderWrapper classLoader : _classLoaders) {
171 try {
172 loadedClass = classLoader.loadClass(name, resolve);
173
174 break;
175 }
176 catch (ClassNotFoundException cnfe) {
177 }
178 }
179
180 if (loadedClass == null) {
181 loadedClass = super.loadClass(name, resolve);
182 }
183 else if (resolve) {
184 resolveClass(loadedClass);
185 }
186
187 return loadedClass;
188 }
189
190 private static Log _log = LogFactoryUtil.getLog(AggregateClassLoader.class);
191
192 private List<ClassLoaderWrapper> _classLoaders =
193 new ArrayList<ClassLoaderWrapper>();
194
195
200 private static class ClassLoaderWrapper extends ClassLoader {
201
202 public ClassLoaderWrapper(ClassLoader classLoader) {
203 super(classLoader);
204 }
205
206 public boolean equals(Object obj) {
207 if (!(obj instanceof ClassLoader)) {
208 return false;
209 }
210
211 return getParent().equals(obj);
212 }
213
214 public Class<?> findClass(String name) throws ClassNotFoundException {
215 try {
216 return (Class<?>)_findClassMethod.invoke(getParent(), name);
217 }
218 catch (InvocationTargetException ite) {
219 throw new ClassNotFoundException(
220 "Unable to find class " + name, ite.getTargetException());
221 }
222 catch (Exception e) {
223 throw new ClassNotFoundException(
224 "Unable to find class " + name, e);
225 }
226 }
227
228 public Class<?> loadClass(String name, boolean resolve)
229 throws ClassNotFoundException {
230
231 return super.loadClass(name, resolve);
232 }
233
234 private static Method _findClassMethod;
235
236 static {
237 try {
238 _findClassMethod = ClassLoader.class.getDeclaredMethod(
239 "findClass", String.class);
240
241 _findClassMethod.setAccessible(true);
242 }
243 catch (NoSuchMethodException nsme) {
244 if (_log.isErrorEnabled()) {
245 _log.error("Unable to locate findClass method", nsme);
246 }
247 }
248 }
249
250 }
251
252 }