1 /*
   2  * Copyright (c) 2009, 2013, 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  * @library ../../../../com/sun/net/httpserver
  28  * @library /lib/testlibrary
  29  * @build jdk.testlibrary.* FileServerHandler
  30  * @run shell build.sh
  31  * @run main/othervm CloseTest
  32  * @summary URL-downloaded jar files can consume all available file descriptors
  33  */
  34 
  35 import java.io.*;
  36 import java.net.*;
  37 import java.lang.reflect.*;
  38 import com.sun.net.httpserver.*;
  39 
  40 public class CloseTest extends Common {
  41 
  42 //
  43 // needs two jar files test1.jar and test2.jar with following structure
  44 //
  45 // com/foo/TestClass
  46 // com/foo/TestClass1
  47 // com/foo/Resource1
  48 // com/foo/Resource2
  49 //
  50 // and a directory hierarchy with the same structure/contents
  51 
  52     public static void main (String args[]) throws Exception {
  53 
  54         String workdir = System.getProperty("test.classes");
  55         if (workdir == null) {
  56             workdir = args[0];
  57         }
  58         if (!workdir.endsWith("/")) {
  59             workdir = workdir+"/";
  60         }
  61 
  62         startHttpServer (workdir+"serverRoot/");
  63 
  64         String testjar = workdir + "test.jar";
  65         copyFile (workdir+"test1.jar", testjar);
  66         test (testjar, 1);
  67 
  68         // repeat test with different implementation
  69         // of test.jar (whose TestClass.getValue() returns 2
  70 
  71         copyFile (workdir+"test2.jar", testjar);
  72         test (testjar, 2);
  73 
  74         // repeat test using a directory of files
  75         String testdir=workdir+"testdir/";
  76         rm_minus_rf (new File(testdir));
  77         copyDir (workdir+"test1/", testdir);
  78         test (testdir, 1);
  79 
  80         testdir=workdir+"testdir/";
  81         rm_minus_rf (new File(testdir));
  82         copyDir (workdir+"test2/", testdir);
  83         test (testdir, 2);
  84         getHttpServer().stop (3);
  85     }
  86 
  87     // create a loader on jarfile (or directory), plus a http loader
  88     // load a class , then look for a resource
  89     // also load a class from http loader
  90     // then close the loader
  91     // check further new classes/resources cannot be loaded
  92     // check jar (or dir) can be deleted
  93     // check existing classes can be loaded
  94     // check boot classes can be loaded
  95 
  96     static void test (String name, int expectedValue) throws Exception {
  97         URL url = new URL ("file", null, name);
  98         URL url2 = getServerURL();
  99         System.out.println ("Doing tests with URL: " + url + " and " + url2);
 100         URL[] urls = new URL[2];
 101         urls[0] =  url;
 102         urls[1] =  url2;
 103         URLClassLoader loader = new URLClassLoader (urls);
 104         Class testclass = loadClass ("com.foo.TestClass", loader, true);
 105         Class class2 = loadClass ("Test", loader, true); // from http
 106         class2.newInstance();
 107         Object test = testclass.newInstance();
 108         Method method = testclass.getDeclaredMethods()[0]; // int getValue();
 109         int res = (Integer) method.invoke (test);
 110 
 111         if (res != expectedValue) {
 112             throw new RuntimeException ("wrong value from getValue() ["+res+
 113                         "/"+expectedValue+"]");
 114         }
 115 
 116         // should find /resource1
 117         URL u1 = loader.findResource ("com/foo/Resource1");
 118         if (u1 == null) {
 119             throw new RuntimeException ("can't find com/foo/Resource1 in test1.jar");
 120         }
 121         loader.close ();
 122 
 123         // should NOT find /resource2 even though it is in jar
 124         URL u2 = loader.findResource ("com/foo/Resource2");
 125         if (u2 != null) {
 126             throw new RuntimeException ("com/foo/Resource2 unexpected in test1.jar");
 127         }
 128 
 129         // load tests
 130         loadClass ("com.foo.TestClass1", loader, false);
 131         loadClass ("com.foo.TestClass", loader, true);
 132         loadClass ("java.sql.Array", loader, true);
 133 
 134         // now check we can delete the path
 135         rm_minus_rf (new File(name));
 136         System.out.println (" ... OK");
 137     }
 138 
 139     static HttpServer httpServer;
 140 
 141     static HttpServer getHttpServer() {
 142         return httpServer;
 143     }
 144 
 145     static URL getServerURL () throws Exception {
 146         int port = httpServer.getAddress().getPort();
 147         String s = "http://127.0.0.1:"+port+"/";
 148         return new URL(s);
 149     }
 150 
 151     static void startHttpServer (String docroot) throws Exception {
 152         httpServer = HttpServer.create (new InetSocketAddress(0), 10);
 153         HttpContext ctx = httpServer.createContext (
 154                 "/", new FileServerHandler(docroot)
 155         );
 156         httpServer.start();
 157     }
 158 }