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