|
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();
}
}
}
}
=======================================================================