# HG changeset patch # User michaelm # Date 1294916490 0 # Node ID 3af394bb6f5974108b68891c8601e35e4d30be43 # Parent f273c0d04215c2642aaa87a3a963d86606356487 6896088: URLClassLoader.close() apparently not working for JAR URLs on Windows Reviewed-by: chegar diff -r f273c0d04215 -r 3af394bb6f59 jdk/src/share/classes/sun/misc/URLClassPath.java --- a/jdk/src/share/classes/sun/misc/URLClassPath.java Wed Jan 12 14:40:36 2011 +0000 +++ b/jdk/src/share/classes/sun/misc/URLClassPath.java Thu Jan 13 11:01:30 2011 +0000 @@ -466,6 +466,7 @@ */ private static class Loader implements Closeable { private final URL base; + private JarFile jarfile; // if this points to a jar file /* * Creates a new Loader for the specified URL. @@ -530,6 +531,17 @@ } uc = url.openConnection(); InputStream in = uc.getInputStream(); + if (uc instanceof JarURLConnection) { + /* JarURLConnection.getInputStream() returns a separate + * instance on each call. So we have to close this here. + * The jar file cache will keep the file open. + * Also, need to remember the jar file so it can be closed + * in a hurry. + */ + JarURLConnection juc = (JarURLConnection)uc; + jarfile = juc.getJarFile(); + in.close(); + } } catch (Exception e) { return null; } @@ -559,7 +571,11 @@ * close this loader and release all resources * method overridden in sub-classes */ - public void close () throws IOException {} + public void close () throws IOException { + if (jarfile != null) { + jarfile.close(); + } + } /* * Returns the local class path for this loader, or null if none. diff -r f273c0d04215 -r 3af394bb6f59 jdk/test/java/net/URLClassLoader/B6896088.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/jdk/test/java/net/URLClassLoader/B6896088.java Thu Jan 13 11:01:30 2011 +0000 @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2011, 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 6896088 + * @run main/othervm B6896088 + * @summary URLClassLoader.close() apparently not working for JAR URLs on Windows + */ + +import java.net.*; +import java.io.*; +import java.nio.file.Path; + +public class B6896088 { + + public static void main(String[] args) throws Exception { + + String dir = System.getProperty ("test.classes"); + File jarf = new File (dir, "foo.jar"); + FileOutputStream fos = new FileOutputStream (jarf); + fos.write(bytes(nums)); + fos.close(); + + // Create URL using JAR protocol + String jarName = (jarf.toURI()).toString(); + URL url = new URL("jar", "", jarName + "!/"); + + // Create URLClassLoader from the URL + URLClassLoader loader = new URLClassLoader(new URL[]{url}); + Class c = loader.loadClass("Foo"); + + // Close the URLClassLoader so we can delete/update the jar file + loader.close(); + + // Now try to delete the jar file + + if (jarf.delete() && !jarf.exists()) { + System.out.println(jarf.getName()+" File Deleted"); + } else { + System.out.println(jarf.getName()+" File Not Deleted"); + throw new RuntimeException ("File not deleted"); + } + } + + static byte[] bytes (int[] i) { + byte[] buf = new byte [i.length]; + + for (int j=0; j