This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
This is the first time that I've felt the "need" of overriding the finalize () method. But I've doubts about the right manner of doing it, and even about if it's what I need or not.
I've written a class which needs to create one or several temporary files. These must exist until the instance is no longer needed, because certain methods require them. I could make a method which deleted every temporary file, that a program should call once that it has ended using the instance. Something like "cleanup ()".
However, taking into account that the programmer may not know about the internal operations of this class (and thus, about the need of deleting these temporary files), I had thought about overriding "finalize ()" and doing this task automatically once the instance is selected by the GC.
Which way is more convenient? The API documentation says:
... the usual purpose of finalize, however, is to perform cleanup actions before the object is irrevocably discarded
...use finalization only when it is absolutely necessary. Finalization is a nondeterministic -- and sometimes unpredictable -- process. The less you rely on it, the smaller the impact it will have on the JVM and your application. See also Joshua Bloch's book, Effective Java Programming Language Guide, chapter 2, item 6: Avoid finalizers.
But I guess in your case since you are not cleaning up scarce native resources, and just deleting temporary files, you can use finalization.
In order to properly use it you will have to make some changes in your design, so that users of your class don't get any memory retention problem, as discussed in above article (scroll down and read "Shield Users From Memory-Retention Problems" topic).
I'm sorry, but I should have been more specific. I can't rely on "deleteOnExit ()" because it's a server environment, so the JVM won't be shutdown ever (at least on "ideal circumstances"). I should have clarified this before, because it's an important matter .
Piyush Joshi: I'll take a look to that article. Thanks ;) .
I am imagining that your server allows the user to create a temporary file and then do various things with it. Perhaps it also allows the user to tell you that they are finished with the temporary file, in which case you can delete it at that time.
But of course you can't rely on the user to do that. They might go off to update their Facebook status and never come back. But if you have a session for the user, you could keep track of the temporary file (or files) in the user's session, and when it times out you could delete the temporary files at that time.
You could also put in some code to delete all of the temporary files when the web application terminates, or to clean up leftover temporary files when it starts, but in most real-life situations those events will only occur very rarely and it would be better to use some other way to manage abandoned temporary files.
Paul Clapham: Hello Paul, and thanks for your answer. I'm sorry, but forgot to answer to your message. My situation is exactly like the one which you described there: there are some rare cases that escape to my (immediate) control, in which some temporary files remain accidentally. Specially when such files are linked in some way to the user session, and it expires. Just as you mention, it's not very common that it happens, but I thought that it could be exploited maliciously and wanted to prevent it.
Solution: This is what I've done finally:
1. Just after creating the temporary file, I call the method "deleteOnExit ()". In my case it's almost useless, but at least I make sure that stopping the JVM (in the right manner) will delete every temporary file.
2. Wherever it's possible, I call the method "delete ()" manually. I've implemented cleaning methods in my classes for this task. There is not anything special about this.
3. Since the session may expire and certain temporary files are contained into it, as attributes, I've taken advantage of the javax.servlet.http.HttpSessionAttributeListener interface to make a wrapper class which detects when these files are attached and removed to/from the session. I've checked that this event is also triggered when the session expires, so it's perfect for this purpose. This is just what I needed .