Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4171239
Votes 78
Synopsis File.deleteOnExit() does not work on open files (win32)
Category java:classes_io
Reported Against 1.3 , 1.2.2 , 1.3.1 , 1.4.2 , 1.2fcs , kestrel-rc2
Release Fixed
State 11-Closed, duplicate of 6357433, bug
Priority: 4-Low
Related Bugs 6357433 , 4969756 , 6474389 , 6475005 , 6541641 , 6632280 , 4894964 , 4404721 , 5086661
Submit Date 03-SEP-1998
Description
If the File.deleteOnExit method is invoked on a File  customer , 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.  --   xxxxx@xxxxx   9/3/1998





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)
======================================================================
Work Around




Make sure you close any file for which the deleteOnExit() method
was/is called.


(Review ID: 103452)
======================================================================




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)
======================================================================
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.  --   xxxxx@xxxxx   9/9/1998
--

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.
Posted Date : 2006-05-06 17:23:46.0

--

(2006-03-10) We have tested a preliminary fix for this issue and plan to fix it in dolphin (1.7).
Posted Date : 2006-05-06 17:23:46.0

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.
Posted Date : 2009-04-28 08:22:31.0
Comments
  
  Include a link with my name & email   

Submitted On 10-JAN-2000
athanas
Could you make this bug public, so more people can find it and vote for it?
It doesn't show up when I search for "deleteOnExit."
But I did get to it through some round about way.

This bug is a problem for me because I use a windows EXE that extracts
a temporary jar file from itself and then runs a java class from it.  The
java code should delete the temporary jar file when it exits, but it can't.
(And the EXE has long exited, so it can't delete the jar file either.)


Submitted On 17-AUG-2001
ccerberus
The system we are using has a multiple skin-based system, 
where each ZIP file contains an entire skin, and skin 
elements are loaded only as they are needed.  This requires 
that we keep the ZIP files open for performance issues, and 
also for management (since otherwise they would have to be 
re-opened every time a single resource is to be pulled from 
them).  

By requiring them to be explicitly closed in this way, we 
have to do a lot of bizarre hoop-jumping at shutdown, 
iterating through all of the entries in a hashtable and 
forcibly closing them, which won't even work in all cases 
since we can't always guarantee that we can intervene at 
shutdown.

With a skin-based system of this sort, a large number of 
temporary files will quickly accumulate if they are not 
allowed to delete themselves.  Fixing this bug would be a 
great improvement for us.


Submitted On 30-JAN-2002
grayrat
I think workarounds should be used in the jdk !!!
I use font.createFont(...) method. It creates a temp file 
that is never deleted... Will this be corrected in the 1.4 
version ?


Submitted On 24-FEB-2002
MKrieger
Also in JDK 1.4.0 :-(

This bug impacts javahelp - the temporary "dict_cache" 
files are not removed on windows.


Submitted On 13-SEP-2002
jamtbay
This is a different bug than the original posting.  This bug only 
affects 1.4, but not 1.3.  So it is a bug fixed, then 
reintroduced.


Submitted On 02-JUL-2003
MKrieger
Not fixed in 1.4.2 :-)


Submitted On 06-SEP-2003
ccerberus
Note to jamtbay: Yes, it is present in 1.3 as well.  This bug 
has gotten VERY old...submitted in 1998?  Must be very 
difficult to fix.


Submitted On 25-SEP-2003
CurtCox
Here are some potential work-arounds until this is fixed:
1. Track all open files.  There is no easy way to do that
short of modifying several classes in java.io.  If your app
is simple enough, and/or you are diligent, this can be done
manually.
2.  Write a custom launcher.
Normally, java.exe supplies your app with
java.io.tmpdir=whatever\
If you write your own launcher, you can reset this to
something like
java.io.tmpdir=whatever\app\
Create this directory before your app starts and delete it
after your app terminates.
http://javageeks.com/Papers/RollYourOwnJava/index.html
3. Do the same thing in a .bat file or shell script.
4. Do the same thing using an Isolate when those become
available.
http://www.jcp.org/en/jsr/detail?id=121


Submitted On 28-NOV-2003
geckojoe
Until the fix, CurtCox's idea of managing your own temp
space seems sound.
However, if re-writing the launcher seems a bit overwhelming
for changing java.io.tmpdir, then just use a vm argument
instead.
Example: java -Djava.io.tmpdir=whatever\app\


Submitted On 14-SEP-2006
Christian_Schlichtherle
By all means, this is not a bug in the Java API, it is an application bug!

Java applications must make sure they close their streams properly like this:

OutputStream out = new FileOutputStream(file);
try {
  // Do your I/O here.
} finally {
  out.close();
}

This is simple and safe. Failing to comply to this idiom may leave file descriptors (an operating system resource) open until the Java application terminates. This is a typical bug in Java which is particularly bad for long running (server) processes: The number of open file descriptors is limited on all operating systems. So a long running Java app which is not propertly closing its streams could easily drain the operating system out of file descriptors, which will affect all other applications.

Don't expect the language or the API to fix bugs in your code. Make sure you always close your streams.

Regards,
Christian


Submitted On 30-JAN-2007
awyork
It sounds like many are reliant on File.deleteOnExit actually working.  Files should explicitly deleted!  You should know when you're finished with it.  Yes, do set this flag so if the program terminates abnormally there is a chance the file is deleted.  Do not rely on the program being able to complete a shutdown though, think about a power failre or the OS terminating the process w/o warning.  File.deleteOnExit  will never be called.  


Submitted On 22-FEB-2007
DanielMAlievsky
This problem is really serious. For example, my libraries, implementing a concept of super-large file-based arrays, imply a lot of opened temporary files. Of course, there are methods allowing to close them, but it is not required operation: it may reduce performance of future accesses to the existing (super-large) array. Moreover, even closing the file does not allow to automatically delete it if it was mapped. 

It would be very good if all files, where deleteOnExit() was called, will be always automatically deleted while NORMAL application exit (not in case of low-level process termination). Now it may be difficult to ensure this for application supporting a lot of opened files, and it is impossible at all if file mapping is used and System.gc() was not called many times.


Submitted On 23-MAY-2007
srujana007
Kotesh
             I think its an application bug not an Java API problem. I executes on window and jre1.4.2 but  the file is deleted. I tested so many times. Only i made changes to the above program is

import java.io.*;

public class DeleteTest {

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

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

			System.out.println("on..........");
			tempFile.deleteOnExit();
			System.out.println("off..........");

			bout = new DbByteArrayOutputStream();
			ObjectOutputStream out = new ObjectOutputStream(bout);

			String testStr = new String("TEST STRING This is not Deleted");
			out.writeObject(testStr);
			out.flush();

			bout.writeTo(raf);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		finally{
			try{
				bout.close();
				raf.close();
			}
			catch(IOException 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);
		}
	
	}
}



