Path: blob/master/test/jdk/java/net/URLClassLoader/RemoveJar.java
41149 views
/*1* Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25* @bug 826404826*27* @run main/othervm RemoveJar true true testpkg.Test testpkg.Test testjar/28* @run main/othervm RemoveJar true true testpkg.Test testpkg.Missing testjar/29* @run main/othervm RemoveJar true true testpkg.Missing testpkg.Test testjar/30* @run main/othervm RemoveJar true true testpkg.Missing testpkg.Missing testjar/31*32* @run main/othervm RemoveJar true false testpkg.Test testpkg.Test testjar/33* @run main/othervm RemoveJar true false testpkg.Test testpkg.Missing testjar/34* @run main/othervm RemoveJar true false testpkg.Missing testpkg.Test testjar/35* @run main/othervm RemoveJar true false testpkg.Missing testpkg.Missing testjar/36*37* @run main/othervm RemoveJar false true testpkg.Test testpkg.Test testjar/38* @run main/othervm RemoveJar false true testpkg.Test testpkg.Missing testjar/39* @run main/othervm RemoveJar false true testpkg.Missing testpkg.Test testjar/40* @run main/othervm RemoveJar false true testpkg.Missing testpkg.Missing testjar/41*42* @run main/othervm RemoveJar false false testpkg.Test testpkg.Test testjar/43* @run main/othervm RemoveJar false false testpkg.Test testpkg.Missing testjar/44* @run main/othervm RemoveJar false false testpkg.Missing testpkg.Test testjar/45* @run main/othervm RemoveJar false false testpkg.Missing testpkg.Missing testjar/46*47* @run main/othervm RemoveJar true true testpkg.Test testpkg.Test badpath48*49* @summary URLClassLoader.close() doesn't close cached JAR file on Windows when load() fails50*/5152import java.io.ByteArrayOutputStream;53import java.io.IOException;54import java.io.PrintStream;55import java.io.UncheckedIOException;56import java.net.URL;57import java.net.URLClassLoader;58import java.net.URLConnection;59import java.nio.file.Files;60import java.nio.file.Path;61import java.nio.file.Paths;62import java.util.Arrays;63import java.util.stream.Stream;64import java.util.zip.ZipException;65import java.util.spi.ToolProvider;6667public class RemoveJar {68private final static String TEST_PKG = "testpkg";69private final static String JAR_DIR = "testjar/" + TEST_PKG;70private final static String FILE_NAME = "testjar.jar";71private final static ByteArrayOutputStream baos = new ByteArrayOutputStream();72private final static PrintStream out = new PrintStream(baos);73private final static ToolProvider JAR_TOOL = ToolProvider.findFirst("jar")74.orElseThrow(() ->75new RuntimeException("jar tool not found")76);7778private static void buildJar() throws IOException {79// create dir80mkdir(JAR_DIR);81// create file82Path path = Paths.get(JAR_DIR);83String src = "package " + TEST_PKG + ";\n" +84"class Test {}\n";85Files.write(Paths.get(JAR_DIR + "/Test.java"), src.getBytes());86// compile class87compile(JAR_DIR + "/Test.java");88// package jar89jar("-cf testjar.jar " + JAR_DIR);90}9192public static void main(String args[]) throws Exception {93buildJar();9495URLClassLoader loader = null;96URL url = null;97Path path = Paths.get(FILE_NAME);9899boolean useCacheFirst = Boolean.parseBoolean(args[0]);100boolean useCacheSecond = Boolean.parseBoolean(args[1]);101String firstClass = args[2];102String secondClass = args[3];103String subPath = args[4];104105try {106String path_str = path.toUri().toURL().toString();107URLConnection.setDefaultUseCaches("jar", useCacheFirst);108109url = new URL("jar", "", path_str + "!/" + subPath);110loader = new URLClassLoader(new URL[]{url});111112loader.loadClass(firstClass);113} catch (Exception e) {114System.err.println("EXCEPTION: " + e);115}116117try {118URLConnection.setDefaultUseCaches("jar", useCacheSecond);119loader.loadClass(secondClass);120} catch (Exception e) {121System.err.println("EXCEPTION: " + e);122} finally {123loader.close();124Files.delete(path);125}126}127128private static Stream<Path> mkpath(String... args) {129return Arrays.stream(args).map(d -> Paths.get(".", d.split("/")));130}131132private static void mkdir(String cmdline) {133System.out.println("mkdir -p " + cmdline);134mkpath(cmdline.split(" +")).forEach(p -> {135try {136Files.createDirectories(p);137} catch (IOException x) {138throw new UncheckedIOException(x);139}140});141}142143private static void jar(String cmdline) throws IOException {144System.out.println("jar " + cmdline);145baos.reset();146147// the run method catches IOExceptions, we need to expose them148ByteArrayOutputStream baes = new ByteArrayOutputStream();149PrintStream err = new PrintStream(baes);150PrintStream saveErr = System.err;151System.setErr(err);152int rc = JAR_TOOL.run(out, err, cmdline.split(" +"));153System.setErr(saveErr);154if (rc != 0) {155String s = baes.toString();156if (s.startsWith("java.util.zip.ZipException: duplicate entry: ")) {157throw new ZipException(s);158}159throw new IOException(s);160}161}162163/* run javac <args> */164private static void compile(String... args) {165if (com.sun.tools.javac.Main.compile(args) != 0) {166throw new RuntimeException("javac failed: args=" + Arrays.toString(args));167}168}169}170171172173