1 /*
   2  * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 4167874
  27  * @modules java.logging
  28  *          jdk.httpserver
  29  * @library ../../../../com/sun/net/httpserver
  30  * @library /lib/testlibrary
  31  * @build FileServerHandler jdk.testlibrary.FileUtils
  32  * @run shell build.sh
  33  * @run main/othervm CloseTest
  34  * @summary URL-downloaded jar files can consume all available file descriptors
  35  */
  36 
  37 import java.io.File;
  38 import java.lang.reflect.Method;
  39 import java.net.URLClassLoader;
  40 import java.net.InetSocketAddress;
  41 import java.net.URL;
  42 import com.sun.net.httpserver.HttpContext;
  43 import com.sun.net.httpserver.HttpServer;
  44 
  45 public class CloseTest extends Common {
  46 
  47 //
  48 // needs two jar files test1.jar and test2.jar with following structure
  49 //
  50 // com/foo/TestClass
  51 // com/foo/TestClass1
  52 // com/foo/Resource1
  53 // com/foo/Resource2
  54 //
  55 // and a directory hierarchy with the same structure/contents
  56 
  57     public static void main (String args[]) throws Exception {
  58 
  59         String workdir = System.getProperty("test.classes");
  60         if (workdir == null) {
  61             workdir = args[0];
  62         }
  63         if (!workdir.endsWith("/")) {
  64             workdir = workdir+"/";
  65         }
  66 
  67         startHttpServer (workdir+"serverRoot/");
  68 
  69         String testjar = workdir + "test.jar";
  70         copyFile (workdir+"test1.jar", testjar);
  71         test (testjar, 1);
  72 
  73         // repeat test with different implementation
  74         // of test.jar (whose TestClass.getValue() returns 2
  75 
  76         copyFile (workdir+"test2.jar", testjar);
  77         test (testjar, 2);
  78 
  79         // repeat test using a directory of files
  80         String testdir=workdir+"testdir/";
  81         rm_minus_rf (new File(testdir));
  82         copyDir (workdir+"test1/", testdir);
  83         test (testdir, 1);
  84 
  85         testdir=workdir+"testdir/";
  86         rm_minus_rf (new File(testdir));
  87         copyDir (workdir+"test2/", testdir);
  88         test (testdir, 2);
  89         getHttpServer().stop (3);
  90     }
  91 
  92     // create a loader on jarfile (or directory), plus a http loader
  93     // load a class , then look for a resource
  94     // also load a class from http loader
  95     // then close the loader
  96     // check further new classes/resources cannot be loaded
  97     // check jar (or dir) can be deleted
  98     // check existing classes can be loaded
  99     // check boot classes can be loaded
 100 
 101     static void test (String name, int expectedValue) throws Exception {
 102         URL url = new URL ("file", null, name);
 103         URL url2 = getServerURL();
 104         System.out.println ("Doing tests with URL: " + url + " and " + url2);
 105         URL[] urls = new URL[2];
 106         urls[0] =  url;
 107         urls[1] =  url2;
 108         URLClassLoader loader = new URLClassLoader (urls);
 109         Class testclass = loadClass ("com.foo.TestClass", loader, true);
 110         Class class2 = loadClass ("Test", loader, true); // from http
 111         class2.newInstance();
 112         Object test = testclass.newInstance();
 113         Method method = testclass.getDeclaredMethods()[0]; // int getValue();
 114         int res = (Integer) method.invoke (test);
 115 
 116         if (res != expectedValue) {
 117             throw new RuntimeException ("wrong value from getValue() ["+res+
 118                         "/"+expectedValue+"]");
 119         }
 120 
 121         // should find /resource1
 122         URL u1 = loader.findResource ("com/foo/Resource1");
 123         if (u1 == null) {
 124             throw new RuntimeException ("can't find com/foo/Resource1 in test1.jar");
 125         }
 126         loader.close ();
 127 
 128         // should NOT find /resource2 even though it is in jar
 129         URL u2 = loader.findResource ("com/foo/Resource2");
 130         if (u2 != null) {
 131             throw new RuntimeException ("com/foo/Resource2 unexpected in test1.jar");
 132         }
 133 
 134         // load tests
 135         loadClass ("com.foo.TestClass1", loader, false);
 136         loadClass ("com.foo.TestClass", loader, true);
 137         loadClass ("java.util.ArrayList", loader, true);
 138 
 139         // now check we can delete the path
 140         rm_minus_rf (new File(name));
 141         System.out.println (" ... OK");
 142     }
 143 
 144     static HttpServer httpServer;
 145 
 146     static HttpServer getHttpServer() {
 147         return httpServer;
 148     }
 149 
 150     static URL getServerURL () throws Exception {
 151         int port = httpServer.getAddress().getPort();
 152         String s = "http://127.0.0.1:"+port+"/";
 153         return new URL(s);
 154     }
 155 
 156     static void startHttpServer (String docroot) throws Exception {
 157         httpServer = HttpServer.create (new InetSocketAddress(0), 10);
 158         HttpContext ctx = httpServer.createContext (
 159                 "/", new FileServerHandler(docroot)
 160         );
 161         httpServer.start();
 162     }
 163 }