JDK-4167874 : URL-downloaded jar files can consume all available file descriptors
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 1.2.0,1.3.0,1.4.2_04,6
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic,windows_xp
  • CPU: generic,x86
  • Submitted: 1998-08-20
  • Updated: 2017-05-16
  • Resolved: 2011-03-08
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 7
7 b48Fixed
Related Reports
Duplicate :  
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
The JarFile objects created by sun.net.www.protocol.jar.JarFileFactory never get garbage collected, even if the classloader that loaded them goes away.  Since each one has an open file descriptor, if an RMI application or server loads classes from enough different jar codebases over time, the process runs out of file descriptors on Solaris, even if the classes have long since been garbage collected.


Name: boT120536			Date: 05/20/2001


java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0)
Java HotSpot(TM) Client VM (build 1.3.0, mixed mode)

When JarURLConnections to entries inside a JarFile are opened, the jarfile is
cached, even when caching is explicitly turned off.

Under Win32 systems, this has the side-effect that the file can no longer be
modified (e.g. deleted). Under Linux this only results in filedescriptors being
kept open as can be seen with 'lsof'.

The source below reproduces this problem, assuming that there is a jarfile
called 'localfile.jar'.

--- BEGIN SOURCE ---import java.io.File;
import java.io.InputStream;
 
import java.net.URL;
import java.net.URLConnection;
 
/**
 * This class shows the caching bug in JarURLConnection
 *
 * @author ###@###.###
 */
public class JarURLConnectionTestCase
{
    /**
     * This method opens a local file, opens a non-caching
     * URLConnection, opens a Stream on that connection, closes the
     * stream and tries to delete the file.
     *
     * On Win32 systems, this will cause an exception because the file
     * is still referenced by the URLConnection-cache
     */
    public static void main(String[] args)
        throws Exception
    {
        URL entryURL
            = new URL("jar:file:localfile.jar!/META-INF/MANIFEST.MF");
        URLConnection connection = entryURL.openConnection();
 
        // BUG: turn off caching; this does NOT work
        connection.setUseCaches(false);
 
        // open and close a stream
        InputStream stream = connection.getInputStream();// causes the caching
        stream.close();
 
        // now delete the file. This fails, because the connection
        // keeps a cache-reference
        File file = new File("localfile.jar");
        System.err.println("Attempting to delete localfile.jar");
        if (!file.delete()) {
            System.err.println("Deletion failed, bug exists!");
        }
    }
}
--- END SOURCE ---

According to our profiler, the caching happens in
sun.net.www.protocol.jar.JarFileFactory:80
(Review ID: 124469)
======================================================================

Comments
EVALUATION This will be fixed very soon in jdk7 (next few weeks).
27-01-2009

PUBLIC COMMENTS The JarFile objects created by sun.net.www.protocol.jar.JarFileFactory never get garbage collected, even if the classloader that loaded them goes away. Since each one has an open file descriptor, if an RMI application or server loads classes from enough different jar codebases over time, the process runs out of file descriptors on Solaris, even if the classes have long since been garbage collected.
10-06-2004

EVALUATION This has been fixed some time ago. Call setUseCaches(false) to turn off caching. ###@###.### 2001-11-13 We probably should think about adding an API to URLConnection to switch off/on particular caching. setDefaultUseCaches(false) switches off caching for all types of connections.
13-11-2001

WORK AROUND use getJarFile() then call JarFile.close() after you are done with the particular JarFile. --------------------- This is probably a bad idea. I suspect this will cause major breakage. See the evaluation. jeff.nisewanger@Eng 1998-10-26
26-10-1998