Duplicate :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
java.net.URLClassLoader.close() doesn't work as expected for JAR archives on Windows. The system resource held by URLClassLoader (i.e. JAR archive itself) is NOT released even when the class loader is closed. A similar issue has been fixed by JDK-6896088. This issue is regarded as a special case fixed by JDK-6896088, which can be observerd when close() is called during exception handling of load(). Issue reproducible in JDK 14, 11, 8 and 7. 7u131 is the oldest of these. Steps to reproduce are below. 1. Creates a arbitrary JAR file > ls Main.java Main.class > jar tvf sample.jar Main.class > ls Main.java Main.class sample.jar 2. Run the Main class. It does the following: a. Creates URLClassLoader and uses it to load a class from the JAR b. Calls close() when the Exception thrown c. Attempts to delete the JAR, but can not. > java.exe --show-version Main java 13 2019-09-17 Java(TM) SE Runtime Environment (build 13+33) Java HotSpot(TM) 64-Bit Server VM (build 13+33, mixed mode, sharing) java.nio.file.FileSystemException: sample.jar: The process cannot access the file because it is being used by another process. at java.base/sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:92) at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:103) at java.base/sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:108) at java.base/sun.nio.fs.WindowsFileSystemProvider.implDelete(WindowsFileSystemProvider.java:274) at java.base/sun.nio.fs.AbstractFileSystemProvider.delete(AbstractFileSystemProvider.java:105) at java.base/java.nio.file.Files.delete(Files.java:1145) at Main.main(Main.java:21) Test code: ======================================================================= import java.io.*; import java.net.*; import java.nio.file.*; public class Main { final static String FILE_NAME = "sample.jar"; public static void main(String args[]) { URLClassLoader loader = null; URL url = null; Path path = Paths.get(FILE_NAME); try { String path_str = path.toUri().toURL().toString(); url = new URL("jar", "", path_str + "!/" + "classes/"); loader = new URLClassLoader(new URL[] { url }); loader.loadClass("DUMMY"); } catch (Exception e) { } finally { try { loader.close(); Files.delete(path); } catch (IOException e) { e.printStackTrace(); } } } } =======================================================================