/* * Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /** * @test * @bug 4167874 * @modules jdk.httpserver * @library ../../../../com/sun/net/httpserver * @library /lib/testlibrary * @build FileServerHandler jdk.testlibrary.FileUtils CompilerUtils JarUtils * @run main/othervm CloseTest * @summary URL-downloaded jar files can consume all available file descriptors */ import java.io.File; import java.io.IOException; import java.net.URL; import java.net.URLClassLoader; import java.lang.reflect.Method; import java.net.InetSocketAddress; import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardOpenOption; import java.util.stream.Stream; import com.sun.net.httpserver.HttpServer; import com.sun.net.httpserver.HttpContext; import static java.nio.file.Files.write; public class CloseTest extends Common { // // needs two jar files test1.jar and test2.jar with following structure // // com/foo/TestClass // com/foo/TestClass1 // com/foo/Resource1 // com/foo/Resource2 // // and a directory hierarchy with the same structure/contents public static final Path TEST_SRC = Paths.get(System .getProperty("test.src")); public static final Path TEST_WORK_DIR = Paths.get(System .getProperty("user.dir")); public static final Path SERVERSRC = TEST_SRC.resolve("serverRoot"); public static final Path TEST1 = TEST_SRC.resolve("test1"); public static final Path TEST2 = TEST_SRC.resolve("test2"); public static final Path SERVER_ROOT = TEST_WORK_DIR.resolve("serverRoot"); public static final Path TEST1_DIR = TEST_WORK_DIR.resolve("test1"); public static final Path TEST2_DIR = TEST_WORK_DIR.resolve("test2"); public static final Path TEST_DIR = TEST_WORK_DIR.resolve("testdir"); public static final Path TEST1_JAR = TEST_WORK_DIR.resolve("test1.jar"); public static final Path TEST2_JAR = TEST_WORK_DIR.resolve("test2.jar"); public static final Path TEST_JAR = TEST_WORK_DIR.resolve("test.jar"); public static void main(String args[]) throws Exception { setUpTest(); startHttpServer(SERVER_ROOT.toString()); copyFile(TEST1_JAR.toFile(), TEST_JAR.toFile()); test(TEST_JAR.toString(), 1); // repeat test with different implementation // of test.jar (whose TestClass.getValue() returns 2 rm_minus_rf(TEST_JAR.toFile()); copyFile(TEST2_JAR.toFile(), TEST_JAR.toFile()); test(TEST_JAR.toString(), 2); // repeat test using a directory of files rm_minus_rf(TEST_DIR.toFile()); copyDir(TEST1_DIR.toFile(), TEST_DIR.toFile()); test(TEST1_DIR.toAbsolutePath().toString() + "/", 1); rm_minus_rf(TEST_DIR.toFile()); copyDir(TEST2_DIR.toFile(), TEST_DIR.toFile()); test(TEST_DIR.toAbsolutePath().toString() + "/", 2); getHttpServer().stop(3); } static void setUpTest() throws IOException { CompilerUtils.compile(TEST1, TEST1_DIR); CompilerUtils.compile(TEST2, TEST2_DIR); writeResourceFiles(TEST1_DIR); writeResourceFiles(TEST2_DIR); CompilerUtils.compile(SERVERSRC, SERVER_ROOT); // create jar JarUtils.createJarFile(TEST1_JAR, TEST1_DIR); JarUtils.createJarFile(TEST2_JAR, TEST2_DIR); } static void writeResourceFiles(Path path) { try { Path resource1 = path.resolve("com").resolve("foo").resolve("Resource1"); write(resource1, "Hello World".getBytes("UTF-8"), StandardOpenOption.CREATE); Path resource2 = path.resolve("com").resolve("foo").resolve("Resource2"); write(resource2, "Hello World again".getBytes("UTF-8"), StandardOpenOption.CREATE); } catch (IOException ex) { System.err.println("Write failed " + ex); } } // create a loader on jarfile (or directory), plus a http loader // load a class , then look for a resource // also load a class from http loader // then close the loader // check further new classes/resources cannot be loaded // check jar (or dir) can be deleted // check existing classes can be loaded // check boot classes can be loaded static void test(String name, int expectedValue) throws Exception { URL url = new URL("file", null, name); System.out.println(name); URL url2 = getServerURL(); System.out.println("Doing tests with URL: " + url + " and " + url2); URL[] urls = new URL[2]; urls[0] = url; urls[1] = url2; URLClassLoader loader = new URLClassLoader(urls); Class testclass = loadClass("com.foo.TestClass", loader, true); Class class2 = loadClass("Test", loader, true); // from http class2.getConstructor().newInstance(); Object test = testclass.getConstructor().newInstance(); Method method = testclass.getDeclaredMethods()[0]; // int getValue(); int res = (Integer) method.invoke(test); if (res != expectedValue) { throw new RuntimeException("wrong value from getValue() [" + res + "/" + expectedValue + "]"); } // should find /resource1 URL u1 = loader.findResource("com/foo/Resource1"); if (u1 == null) { throw new RuntimeException("can't find com/foo/Resource1 in test1.jar"); } loader.close(); // should NOT find /resource2 even though it is in jar URL u2 = loader.findResource("com/foo/Resource2"); if (u2 != null) { throw new RuntimeException("com/foo/Resource2 unexpected in test1.jar"); } // load tests loadClass("com.foo.TestClass1", loader, false); loadClass("com.foo.TestClass", loader, true); loadClass("java.sql.Array", loader, true); // now check we can delete the path rm_minus_rf(new File(name)); System.out.println(" ... OK"); } static HttpServer httpServer; static HttpServer getHttpServer() { return httpServer; } static URL getServerURL() throws Exception { int port = httpServer.getAddress().getPort(); String s = "http://127.0.0.1:" + port + "/"; return new URL(s); } static void startHttpServer(String docroot) throws Exception { httpServer = HttpServer.create(new InetSocketAddress(0), 10); HttpContext ctx = httpServer.createContext( "/", new FileServerHandler(docroot) ); httpServer.start(); } }