Submitted On 02-OCT-2007
This bug completed 9 years and still unfixed. Congratulation for the anniversary.

Happy birthday to you.
Happy birthday to you.
Happy birthday my dear bug 4171239.
Happy birthday to you!


Submitted On 18-JAN-2008
miguel.jette
I think this is related to another bug (See 6266377), where if an exception occurs when closing a BufferedWriter that is writing to a file, the underlying stream does not release its resources correctly which means that subsequent file operations can fail unecessarily.

I seemed to have the problem happening when I closed my application and a FileInputStream was still open. It would clean it the next time I opened my application, but I REALLY didn't want that! I wanted a clean exit basically.

The resolution offered for bug 6266377 is to call System.gc() before attempting to delete the file results in the underlying streams getting cleaned up and thus the delete can succeed.

I do that when the action Exit is called basically and it works perfectly! Cheers!


Submitted On 18-JAN-2008
miguel.jette
I think this is related to another bug (See 6266377), where if an exception occurs when closing a BufferedWriter that is writing to a file, the underlying stream does not release its resources correctly which means that subsequent file operations can fail unnecessarily.

I seemed to have the problem happening when I closed my application and a FileInputStream was still open. It would clean it the next time I opened my application, but I REALLY didn't want that! I wanted a clean exit basically.

The resolution offered for bug 6266377 is to call System.gc() before attempting to delete the file results in the underlying streams getting cleaned up and thus the delete can succeed.

I do that when the action Exit is called basically and it works perfectly! Cheers!


Submitted On 03-NOV-2008
ChristophL
Wow, a 10 years old bug. Shouldn't we define it as a feature now?

Doesn't the age of this bug and many others say a lot about the quality of the java plattform? Microsoft has its patch days. What has Sun? Hollidays?

Sorry, but this is really frustrating...



PLEASE NOTE: JDK6 is formerly known as Project Mustang