JDK-4171239 : File.deleteOnExit() does not work on open files (win32)
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.io
  • Affected Version: 1.2.0,1.2.2,1.3.0,1.3.1,1.4.2
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS:
    generic,windows_98,windows_nt,windows_2000 generic,windows_98,windows_nt,windows_2000
  • CPU: generic,x86
  • Submitted: 1998-09-03
  • Updated: 2009-04-28
  • Resolved: 2009-04-28
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
If the File.deleteOnExit method is invoked on a File object, and one or more
instances of FileInputStream, FileOutputStream, or RandomAccessFile are open on
the file at the time the VM exits, then the file will not be deleted.  This
occurs only on win32, which does not allow a file to be deleted until all
streams on it have been closed.  -- mr@eng 9/3/1998


Name: skT45625			Date: 06/09/2000


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


In the code below, the line that is commented-out causes the temporary file to
not be deleted on JVM exit. If the line is uncommented, the file does get
deleted.

Possibly the garbage collection for a RandomAccessFile should close the file
just in case it was not closed. If Java had destructors, the destructor for
this class would make sure to close the RandomAccessFile.


----------
import java.io.*;

public class DeleteTest {

	private static String FILE_PREFIX = "inet";
	private File tempFile;
	private RandomAccessFile raf;

	public DeleteTest() {
		try {
	
			tempFile = File.createTempFile(FILE_PREFIX, null);
			System.out.println("TEMPFILE = " +
tempFile.getAbsolutePath());
			raf = new RandomAccessFile(tempFile, "rw");
			
			tempFile.deleteOnExit();
			
			DbByteArrayOutputStream bout = new
DbByteArrayOutputStream();
			ObjectOutputStream out = new ObjectOutputStream(bout);

			String testStr = new String("TEST STRING");
			out.writeObject(testStr);
			out.flush();

			bout.writeTo(raf);
			bout.close();
			
			//raf.close();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


	public static void main(String args[]) {
		DeleteTest app = new DeleteTest();
	}


	public class DbByteArrayOutputStream extends ByteArrayOutputStream {
	
		public DbByteArrayOutputStream() {
			super();
		}
		
		public DbByteArrayOutputStream(int size) {
			super(size);
		}
		
		public synchronized void writeTo(DataOutput dstr) throws
IOException {
			byte[] data = super.buf;
			int len = super.size();
			dstr.write(data, 0, len);
		}
	
	}
}
(Review ID: 105968)
======================================================================

Comments
EVALUATION Our best hope for a solution to this issue is to open files with the FILE_SHARE_DELETE sharing option. The new file system API, introduced by JSR-203/NIO2, does this by default (with the option of using platform/Windows specific options to configure the sharing mode otherwise). Changing the sharing mode after 12+ years could potentially break existing applications that rely on the current behavior. This needs careful consideration. Changing the sharing mode is tracked by 6357433. Note that this doesn't address the issue of applications trying to delete files that are mapped into memory. This is just not possible on Windows and cannot be fixed in the JDK.
28-04-2009

EVALUATION -- (2006-03-10) We have tested a preliminary fix for this issue and plan to fix it in dolphin (1.7).
10-03-2006

EVALUATION -- The shutdown hooks execute before the registered exit functions so one potential approach is for FIS/FOS/RAF to track all open & closes. Then in a shutdown hook close the open streams before the registered function to remove the file or directory executes.
12-10-2005

WORK AROUND Name: tb29552 Date: 04/11/2000 Make sure you close any file for which the deleteOnExit() method was/is called. (Review ID: 103452) ====================================================================== Name: skT45625 Date: 06/09/2000 Must open and close the RandomAccessFile each time we need to access it. Cannot just open it in a constructor and leave it open. (Review ID: 105968) ======================================================================
25-09-2004

SUGGESTED FIX Keep track of open file descriptors, and have the delete-on-exit hook close them all before it tries to delete anything. -- mr@eng 9/9/1998
09-09-1998

EVALUATION Too risky to fix for 1.2fcs. Suggested fix probably requires a JVM change. Lowering priority to 4 since we've found an alternative fix for the immediate problem of temporary zip files not being deleted. -- mr@eng 9/9/1998
09-09-1998