JDK-4722539 : File.delete() doesn't work the same between Windows & Unix
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.io
  • Affected Version: 1.4.0,6
  • Priority: P3
  • Status: Closed
  • Resolution: Won't Fix
  • OS: solaris_7,windows_xp
  • CPU: x86
  • Submitted: 2002-07-29
  • Updated: 2002-07-30
  • Resolved: 2002-07-30
Related Reports
Relates :  
Description

Name: nt126004			Date: 07/29/2002


FULL PRODUCT VERSION :
java version "1.4.0-rc"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-rc-b91)
==
java version "1.2.2"
Solaris VM (build patc.2000.05.19.09.11, native threads, sunwjit)

FULL OPERATING SYSTEM VERSION :
SunOS OOLAB10.pok.ibm.com 5.7 Generic_106541-16 sun4u sparc
SUNW,Ultra-4

ADDITIONAL OPERATING SYSTEMS :
zOS
AIX
Linux
-- all UNIX OS have this problem...


A DESCRIPTION OF THE PROBLEM :
Locking mechanism fails using delete method even when File
is in use via FileInputStream and/or ZipFile constructor.
When a java.io.File object is in use either via
FileInputStream constructor (for reading the file) or
ZipFile (for reading Zip file), delete method should be
returning false (boolean) since the File itself is
currently in use. But on UNIX JVM, it ignores that the File
is in use & simply removes it from the underlying
filesystem.

Opposite to BUG #4045014.



STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Run the sample code on Windows OS JVM.
2. Run the sample code on UNIX OS JVM.
3. Will see the difference in bahavior.

EXPECTED VERSUS ACTUAL BEHAVIOR :
On Windows JVM (either Sun's or IBM's at various versions --
 v1.1.8, v1.2.2, v1.3.x, v1.4.0),
File.delete will return false when it is in use via
FileInputStream and/or ZipFile (possibly others
as well which may open the file for use), but UNIX JVM
always returns true & deletes the
file in the underlying filesystem.

Here is a snippit of my code that would show this
difference:

            File tmpFile = File.createTempFile
("tmpFile", ".txt", tmpDir);
            FileInputStream tmpFIS = new FileInputStream
(tmpFile);        // Causes lock on File
            boolean deleted = tmpFile.delete();
            if (deleted) {
               // on zOS, this is the path that JVM takes
               System.out.println("YJY: this tmp file is
GONE!");
            }
            else {
               System.out.println("YJY: this tmp file is
being USED!");
               // on Windows, this is the path that JVM
takes
            }

Here is a sample run of Temp.java (which I will send via
FTP) from Windows:

C:\>java Temp
YJY: tmp file name is ==|C:\temp\tmpFile43838.txt|==
YJY: try to delete this puppy when FileInputStream is
holding the file!
YJY: this tmp file is being USED!
YJY: this tmpDir is NOT deleted ==|C:\temp|==
YJY: delete this tmpDir ==|C:\temp|== during shutdown...

Here is a sample run of Temp.java from zOS:

YJYOON:/u/yjyoon:>java Temp
YJY: tmp file name is ==|/u/yjyoon/temp/tmpFile20013.txt|==
YJY: try to delete this puppy when FileInputStream is
holding the file!
YJY: this tmp file is GONE!
YJY: this tmpDir is deleted ==|/u/yjyoon/temp|==
YJY: delete this tmpDir ==|/u/yjyoon/temp|== during
shutdown...

ERROR MESSAGES/STACK TRACES THAT OCCUR :
see "Expected and Actual Results" above.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.io.*;
import java.util.Properties;
import java.util.Enumeration;
import java.util.*;
import java.util.zip.*;

public class Temp {

    public static String tmpdir = System.getProperty("user.dir") +
File.separator +
                                  "temp" + File.separator;

    public static void main(String[] args) {

        File tmpDir = new File(Temp.tmpdir);
        File tmpFile = null;
        try {
            // Initially create this tmpdir if it doesn't already exist!
            if (!tmpDir.exists()) {
                tmpDir.mkdirs();
            }

            tmpFile = File.createTempFile("tmpFile", ".txt", tmpDir);
            // Check to see if the java.io.File.delete() is behaving the same
on 390 vs. Windows...
            if (tmpFile.exists()) {
                System.out.println("YJY: tmp file name is ==|" +
tmpFile.getAbsolutePath() + "|==");
//                ZipFile tmpZipFile = new ZipFile(tmpFile);
                FileInputStream tmpFIS = new FileInputStream(tmpFile);
                System.out.println("YJY: try to delete this puppy when
FileInputStream is holding the file!");
                boolean deleted = tmpFile.delete();
                if (deleted) {
                    System.out.println("YJY: this tmp file is GONE!");
                }
                else {
                    System.out.println("YJY: this tmp file is being USED!");
                }
            }
            else {
                System.out.println("YJY: where did this tmp file GO? ==|" +
tmpFile.getAbsolutePath() + "|==");
            }

            return;
        } catch (Throwable e) {
            e.printStackTrace();
        } finally {
            if (tmpDir.delete()) {
                System.out.println("YJY: this tmpDir is deleted ==|" +
tmpDir.getAbsolutePath() + "|==");
            }
            else {
                System.out.println("YJY: this tmpDir is NOT deleted ==|" +
tmpDir.getAbsolutePath() + "|==");
            }

            System.out.println("YJY: delete this tmpDir ==|" +
tmpDir.getAbsolutePath() + "|== during shutdown...");
            tmpDir.deleteOnExit();
        }
    }
}
---------- END SOURCE ----------

CUSTOMER WORKAROUND :
Currently there is no workaround for my situation.
Basically, on Windows, my application works fine using its
locking mechanism, but, on UNIX OS, this is not the case.

IF there is a way to programmatically via JDK APIs similate
the locking mechanism on underlying files, it would solve
my problem for the time being. My code initially written on
Windows OS is NOT compatible on UNIX OS. I can't write once
and run everywhere. This should be fixed to behave the same
on all platforms.
(Review ID: 159741) 
======================================================================

Comments
EVALUATION We cannot fix this, for the same reasons that we cannot fix 4045014: There's no efficient way to force Windows-style semantics on Unix, and vice-versa. This difference is annoying, but it's not a violation of WORA because the specification doesn't make any guarantees about what happens when you delete an open file. If you need to lock files, the new java.nio.channels.FileChannel API in 1.4 provides a more robust mechanism. -- ###@###.### 2002/7/30
07-10-0196