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