Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

This example creates a new file, outputs some text to it, and abruptly exits using Runtime.exit(). Consequently, the file may be closed without the text actually being written.

Code Block
bgColor#ffcccc

public class CreateFile {
  public static void main(String[] args)
                          throws FileNotFoundException {
    final PrintStream out =
        new PrintStream(new BufferedOutputStream(
                        new FileOutputStream("foo.txt")));
    out.println("hello");
    Runtime.getRuntime().exit(1);
  }
}

...

This solution explicitly closes the file before exiting.

Code Block
bgColor#ccccff

public class CreateFile {
  public static void main(String[] args)
                          throws FileNotFoundException {
    final PrintStream out =
    new PrintStream(new BufferedOutputStream(
        new FileOutputStream("foo.txt")));
    try {
      out.println("hello");
    } finally {
    try {
      out.close();
   } catch (IOException x) {
     // handle error
   }
    }
    Runtime.getRuntime().exit(1);
  }
}

...

This compliant solution adds a shutdown hook to close the file. This hook is invoked by Runtime.exit() and is called before the JVM is halted.

Code Block
bgColor#ccccff

public class CreateFile {
  public static void main(String[] args)
                          throws FileNotFoundException {
    final PrintStream out =
        new PrintStream(new BufferedOutputStream(
                        new FileOutputStream("foo.txt")));
    Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
        public void run() {
          out.close();
        }
    }));
    out.println("hello");
    Runtime.getRuntime().exit(1);
  }
}

...

This noncompliant code example calls Runtime.halt() instead of Runtime.exit(). The Runtime.halt() method stops the JVM without invoking any shutdown hooks; consequently the file is not properly written to or closed.

Code Block
bgColor#ffcccc

public class CreateFile {
  public static void main(String[] args)
                          throws FileNotFoundException {
    final PrintStream out =
          new PrintStream(new BufferedOutputStream(
                          new FileOutputStream("foo.txt")));
    Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
        public void run() {
          out.close();
        }
    }));
    out.println("hello");
    Runtime.getRuntime().halt(1);
  }
}

...

When a user forcefully exits a program, for example by pressing the ctrl + c keys or by using the kill command, the JVM terminates abruptly. Although this event cannot be captured, the program should nevertheless perform any mandatory cleanup operations before exiting. This noncompliant code example fails to do so.

Code Block
bgColor#FFcccc

public class InterceptExit {
  public static void main(String[] args)
                          throws FileNotFoundException {
    InputStream in = null;
    try {
      in = new FileInputStream("file");
      System.out.println("Regular code block");
      // Abrupt exit such as ctrl + c key pressed
      System.out.println("This never executes");
    } finally {
      if (in != null) {
        try {
          in.close();  // this never executes either
        } catch (IOException x) {
          // handle error
        }
      }
    }
  }
}

...

This compliant solution shows the standard method to install a hook.

Code Block
bgColor#ccccff

public class Hook {

  public static void main(String[] args) {
    try {
      final InputStream in = new FileInputStream("file");
      Runtime.getRuntime().addShutdownHook(new Thread() {
          public void run() {
            // Log shutdown and close all resources
            in.close();
          }
      });

     // ...
    } catch (IOException x) {
      // handle error
    } catch (FileNotFoundException x) {
      // handle error
    }
  }
}

...

Android Implementation Details

Although most of the code examples are not applicable to the Android platform, the principle is applicable to Android. There are a number of ways to terminate a process on Android: android.app.Activity.finish(), and the related finish... methods, android.app.Activity.moveTaskToBack(boolean flag), android.os.Process.killProcess(int pid), System.exit().

Bibliography

[API 06]

Class Runtime

[ISO/IEC TR 24772:2010]

Section 6.46, Termination Strategy [REU]