Home | History | Annotate | Download | only in net
      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 {
     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 
     75         public URLClassLoaderExt(URL[] urls) {
     76             super(urls);
     77         }
     78 
     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      */
     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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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 
    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 
    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      */
    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      */
    449     public void test_getResource() throws Exception {
    450         URLClassLoader urlLoader = getURLClassLoader();
    451         assertNull(urlLoader.findResource("XXX")); //$NON-NLS-1$
    452     }
    453 
    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      */
    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      */
    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