• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Licensed to the Apache Software Foundation (ASF) under one or more
3  *  contributor license agreements.  See the NOTICE file distributed with
4  *  this work for additional information regarding copyright ownership.
5  *  The ASF licenses this file to You under the Apache License, Version 2.0
6  *  (the "License"); you may not use this file except in compliance with
7  *  the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  */
17 
18 package org.apache.harmony.luni.tests.java.net;
19 
20 import java.io.File;
21 import java.io.FileOutputStream;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.net.MalformedURLException;
25 import java.net.URL;
26 import java.net.URLClassLoader;
27 import java.net.URLStreamHandler;
28 import java.net.URLStreamHandlerFactory;
29 import java.util.Enumeration;
30 import java.util.NoSuchElementException;
31 import java.util.StringTokenizer;
32 import java.util.Vector;
33 import java.util.jar.Attributes;
34 import java.util.jar.JarFile;
35 import java.util.jar.JarOutputStream;
36 import java.util.jar.Manifest;
37 
38 import junit.framework.TestCase;
39 import tests.support.Support_Configuration;
40 import tests.support.Support_Jetty;
41 import tests.support.resource.Support_Resources;
42 
43 public class URLClassLoaderTest extends TestCase {
44 
45     private static final String PREFIX = "http://localhost:";
46 
47     private static final String ROOT = "resources/net.resources/HTTP/html/testres231";
48 
49     private static String serverURL = null;
50 
51     URLClassLoader ucl;
52 
53     static {
54         int port = 0;
55         try {
56             port = Support_Jetty.startHttpServerWithDocRoot(ROOT);
57         } catch (Exception e) {
58             fail("Exception during setup jetty : " + e.getMessage());
59         }
60         serverURL = PREFIX + port + "/";
61     }
62 
63     class BogusClassLoader extends ClassLoader {
getResource(String res)64         public URL getResource(String res) {
65             try {
66                 return new URL("http://test/BogusClassLoader");
67             } catch (MalformedURLException e) {
68                 return null;
69             }
70         }
71     }
72 
73     public class URLClassLoaderExt extends URLClassLoader {
74 
URLClassLoaderExt(URL[] urls)75         public URLClassLoaderExt(URL[] urls) {
76             super(urls);
77         }
78 
findClass(String cl)79         public Class<?> findClass(String cl) throws ClassNotFoundException {
80             return super.findClass(cl);
81         }
82     }
83 
84     /**
85      * @tests java.net.URLClassLoader#URLClassLoader(java.net.URL[])
86      */
test_Constructor$Ljava_net_URL()87     public void test_Constructor$Ljava_net_URL() throws Exception {
88         URL[] u = new URL[0];
89         ucl = new URLClassLoader(u);
90         assertNotNull(ucl);
91         assertSame("Failed to set parent", URLClassLoader
92                 .getSystemClassLoader(), ucl.getParent());
93 
94         URLClassLoader loader = new URLClassLoader(new URL[] { null });
95         try {
96             Class.forName("test", false, loader);
97             fail("Should throw NullPointerException");
98         } catch (NullPointerException e) {
99             // Expected
100         }
101     }
102 
103     /**
104      * @tests java.net.URLClassLoader#URLClassLoader(java.net.URL[],
105      *java.lang.ClassLoader)
106      */
test_Constructor$Ljava_net_URLLjava_lang_ClassLoader()107     public void test_Constructor$Ljava_net_URLLjava_lang_ClassLoader() {
108         ClassLoader cl = new BogusClassLoader();
109         URL[] u = new URL[0];
110         ucl = new URLClassLoader(u, cl);
111         URL res = ucl.getResource("J");
112         assertNotNull(res);
113         assertEquals("Failed to set parent", "/BogusClassLoader", res.getFile());
114     }
115 
116     /**
117      * @tests java.net.URLClassLoader#findResources(java.lang.String)
118      */
test_findResourcesLjava_lang_String()119     public void test_findResourcesLjava_lang_String() throws IOException {
120         String[] resValues = { "This is a test resource file.",
121                 "This is a resource from a subdir" };
122         URL[] urls = new URL[2];
123         urls[0] = new URL(serverURL);
124         urls[1] = new URL(serverURL + "/subdir1/");
125         ucl = new URLClassLoader(urls);
126         Enumeration res = ucl.findResources("RESOURCE.TXT");
127         assertNotNull("Failed to locate resources", res);
128 
129         int i = 0;
130         while (res.hasMoreElements()) {
131             StringBuffer sb = new StringBuffer();
132             InputStream is = ((URL) res.nextElement()).openStream();
133             int c;
134             while ((c = is.read()) != -1) {
135                 sb.append((char) c);
136             }
137             assertEquals("Returned incorrect resource/or in wrong order",
138                     resValues[i++], sb.toString());
139         }
140         assertEquals("Incorrect number of resources returned: " + i, 2, i);
141 
142         // Regression for HARMONY-6510
143         res = ucl.findResources(null);
144         assertNotNull(res);
145         assertFalse(res.hasMoreElements());
146     }
147 
148     /**
149      * @tests java.net.URLClassLoader#getURLs()
150      */
test_getURLs()151     public void test_getURLs() throws MalformedURLException {
152         URL[] urls = new URL[4];
153         urls[0] = new URL("http://" + Support_Configuration.HomeAddress);
154         urls[1] = new URL("http://" + Support_Configuration.TestResources + "/");
155         urls[2] = new URL("ftp://" + Support_Configuration.TestResources + "/");
156         urls[3] = new URL("jar:file:c://" + Support_Configuration.TestResources
157                 + "!/");
158         ucl = new URLClassLoader(urls);
159         URL[] ucUrls = ucl.getURLs();
160         for (int i = 0; i < urls.length; i++) {
161             assertEquals("Returned incorrect URL[]", urls[i], ucUrls[i]);
162         }
163     }
164 
165     /**
166      * @tests java.net.URLClassLoader#newInstance(java.net.URL[])
167      */
test_newInstance$Ljava_net_URL()168     public void test_newInstance$Ljava_net_URL() throws MalformedURLException,
169             ClassNotFoundException {
170         // Verify that loaded class' have correct permissions
171         URL[] urls = new URL[1];
172         urls[0] = new URL(serverURL + "/UCL/UCL.jar");
173         ucl = URLClassLoader.newInstance(urls);
174         Class cl = ucl.loadClass("ucl.ResClass");
175 
176         URL res = cl.getClassLoader().getResource("XX.class");
177         assertNotNull("Failed to load class", cl);
178         assertNotNull(
179                 "Loaded class unable to access resource from same codeSource",
180                 res);
181         cl = null;
182         urls[0] = new URL("jar:" + serverURL + "/UCL/UCL.jar!/");
183         ucl = URLClassLoader.newInstance(urls);
184         cl = ucl.loadClass("ucl.ResClass");
185         assertNotNull("Failed to load class from explicit jar URL", cl);
186     }
187 
188     /**
189      * @tests java.net.URLClassLoader#newInstance(java.net.URL[],
190      *java.lang.ClassLoader)
191      */
test_newInstance$Ljava_net_URLLjava_lang_ClassLoader()192     public void test_newInstance$Ljava_net_URLLjava_lang_ClassLoader() {
193         ClassLoader cl = new BogusClassLoader();
194         URL[] u = new URL[0];
195         ucl = URLClassLoader.newInstance(u, cl);
196         URL res = ucl.getResource("J");
197         assertNotNull(res);
198         assertEquals("Failed to set parent", "/BogusClassLoader", res.getFile());
199     }
200 
201     /**
202      * @tests java.net.URLClassLoader#URLClassLoader(java.net.URL[],
203      *java.lang.ClassLoader, java.net.URLStreamHandlerFactory)
204      */
test_Constructor$Ljava_net_URLLjava_lang_ClassLoaderLjava_net_URLStreamHandlerFactory()205     public void test_Constructor$Ljava_net_URLLjava_lang_ClassLoaderLjava_net_URLStreamHandlerFactory() {
206         class TestFactory implements URLStreamHandlerFactory {
207             public URLStreamHandler createURLStreamHandler(String protocol) {
208                 return null;
209             }
210         }
211         ClassLoader cl = new BogusClassLoader();
212         URL[] u = new URL[0];
213         ucl = new URLClassLoader(u, cl, new TestFactory());
214         URL res = ucl.getResource("J");
215         assertNotNull(res);
216         assertEquals("Failed to set parent", "/BogusClassLoader", res.getFile());
217     }
218 
219     /**
220      * @throws ClassNotFoundException
221      * @throws IOException
222      * @tests java.net.URLClassLoader#findClass(java.lang.String)
223      */
test_findClassLjava_lang_String()224     public void test_findClassLjava_lang_String()
225             throws ClassNotFoundException, IOException {
226         File resources = Support_Resources.createTempFolder();
227         String resPath = resources.toString();
228         if (resPath.charAt(0) == '/' || resPath.charAt(0) == '\\') {
229             resPath = resPath.substring(1);
230         }
231         Support_Resources.copyFile(resources, "JarIndex", "hyts_11.jar");
232         Support_Resources.copyFile(resources, "JarIndex", "hyts_12.jar");
233         Support_Resources.copyFile(resources, "JarIndex", "hyts_13.jar");
234         Support_Resources.copyFile(resources, "JarIndex", "hyts_14.jar");
235 
236         URL[] urls = new URL[1];
237         urls[0] = new URL("file:/" + resPath + "/JarIndex/hyts_11.jar");
238         URLClassLoader ucl = URLClassLoader.newInstance(urls, null);
239 
240         URL resURL = ucl.findResource("Test.txt");
241         URL reference = new URL("jar:file:/" + resPath.replace('\\', '/')
242                 + "/JarIndex/hyts_14.jar!/Test.txt");
243         assertEquals("Resource not found: " + resURL + " ref: " + reference,
244                 reference, resURL);
245 
246         assertNotNull(Class.forName("cpack.CNothing", true, ucl));
247 
248         Support_Resources.copyFile(resources, "JarIndex", "hyts_21.jar");
249         Support_Resources.copyFile(resources, "JarIndex", "hyts_22.jar");
250         Support_Resources.copyFile(resources, "JarIndex", "hyts_23.jar");
251         urls[0] = new URL("file:/" + resPath + "/JarIndex/hyts_21.jar");
252         ucl = URLClassLoader.newInstance(urls, null);
253         Enumeration en = ucl.findResources("bpack/");
254 
255         boolean resourcesFound;
256         try {
257             resourcesFound = true;
258             URL url1 = (URL) en.nextElement();
259             URL url2 = (URL) en.nextElement();
260             resourcesFound = resourcesFound
261                     && url1.equals(new URL("jar:file:/"
262                     + resPath.replace('\\', '/')
263                     + "/JarIndex/hyts_22.jar!/bpack/"));
264             resourcesFound = resourcesFound
265                     && url2.equals(new URL("jar:file:/"
266                     + resPath.replace('\\', '/')
267                     + "/JarIndex/hyts_23.jar!/bpack/"));
268             if (en.hasMoreElements()) {
269                 resourcesFound = false;
270             }
271         } catch (NoSuchElementException e) {
272             resourcesFound = false;
273         }
274         assertTrue("Resources not found (1)", resourcesFound);
275 
276         assertNotNull(Class.forName("bpack.Homer", true, ucl));
277 
278         try {
279             Class.forName("bpack.Bart", true, ucl);
280             fail("should throw ClassNotFoundException");
281         } catch (ClassNotFoundException e) {
282             // Expected
283         }
284 
285         try {
286             Class.forName("Main4", true, ucl);
287             fail("should throw ClassNotFoundException");
288         } catch (ClassNotFoundException e) {
289             // Expected
290         }
291 
292         Support_Resources.copyFile(resources, "JarIndex", "hyts_22-new.jar");
293         urls[0] = new URL("file:/" + resPath + "/JarIndex/hyts_22-new.jar");
294         ucl = URLClassLoader.newInstance(urls, null);
295         assertNotNull("Cannot find resource", ucl.findResource("cpack/"));
296         Support_Resources.copyFile(resources, "JarIndex", "hyts_11.jar");
297         urls[0] = new URL("file:/" + resPath + "/JarIndex/hyts_31.jar");
298         ucl = URLClassLoader.newInstance(urls, null);
299 
300         try {
301             Class.forName("cpack.Mock", true, ucl);
302             fail("should throw ClassNotFoundException");
303         } catch (ClassNotFoundException e) {
304             // Expected
305         }
306 
307         // testing circular reference
308         Support_Resources.copyFile(resources, "JarIndex", "hyts_41.jar");
309         Support_Resources.copyFile(resources, "JarIndex", "hyts_42.jar");
310         urls[0] = new URL("file:/" + resPath + "/JarIndex/hyts_41.jar");
311         ucl = URLClassLoader.newInstance(urls, null);
312         en = ucl.findResources("bpack/");
313         resourcesFound = resourcesFound
314                 && ((URL) en.nextElement()).equals(new URL("jar:file:/"
315                 + resPath.replace('\\', '/')
316                 + "/JarIndex/hyts_42.jar!/bpack/"));
317         assertTrue("Resources not found (2)", resourcesFound);
318         assertFalse("No more resources expected", en.hasMoreElements());
319 
320         // Regression test for HARMONY-2357.
321         try {
322             URLClassLoaderExt cl = new URLClassLoaderExt(new URL[557]);
323             cl.findClass("0");
324             fail("should throw NullPointerException");
325         } catch (NullPointerException npe) {
326             // Expected
327         }
328 
329         // Regression test for HARMONY-2871.
330         URLClassLoader cl = new URLClassLoader(new URL[] { new URL(
331                 "file:/foo.jar") });
332 
333         try {
334             Class.forName("foo.Foo", false, cl);
335         } catch (Exception ex) {
336             // Ignored
337         }
338 
339         try {
340             Class.forName("foo.Foo", false, cl);
341             fail("should throw ClassNotFoundException");
342         } catch (ClassNotFoundException cnfe) {
343             // Expected
344         }
345     }
346 
347     /**
348      * @tests java.net.URLClassLoader#findResource(java.lang.String)
349      */
test_findResourceLjava_lang_String()350     public void test_findResourceLjava_lang_String()
351             throws MalformedURLException {
352         URL[] urls = new URL[2];
353         urls[0] = new URL(serverURL);
354         urls[1] = new URL(serverURL);
355         ucl = new URLClassLoader(urls);
356         URL res = ucl.findResource("RESOURCE.TXT");
357         assertNotNull("Failed to locate resource", res);
358 
359         StringBuffer sb = new StringBuffer();
360         try {
361             java.io.InputStream is = res.openStream();
362 
363             int c;
364             while ((c = is.read()) != -1) {
365                 sb.append((char) c);
366             }
367             is.close();
368         } catch (IOException e) {
369         }
370         assertTrue("Returned incorrect resource", !sb.toString().equals(
371                 "This is a test resource file"));
372     }
373 
testFindResource_H3461()374     public void testFindResource_H3461() throws Exception {
375         File userDir = new File(System.getProperty("user.dir"));
376         File dir = new File(userDir, "encode#me");
377         File f, f2;
378         URLClassLoader loader;
379         URL dirUrl;
380 
381         if (!dir.exists()) {
382             dir.mkdir();
383         }
384         dir.deleteOnExit();
385         dirUrl = dir.toURI().toURL();
386         loader = new URLClassLoader(new URL[] { dirUrl });
387 
388         f = File.createTempFile("temp", ".dat", dir);
389         f.deleteOnExit();
390         f2 = File.createTempFile("bad#name#", ".dat", dir);
391         f2.deleteOnExit();
392 
393         assertNotNull(
394                 "Unable to load resource from path with problematic name",
395                 loader.getResource(f.getName()));
396         assertEquals("URL was not correctly encoded", f2.toURI().toURL(),
397                 loader.getResource(f2.getName()));
398     }
399 
test_findResource()400     public void test_findResource() throws Exception {
401         File resources = Support_Resources.createTempFolder();
402         String resPath = resources.toString();
403         if (resPath.charAt(0) == '/' || resPath.charAt(0) == ' ') {
404             resPath = resPath.substring(1);
405         }
406         Support_Resources.copyFile(resources, "JarIndex", "hyts_21.jar");
407         Support_Resources.copyFile(resources, "JarIndex", "hyts_22.jar");
408         Support_Resources.copyFile(resources, "JarIndex", "hyts_23.jar");
409 
410         URLClassLoader urlClassloader = URLClassLoader.newInstance(
411                 new URL[] { new URL("file:/" + resPath
412                         + "/JarIndex/hyts_21.jar") }, null);
413         Enumeration en = urlClassloader.findResources("bpack/");
414         assertTrue(en.hasMoreElements());
415         URL expected = new URL("jar:file:/" + resPath.replace('\\', '/')
416                 + "/JarIndex/hyts_22.jar!/bpack/");
417         assertEquals(expected, (URL) en.nextElement());
418         assertEquals(expected, urlClassloader.findResource("bpack/"));
419     }
420 
421     /**
422      * @tests java.net.URLClassLoader#getResource(java.lang.String)
423      */
test_getResourceLjava_lang_String()424     public void test_getResourceLjava_lang_String()
425             throws MalformedURLException {
426         URL url1 = new URL("file:///");
427         URLClassLoader loader = new URLClassLoader(new URL[] { url1 }, null);
428         long start = System.currentTimeMillis();
429         // try without the leading /
430         URL result = loader.getResource("dir1/file1");
431         long end = System.currentTimeMillis();
432         long time = end - start;
433         if (time < 100) {
434             time = 100;
435         }
436 
437         start = System.currentTimeMillis();
438         // try with the leading forward slash
439         result = loader.getResource("/dir1/file1");
440         end = System.currentTimeMillis();
441         long uncTime = end - start;
442         assertTrue("too long. UNC path formed? UNC time: " + uncTime
443                 + " regular time: " + time, uncTime <= (time * 4));
444     }
445 
446     /**
447      * Regression for Harmony-2237
448      */
test_getResource()449     public void test_getResource() throws Exception {
450         URLClassLoader urlLoader = getURLClassLoader();
451         assertNull(urlLoader.findResource("XXX")); //$NON-NLS-1$
452     }
453 
getURLClassLoader()454     private static URLClassLoader getURLClassLoader() {
455         String classPath = System.getProperty("java.class.path");
456         StringTokenizer tok = new StringTokenizer(classPath, File.pathSeparator);
457         Vector<URL> urlVec = new Vector<URL>();
458         String resPackage = Support_Resources.RESOURCE_PACKAGE;
459         try {
460             while (tok.hasMoreTokens()) {
461                 String path = tok.nextToken();
462                 String url;
463                 if (new File(path).isDirectory())
464                     url = "file:" + path + resPackage + "subfolder/";
465                 else
466                     url = "jar:file:" + path + "!" + resPackage + "subfolder/";
467                 urlVec.addElement(new URL(url));
468             }
469         } catch (MalformedURLException e) {
470             // do nothing
471         }
472         URL[] urls = new URL[urlVec.size()];
473         for (int i = 0; i < urlVec.size(); i++) {
474             urls[i] = urlVec.elementAt(i);
475         }
476         URLClassLoader loader = new URLClassLoader(urls, null);
477         return loader;
478     }
479 
480     /**
481      * Regression test for HARMONY-2255
482      */
test_getResourceAsStream()483     public void test_getResourceAsStream() {
484         InputStream in = this.getClass()
485                 .getResourceAsStream("test%.properties");
486         assertNotNull(in);
487         in = this.getClass().getResourceAsStream("test%25.properties");
488         assertNull(in);
489     }
490 
491     /**
492      * Regression test for HARMONY-6074
493      */
test_findClassLjava_lang_String_Jar_Class_Path()494     public void test_findClassLjava_lang_String_Jar_Class_Path() throws Exception {
495         File resources = Support_Resources.createTempFolder();
496         String resPath = resources.toString();
497         if (resPath.charAt(0) == '/' || resPath.charAt(0) == '\\') {
498             resPath = resPath.substring(1);
499         }
500 
501         Support_Resources.copyFile(resources, "JarIndex", "hyts_11.jar");
502         Support_Resources.copyFile(resources, "JarIndex", "hyts_13.jar");
503 
504         JarFile jarFile = new JarFile(resources.getAbsolutePath() + "/JarIndex/hyts_11.jar");
505         Manifest mf = jarFile.getManifest();
506         Attributes attrs = mf.getMainAttributes();
507         attrs.putValue("Class-Path", "file:/" + resPath + "/JarIndex/hyts_13.jar");
508 
509         File mainJar = new File(resources.getAbsolutePath() + "/JarIndex/main.jar");
510         JarOutputStream jos = new JarOutputStream(new FileOutputStream(mainJar), mf);
511         jos.flush();
512         jos.close();
513         assertTrue(mainJar.exists());
514 
515         URL[] urls = new URL[1];
516         urls[0] = new URL("file:/" + resPath + "/JarIndex/main.jar");
517         ucl = URLClassLoader.newInstance(urls, null);
518         assertNotNull(Class.forName("Main2", true, ucl));
519     }
520 
521 }
522