Java deleteOnExit and addShutdownHook - which comes first?
Asked Answered
H

1

9

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?

Heteronomy answered 10/3, 2015 at 17:39 Comment(4)
I'm not sure whether it's guaranteed by any spec but that's the way OpenJDK (and hence the Oracle JDK) does it - the deleteOnExit hook runs after normal shutdown hooks.Collation
There is a bug report about implementing deleteOnExit with shutdown hooks. According to this comment deleteOnExit should be run after the shutdown hooks have executedWineskin
I'm sure you could make a case that no Java code in that JVM should see that the deletion has occurred.Kruse
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.Kruse
B
-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();
Bawcock answered 16/2, 2019 at 11:57 Comment(3)
Which version of Java does it like that? I've looked at OpenJDK 6, 7, 8 and 11 and they all use a special-purpose DeleteOnExitHook rather than Runtime.addShutdownHook().Heteronomy
I meant to say like both deals with ShutDownHooks internally. Updated my answer for better clarity.Bawcock
Looking at underlying implementations doesn't constitute a guarantee.Kruse

© 2022 - 2024 — McMap. All rights reserved.