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