001
014
015 package com.liferay.portal.kernel.util;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019
020 import java.lang.reflect.InvocationTargetException;
021 import java.lang.reflect.Method;
022
023 import java.util.ArrayList;
024 import java.util.Collection;
025 import java.util.List;
026
027
031 public class AggregateClassLoader extends ClassLoader {
032
033 public static ClassLoader getAggregateClassLoader(
034 ClassLoader parentClassLoader, ClassLoader[] classLoaders) {
035
036 if ((classLoaders == null) || (classLoaders.length == 0)) {
037 return null;
038 }
039
040 if (classLoaders.length == 1) {
041 return classLoaders[0];
042 }
043
044 AggregateClassLoader aggregateClassLoader = new AggregateClassLoader(
045 parentClassLoader);
046
047 for (ClassLoader classLoader : classLoaders) {
048 aggregateClassLoader.addClassLoader(classLoader);
049 }
050
051 return aggregateClassLoader;
052 }
053
054 public static ClassLoader getAggregateClassLoader(
055 ClassLoader[] classLoaders) {
056
057 if ((classLoaders == null) || (classLoaders.length == 0)) {
058 return null;
059 }
060
061 return getAggregateClassLoader(classLoaders[0], classLoaders);
062 }
063
064 public AggregateClassLoader(ClassLoader classLoader) {
065 super(classLoader);
066 }
067
068 public void addClassLoader(ClassLoader classLoader) {
069 if (_classLoaders.contains(classLoader)) {
070 return;
071 }
072
073 if ((classLoader instanceof AggregateClassLoader) &&
074 (classLoader.getParent().equals(getParent()))){
075
076 AggregateClassLoader aggregateClassLoader =
077 (AggregateClassLoader)classLoader;
078
079 for (ClassLoader curClassLoader :
080 aggregateClassLoader.getClassLoaders()) {
081
082 addClassLoader(curClassLoader);
083 }
084 }
085 else {
086 if (classLoader instanceof ClassLoaderWrapper) {
087 _classLoaders.add((ClassLoaderWrapper)classLoader);
088 }
089 else {
090 _classLoaders.add(new ClassLoaderWrapper(classLoader));
091 }
092 }
093 }
094
095 public void addClassLoader(ClassLoader... classLoaders) {
096 for (ClassLoader classLoader : classLoaders) {
097 addClassLoader(classLoader);
098 }
099 }
100
101 public void addClassLoader(Collection<ClassLoader> classLoaders) {
102 for (ClassLoader classLoader : classLoaders) {
103 addClassLoader(classLoader);
104 }
105 }
106
107 public boolean equals(Object obj) {
108 if (this == obj) {
109 return true;
110 }
111
112 if (!(obj instanceof AggregateClassLoader)) {
113 return false;
114 }
115
116 AggregateClassLoader aggregateClassLoader = (AggregateClassLoader)obj;
117
118 if (_classLoaders.equals(aggregateClassLoader._classLoaders) &&
119 (((getParent() == null) &&
120 (aggregateClassLoader.getParent() == null)) ||
121 ((getParent() != null) &&
122 (getParent().equals(aggregateClassLoader.getParent()))))) {
123
124 return true;
125 }
126
127 return false;
128 }
129
130 public List<ClassLoaderWrapper> getClassLoaders() {
131 return _classLoaders;
132 }
133
134 public int hashCode() {
135 if (_classLoaders != null) {
136 return _classLoaders.hashCode();
137 }
138 else {
139 return 0;
140 }
141 }
142
143 protected Class<?> findClass(String name) throws ClassNotFoundException {
144 for (ClassLoaderWrapper classLoader : _classLoaders) {
145 try {
146 return classLoader.findClass(name);
147 }
148 catch (ClassNotFoundException cnfe) {
149 }
150 }
151
152 throw new ClassNotFoundException("Unable to find class " + name);
153 }
154
155 protected Class<?> loadClass(String name, boolean resolve)
156 throws ClassNotFoundException {
157
158 Class<?> loadedClass = null;
159
160 for (ClassLoaderWrapper classLoader : _classLoaders) {
161 try {
162 loadedClass = classLoader.loadClass(name, resolve);
163
164 break;
165 }
166 catch (ClassNotFoundException cnfe) {
167 }
168 }
169
170 if (loadedClass == null) {
171 loadedClass = super.loadClass(name, resolve);
172 }
173 else if (resolve) {
174 resolveClass(loadedClass);
175 }
176
177 return loadedClass;
178 }
179
180 private static Log _log = LogFactoryUtil.getLog(AggregateClassLoader.class);
181
182 private List<ClassLoaderWrapper> _classLoaders =
183 new ArrayList<ClassLoaderWrapper>();
184
185
186
187
188
189
190 private static class ClassLoaderWrapper extends ClassLoader {
191
192 public ClassLoaderWrapper(ClassLoader classLoader) {
193 super(classLoader);
194 }
195
196 public boolean equals(Object obj) {
197 if (!(obj instanceof ClassLoader)) {
198 return false;
199 }
200
201 return getParent().equals(obj);
202 }
203
204 public Class<?> findClass(String name) throws ClassNotFoundException {
205 try {
206 return (Class<?>)_findClassMethod.invoke(getParent(), name);
207 }
208 catch (InvocationTargetException ite) {
209 throw new ClassNotFoundException(
210 "Unable to find class " + name, ite.getTargetException());
211 }
212 catch (Exception e) {
213 throw new ClassNotFoundException(
214 "Unable to find class " + name, e);
215 }
216 }
217
218 public Class<?> loadClass(String name, boolean resolve)
219 throws ClassNotFoundException {
220
221 return super.loadClass(name, resolve);
222 }
223
224 private static Method _findClassMethod;
225
226 static {
227 try {
228 _findClassMethod = ClassLoader.class.getDeclaredMethod(
229 "findClass", String.class);
230
231 _findClassMethod.setAccessible(true);
232 }
233 catch (NoSuchMethodException nsme) {
234 if (_log.isErrorEnabled()) {
235 _log.error("Unable to locate findClass method", nsme);
236 }
237 }
238 }
239
240 }
241
242 }