Search code examples
javaspringtomcatjbossshutdown

java - Proper way to cleanup temp files in spring/tomcat/jboss libraries


I have a library that creates a few temp files in java.io.tempdir while it is running. First question is whether linux/centos ever auto-deletes a tempfile in /tmp while it is open. Hope not!

Second question, I want to make sure my tempfiles are automatically cleaned up when the JVM quits or is aborted. File.deleteOnExit is not an option because in general my tempfiles are deleted when the client of the library closes his "stream". They are very ephemeral files, and in proper use, there will never be any clutter, but there could be crashes and other causes for my temp files not being deleted.

The first idea is that the best way to do this is to create my own uniquely named folder (with a random portion of the name) within /tmp and create all my temp files within this folder, rather than using File.createTempFile. Then I register a shutdown hook, and knowing the path of the folder used by my vm instance, I iterate this folder on shutdown and delete all the files in it, and then delete the folder.

This would seem to work on linux, based on the fact that you can delete open files, but there is no guarantee with my library that the clients of the temp file streams will have closed all their streams before the shutdown hook is called, so on windows the files would not be deleted. That's a problem.

Also, some containers may not allow shutdown hooks, and even if they do, there is no absolute guarantee that the shutdown hook is called.

What I wish for is some reliable way to clean up garbage my library created on startup such that this approach will work for several JVMs running on the same machine.


Solution

  • I have a library that creates a few temp files in java.io.tempdir while it is running. First question is whether linux/centos ever auto-deletes a tempfile in /tmp while it is open. Hope not!

    This depends on whether there are cleanup scripts running. But on UN*X machines, this doesn't matter, since the JVM will hold the open file-descriptor - this allows it to be read/written until it is closed. Once it's closed the filesystem will release the space automatically.

    Second question, I want to make sure my tempfiles are automatically cleaned up when the JVM quits or is aborted. File.deleteOnExit is not an option because in general my tempfiles are deleted when the client of the library closes his "stream". They are very ephemeral files, and in proper use, there will never be any clutter, but there could be crashes and other causes for my temp files not being deleted.

    A common trick under UN*X servers is to open the file and then use File.remove() to remove the entry from the filesystem, while still being able to read/write to it. If the JVM crashes or exits normally, the space is automatically released and there are no trash temp-files on the filesystem. With Windows, it is a bit more problematic, and you may need to implement periodic sweeps that attempts File.remove() [ignoring failures].