1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.logging.pathable;
18
19 import static org.junit.Assert.assertNotEquals;
20
21 import java.io.InputStream;
22 import java.net.URL;
23 import java.util.ArrayList;
24 import java.util.Arrays;
25 import java.util.Enumeration;
26 import java.util.HashSet;
27 import java.util.Set;
28
29 import junit.framework.Test;
30 import junit.framework.TestCase;
31
32 import org.apache.commons.logging.Artifacts;
33 import org.apache.commons.logging.PathableClassLoader;
34 import org.apache.commons.logging.PathableTestSuite;
35
36
37
38
39
40
41
42
43
44
45
46
47 public class ParentFirstTestCase extends TestCase {
48
49
50
51
52
53
54
55
56
57
58 public static Test suite() throws Exception {
59 final Class<ParentFirstTestCase> thisClass = ParentFirstTestCase.class;
60 final ClassLoader thisClassLoader = thisClass.getClassLoader();
61
62
63
64 final PathableClassLoader parent = new PathableClassLoader(null);
65
66
67
68
69
70
71 parent.useExplicitLoader("junit.", thisClassLoader);
72 parent.useExplicitLoader("org.junit.", thisClassLoader);
73
74
75 parent.addLogicalLib("commons-logging");
76
77
78 final PathableClassLoader child = new PathableClassLoader(parent);
79
80
81
82 child.addLogicalLib("testclasses");
83 child.addLogicalLib("commons-logging-adapters");
84
85
86 final PathableClassLoader context = new PathableClassLoader(child);
87
88
89 final Class<?> testClass = child.loadClass(thisClass.getName());
90
91
92 return new PathableTestSuite(testClass, context);
93 }
94
95
96
97
98 private static URL[] toURLArray(final Enumeration<URL> e) {
99 final ArrayList<URL> l = new ArrayList<>();
100 while (e.hasMoreElements()) {
101 l.add(e.nextElement());
102 }
103 final URL[] tmp = new URL[l.size()];
104 return l.toArray(tmp);
105 }
106
107
108
109
110
111
112 private Set<ClassLoader> getAncestorCLs() {
113 final Set<ClassLoader> s = new HashSet<>();
114 ClassLoader cl = this.getClass().getClassLoader();
115 while (cl != null) {
116 s.add(cl);
117 cl = cl.getParent();
118 }
119 return s;
120 }
121
122
123
124
125
126
127
128 public void testPaths() throws Exception {
129
130 final ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
131 assertNotNull("Context class loader is null", contextLoader);
132 assertEquals("Context class loader has unexpected type",
133 PathableClassLoader.class.getName(),
134 contextLoader.getClass().getName());
135
136
137 final ClassLoader thisLoader = this.getClass().getClassLoader();
138 assertNotNull("thisLoader is null", thisLoader);
139 assertEquals("thisLoader has unexpected type",
140 PathableClassLoader.class.getName(),
141 thisLoader.getClass().getName());
142
143
144
145 assertSame("Context class loader is not child of thisLoader",
146 thisLoader, contextLoader.getParent());
147
148
149 final ClassLoader parentLoader = thisLoader.getParent();
150 assertNotNull("Parent class loader is null", parentLoader);
151 assertEquals("Parent class loader has unexpected type",
152 PathableClassLoader.class.getName(),
153 parentLoader.getClass().getName());
154
155
156 assertNull("Parent class loader has non-null parent", parentLoader.getParent());
157
158
159
160
161 final ClassLoader systemLoader = ClassLoader.getSystemClassLoader();
162 assertNotNull("System class loader is null", systemLoader);
163 assertNotEquals("System class loader has unexpected type", PathableClassLoader.class.getName(),
164 systemLoader.getClass().getName());
165
166
167
168
169 final Class<?> junitTest = contextLoader.loadClass("junit.framework.Test");
170 final Set<?> ancestorCLs = getAncestorCLs();
171 assertFalse("Junit not loaded by ancestor class loader",
172 ancestorCLs.contains(junitTest.getClassLoader()));
173
174
175 final Class<?> logClass = contextLoader.loadClass("org.apache.commons.logging.Log");
176 assertSame("Log class not loaded via parent",
177 logClass.getClassLoader(), parentLoader);
178
179
180
181 final Class<?> log4jClass = contextLoader.loadClass("org.apache.commons.logging.impl.Log4JLogger");
182 assertSame("Log4JLogger not loaded via parent",
183 log4jClass.getClassLoader(), parentLoader);
184
185
186 final Class<?> testClass = contextLoader.loadClass("org.apache.commons.logging.PathableTestSuite");
187 assertSame("PathableTestSuite not loaded via child",
188 testClass.getClassLoader(), thisLoader);
189
190
191 try {
192 final Class<?> noSuchClass = contextLoader.loadClass("no.such.class");
193 fail("Class no.such.class is unexpectedly available");
194 assertNotNull(noSuchClass);
195 } catch (final ClassNotFoundException ex) {
196
197 }
198
199
200 final Class<?> stringClass = contextLoader.loadClass("java.lang.String");
201 assertNull("String class class loader is not null!",
202 stringClass.getClassLoader());
203 }
204
205
206
207
208 public void testResource() {
209 URL resource;
210
211 final ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
212 final ClassLoader childLoader = contextLoader.getParent();
213
214
215 resource = childLoader.getResource("nosuchfile");
216 assertNull("Non-null URL returned for invalid resource name", resource);
217
218
219 resource = childLoader.getResource("org/apache/commons/logging/Log.class");
220 assertNotNull("Unable to locate Log.class resource", resource);
221
222
223 resource = childLoader.getResource("org/apache/commons/logging/PathableTestSuite.class");
224 assertNotNull("Unable to locate PathableTestSuite.class resource", resource);
225
226
227
228
229
230 resource = childLoader.getResource("org/apache/commons/logging/impl/Log4JLogger.class");
231 assertNotNull("Unable to locate Log4JLogger.class resource", resource);
232 assertTrue("Incorrect source for Log4JLogger class",
233 resource.toString().indexOf(Artifacts.getMainJarName()) > 0);
234 }
235
236
237
238
239 public void testResourceAsStream() throws Exception {
240
241 final ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
242 final ClassLoader childLoader = contextLoader.getParent();
243 final ClassLoader parentLoader = childLoader.getParent();
244 final ClassLoader bootLoader = parentLoader.getParent();
245 assertNull("Unexpected class loader hierarchy", bootLoader);
246
247
248 InputStream is = childLoader.getResourceAsStream("nosuchfile");
249 assertNull("Invalid resource returned non-null stream", is);
250
251
252 is = childLoader.getResourceAsStream("org/apache/commons/logging/Log.class");
253 assertNotNull("Null returned for valid resource", is);
254 is.close();
255
256
257
258
259
260 }
261
262
263
264
265 public void testResources() throws Exception {
266
267 final ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
268 final ClassLoader childLoader = contextLoader.getParent();
269 final ClassLoader parentLoader = childLoader.getParent();
270 final ClassLoader bootLoader = parentLoader.getParent();
271 assertNull("Unexpected class loader hierarchy", bootLoader);
272
273
274 Enumeration<URL> resources = childLoader.getResources("nosuchfile");
275 URL[] urls = toURLArray(resources);
276 assertEquals("Non-null URL returned for invalid resource name", 0, urls.length);
277
278
279 resources = childLoader.getResources("org/apache/commons/logging/Log.class");
280 urls = toURLArray(resources);
281 assertEquals("Unexpected number of Log.class resources found", 1, urls.length);
282
283
284 resources = childLoader.getResources("org/apache/commons/logging/PathableTestSuite.class");
285 urls = toURLArray(resources);
286 assertEquals("Unexpected number of PathableTestSuite.class resources found", 1, urls.length);
287
288
289
290 resources = childLoader.getResources("org/apache/commons/logging/impl/Log4JLogger.class");
291 urls = toURLArray(resources);
292 assertEquals("Unexpected number of Log4JLogger.class resources found", 2, urls.length);
293
294
295
296 final String[] urlsToStrings = new String[2];
297 urlsToStrings[0] = urls[0].toString();
298 urlsToStrings[1] = urls[1].toString();
299 Arrays.sort(urlsToStrings);
300 assertTrue("Incorrect source for Log4JLogger class",
301 urlsToStrings[0].indexOf(Artifacts.getAdaptersJarName()) > 0);
302 assertTrue("Incorrect source for Log4JLogger class",
303 urlsToStrings[1].indexOf(Artifacts.getMainJarName()) > 0);
304
305 }
306 }