Skip to main content

APIzation: Replication Package

[Q#1410951][A#1410961] How does Java's System.exit() work with try/catch/finally blocks?

https://stackoverflow.com/q/1410951

I'm aware of headaches that involve returning in try/catch/finally blocks - cases where the return in the finally is always the return for the method, even if a return in a try or catch block should be the one executed. However, does the same apply to System.exit()? For example, if I have a try block: If there are no exceptions, which System.exit() will be called? If the exit was a return statement, then the line System.exit(1) would always (?) be called. However, I'm not sure if exit behaves differently than return. The code is in an extreme case that is very difficult, if not impossible, to reproduce, so I can't write a unit test. I'm going to try to run an experiment later today, if I get a few free minutes, but I'm curious anyway, and perhaps someone on SO knows the answer and can provide it before or in case I can't run an experiment.

Answer

https://stackoverflow.com/a/1410961

No. System.exit(0) doesn't return, and the finally block is not executed. System.exit(int) can throw a SecurityException. If that happens, the finally block will be executed. And since the same principal is calling the same method from the same code base, another SecurityException is likely to be thrown from the second call. Here's an example of the second case:

APIzation

import java.security.Permission;

public class Main
{

  public static void main(String... argv)
    throws Exception
  {
    System.setSecurityManager(new SecurityManager() {

      @Override
      public void checkPermission(Permission perm)
      {
        /* Allow everything else. */
      }

      @Override
      public void checkExit(int status)
      {
        /* Don't allow exit with any status code. */
        throw new SecurityException();
      }

    });
    System.err.println("I'm dying!");
    try {
      System.exit(0);
    } finally {
      System.err.println("I'm not dead yet!");
      System.exit(1);
    }
  }

}
package com.stackoverflow.api;

import java.security.Permission;

public class Human1410961 {

  public static void systemExitTryCatchFinally() throws Exception {
    System.setSecurityManager(
      new SecurityManager() {
        @Override
        public void checkPermission(Permission perm) {
          /* Allow everything else. */
        }

        @Override
        public void checkExit(int status) {
          /* Don't allow exit with any status code. */
          throw new SecurityException();
        }
      }
    );
    System.err.println("I'm dying!");
    try {
      System.exit(0);
    } finally {
      System.err.println("I'm not dead yet!");
      System.exit(1);
    }
  }
}

package com.stackoverflow.api;

import java.security.Permission;

/**
 * How does Java's System.exit() work with try/catch/finally blocks?
 *
 * @author APIzator
 * @see <a href="https://stackoverflow.com/a/1410961">https://stackoverflow.com/a/1410961</a>
 */
public class APIzator1410961 {

  public static void block() throws Exception {
    System.setSecurityManager(
      new SecurityManager() {
        @Override
        public void checkPermission(Permission perm) {
          /* Allow everything else. */
        }

        @Override
        public void checkExit(int status) {
          /* Don't allow exit with any status code. */
          throw new SecurityException();
        }
      }
    );
    System.err.println("I'm dying!");
    try {
      System.exit(0);
    } finally {
      System.err.println("I'm not dead yet!");
      System.exit(1);
    }
  }
}