JDK-8232854 : URLClassLoader.close() doesn't close cached JAR file on Windows when load() fails
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 7,8,11.0.5,14
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows
  • Submitted: 2019-10-23
  • Updated: 2021-01-12
  • Resolved: 2020-01-30
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 11 JDK 7 JDK 8
11.0.8-oracle b01Fixed 7u271Fixed 8u261Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
java.net.URLClassLoader.close() doesn't work as expected for JAR archives on 

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 }); 
       } catch (Exception e) { 
       } finally { 
           try { 
           } catch (IOException e) {