United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-5041014 : URLClassLoader.getResourceAsStream locks jar files

Details
Type:
Bug
Submit Date:
2004-05-01
Status:
Closed
Updated Date:
2010-07-05
Project Name:
JDK
Resolved Date:
2010-07-05
Component:
core-libs
OS:
windows_xp
Sub-Component:
java.net
CPU:
x86
Priority:
P2
Resolution:
Won't Fix
Affected Versions:
1.4.2,1.4.2_04
Fixed Versions:
7

Related Reports
Relates:
Relates:
Relates:

Sub Tasks

Description
To reproduce the problem, on a Windows machine, create a test.jar, and run the following test case in jdb.  Stop at the first println, "test.jar" is now locked and cannot be deleted.

Note that the test is only trying to get a non-existant resource.  Note also that this is only a problem for the Windows platform.

This bug breaks an important functionality in AppServer, because it makes undeployment of a web applications impossible (in Windows), because jar files in it cannot be deleted.  See bug 5004315.  There does not seems to be any workarounds.

% cat Test.java
import java.io.*;
import java.net.*;

class Test {
    public static void main(String args[]) {

        try {
            File jarf = (new File("test.jar")).getCanonicalFile();
            URL urls[] = { jarf.toURL() };
            URLClassLoader loader =
                new URLClassLoader(urls, Test.class.getClassLoader());
            InputStream is = loader.getResourceAsStream("BadName");
            System.out.println("stream is " + is);
        } catch (Exception ex) {
            System.out.println("Error: " + ex);
        }
    }
}


###@###.### 2004-04-30

                                    

Comments
EVALUATION

URLClassLoader now has a close() method, which is designed to address this problem.
                                     
2010-07-05
EVALUATION

Looks like the creation of a JarFile would retain a lock to the file. I don't know whether that's the correct behaviour. Reassigning to the T&L team for further evaluation.

###@###.### 2004-05-06

While a jar file is opened, a file descriptor to the file is maintained,
so that the file does not have to be continually reopened.
This is important for good performance of the JVM.

Note that this is business as usual for Windows applications.
You cannot replace any supporting files in a Windows application that are in
use, by design.  An operation like replacing a dll typically requires a reboot
on Windows.  You can make an argument for both ways of doing things, but
Java certainly cannot change the way Windows works.

I will likely close this as Will Not Fix.

###@###.### 2004-05-06

The general problem of a program's supporting files being replaced is
a known problem.  Windows chooses to lock such files, while Unix
permits it, at the cost of possibly causing JVM crashes when a zip
file being used is replaced unexpectedly.

The standard workaround, if you *really* want replaceability, is to
always make a defensive copy of the jar file containing the contents
you want before opening it.  You might not want to pay the cost of
that, however.  We are very unlikely to want to copy rt.jar every time
`java' is invoked.

###@###.### 2004-05-11

5098318 also has to make sure sure JCE tries to clean up everything to allow for 
GC'ing/unloading correctly.  Having a close() would make things easier.

###@###.### 2005-05-26 00:22:38 GMT
###@###.### 2005-05-26 00:52:07 GMT
                                     
2005-05-26
SUGGESTED FIX

The bug seems to be in sun.misc.URLClassPath$Loader.findResource.  In it URL.openConnection() is invoked, but the stream for the connection is not closed.
                                     
2004-06-11



Hardware and Software, Engineered to Work Together