8

I have a number of temporary files that I call deleteOnExit() on. I also have a runnable that I register with addShutdownHook() to run when System.exit is called.

Is there any guarantee that the temporary files will still be available when my shutdown hook runs?

Tamara Koliada
  • 1,200
  • 2
  • 14
  • 31
Klitos Kyriacou
  • 10,634
  • 2
  • 38
  • 70
  • 2
    I'm not sure whether it's guaranteed by any spec but [that's the way OpenJDK (and hence the Oracle JDK) does it](http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7-b147/java/io/DeleteOnExitHook.java#DeleteOnExitHook) - the deleteOnExit hook runs after normal shutdown hooks. – Ian Roberts Mar 10 '15 at 17:47
  • 1
    There is a [bug report about implementing deleteOnExit with shutdown hooks](https://bugs.openjdk.java.net/browse/JDK-4809375). According to [this comment](https://bugs.openjdk.java.net/browse/JDK-4809375?focusedCommentId=12139894&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-12139894) deleteOnExit should be run after the shutdown hooks have executed – Tunaki Mar 10 '15 at 17:49
  • I'm sure you could make a case that no Java code in that JVM should see that the deletion has occurred. – user207421 Mar 10 '15 at 17:58
  • 1
    I'm sure that you can make the case that it isn't specified anywhere, and therefore that your code shouldn't rely on any ordering. – user207421 Feb 19 '19 at 09:19

1 Answers1

-1

When we look at the underneath implementations, both are dealing with Shutdown-Hook.

  1. When we deal with addShutdownHook (ApplicationShutdownHooks), we have a piece of code like below in our code.

    Runtime.getRuntime().addShutdownHook(new Thread() {
          public void run() { 
                <<---Do the Implementations here--->>
          }
        });
    

Internally inside Java Source Code ApplicationShutdownHooks are implemented as below and called from Runtime class as mentioned in this link http://www.docjar.com/html/api/java/lang/Runtime.java.html

class ApplicationShutdownHooks {
    /* The set of registered hooks */
    private static IdentityHashMap<Thread, Thread> hooks;
    static {
        try {
            Shutdown.add(1 /* shutdown hook invocation order */,
                false /* not registered if shutdown in progress */,
                new Runnable() {
                    public void run() {
                        runHooks();
                    }
                }
            );
  1. Whereas when we deal with File.deleteOnExit(), Java internally registers for a shutdown as below.

            // DeleteOnExitHook must be the last shutdown hook to be invoked.
            // Application shutdown hooks may add the first file to the
            // delete on exit list and cause the DeleteOnExitHook to be
            // registered during shutdown in progress. So set the
            // registerShutdownInProgress parameter to true.
            sun.misc.SharedSecrets.getJavaLangAccess()
                .registerShutdownHook(2 /* Shutdown hook invocation order */,
                    true /* register even if shutdown in progress */,
                    new Runnable() {
                        public void run() {
                           runHooks();
                        }
                    }
            );
    

    Note: Above piece of Code that registers the hook can be found in JavaSourceCode as below: http://hg.openjdk.java.net/icedtea/jdk7/jdk/file/10672183380a/src/share/classes/java/io/DeleteOnExitHook.java http://hg.openjdk.java.net/icedtea/jdk7/jdk/file/10672183380a/src/share/classes/java/io/File.java

If Shutdown Hook runs fine, we will have all the files cleared off from System. However there is no guarantee that Shutdown Hooks runs fine everytime. There are some rare scenrios as well for which you can refer the below links:

ApplicationShutdownHooks : https://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html#addShutdownHook (java.lang.Thread)

deleteOnExit: https://docs.oracle.com/javase/7/docs/api/java/io/File.html#deleteOnExit()

And More specifically, we should use ApplicationShutdownHooks rather than deleteOnExit() because deleteOnExit() uses a lot of memory that will not be released until the JVM terminates.

Note: Also since deleteOnExit(), applies to File instances and not Path, we also need to convert the Path to a File by calling the method as below:

Path path = FileSystems.getDefault.getPath(".");
File asFile = path.toFile();
asFile.deleteOnExit();
Anandaraja_Srinivasan
  • 568
  • 1
  • 10
  • 25