Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Java's System.exit() work with try/catch/finally blocks? [duplicate]

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:

try {
    //Code
    System.exit(0)
}
catch (Exception ex) {
    //Log the exception
}
finally {
    System.exit(1)
}

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.

like image 821
Thomas Owens Avatar asked Sep 11 '09 13:09

Thomas Owens


People also ask

What happens if Write System exit () will finally block executes?

Yes, the finally block will be executed even after a return statement in a method. The finally block will always execute even an exception occurred or not in Java. If we call the System. exit() method explicitly in the finally block then only it will not be executed.

What will happen if you put System exit () on try or catch block will finally block execute?

It will not execute finally block. The program will be terminated after System. exit() statement.

What happens if you put return statement System exit () in try catch block?

If the catch block completes normally, then the finally block is executed. Since you are calling System. exit which terminate the program within the try block then try-catch does not complete normally thus finally block wont get executed.

Will finally block executed if we give System Exit 0 in TRY block?

exit(0) gets called without any exception then finally won't execute. However if any exception occurs while calling System. exit(0) then finally block will be executed.


4 Answers

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:

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);
    }
  }

}
like image 199
erickson Avatar answered Sep 30 '22 06:09

erickson


Simple tests including catch too reveal that if system.exit(0) does not throw a security exception, it will be the last executed statement (catch and finally are not executed at all).

If system.exit(0) does throw a security exception, catch and finally statements are executed. If both catch and finally contain system.exit() statements, only statements preceding these system.exit() statements are executed.

In both cases decribed above, if the try code belongs to a method called by another method, the called method does not return.

More details here (personal blog).

like image 26
Jérôme Verstrynge Avatar answered Sep 30 '22 05:09

Jérôme Verstrynge


Other answers have covered how the catch and finally blocks don't run if System.exit exits the JVM without throwing a SecurityException, but they don't show what happens in a "try-with-resources" block to the resources: Are they closed?

According to the JLS, Section 14.20.3.2:

The effect of the translation is to put the resource specification "inside" the try statement. This allows a catch clause of an extended try-with-resources statement to catch an exception due to the automatic initialization or closing of any resource.

Furthermore, all resources will have been closed (or attempted to be closed) by the time the finally block is executed, in keeping with the intent of the finally keyword.

That is, resources will be closed before a catch or finally block runs. What if they are closed somehow even if catch and finally don't run?

Here's some code to demonstrate that the resources in a "try-with-resources" statement aren't closed either.

I use a simple subclass of BufferedReader that prints a statement before calling super.close.

class TestBufferedReader extends BufferedReader {
    public TestBufferedReader(Reader r) {
        super(r);
    }

    @Override
    public void close() throws IOException {
        System.out.println("close!");
        super.close();
    }
}

Then I set up the test case of calling System.exit in the try-with-resources statement.

public static void main(String[] args)
{
    try (BufferedReader reader = new TestBufferedReader(new InputStreamReader(System.in)))
    {
        System.out.println("In try");
        System.exit(0);
    }
    catch (Exception e)
    {
        System.out.println("Exception of type " + e.getClass().getName() + " caught: " + e.getMessage());
    }
    finally
    {
        System.out.println("finally!");
    }
}

Output:

In try

Therefore, not only do catch and finally blocks not run, a "try-with-resources" statement won't get a chance to close its resources if System.exit succeeds.

like image 8
rgettman Avatar answered Sep 30 '22 06:09

rgettman


finally block will be executed no matter what....even if try block throws any throwable(exception or error).....

only case finally block does not execute...is when we call System.exit() method..

try{
    System.out.println("I am in try block");
    System.exit(1);
} catch(Exception ex){
    ex.printStackTrace();
} finally {
    System.out.println("I am in finally block!!!");
}

It will not execute finally block. The program will be terminated after System.exit() statement.

like image 4
Chinmoy Avatar answered Sep 30 '22 05:09

Chinmoy