Java exception not caught

Viewed 51923

Why are some exceptions in Java not caught by catch (Exception ex)? This is code is completely failing out with an unhandled exception. (Java Version 1.4).

public static void main(String[] args) {
    try {
        //Code ...
    } catch (Exception ex) {
        System.err.println("Caught Exception");
        ex.printStackTrace();
        exitCode = app.FAILURE_EXIT_CODE;
    }
    finally {
        app.shutdown();
    }
    System.exit(exitCode);
}

I get a Exception in thread "main" java.lang.NoSuchMethodError

But this works

public static void main(String[] args) {
    int exitCode = app.SUCCESS_EXIT_CODE;
    try {
        //Code ...
    } catch (java.lang.NoSuchMethodError mex){
        System.err.println("Caught NoSuchMethodError");
        mex.printStackTrace();
        exitCode = app.FAILURE_EXIT_CODE;
    } catch (Exception ex) {
        System.err.println("Caught Exception");
        ex.printStackTrace();
        exitCode = app.FAILURE_EXIT_CODE;
    }
    finally {
        app.shutdown();
    }
    System.exit(exitCode);
}

I get Caught NoSuchMethodError java.lang.NoSuchMethodError:

I thought catching exceptions would catch all exceptions? How can I catch all exceptions in java?

7 Answers

First let's clear up some unfortunate semantic confusion in this discussion. There is the java.lang.Exception class which we can refer to simply as Exception with a capital 'E'. Then you have exception with a lowercase 'e' which is a language feature. You can see the lower case version in the documentation for the Throwable class:

For the purposes of compile-time checking of exceptions, Throwable and any subclass of Throwable that is not also a subclass of either RuntimeException or Error are regarded as checked exceptions.

For me it's easier to think about the answer to this question as checked vs. unchecked exceptions (lower case e). Checked exceptions must be considered at compile time, whereas unchecked exceptions are not. Exception (uppercase E) and it's subclasses are checked exceptions, which means you either have to catch any exception that can be thrown by your code, or declare the exceptions that your method could throw (if not caught).

Error and it's subclasses are unchecked exceptions, which means your code neither has to catch an Errors that could be thrown, nor do you have to declare that you throw those Errors. RunTimeException and its subclasses are also unchecked exceptions, despite their location in the class hierarchy.

Consider the following code:

void test() {
  int a = 1, b = 0, c = a / b;
}

When run, the above code will produce a java.lang.ArithmeticException. This will compile without any errors, even though an exception is thrown and the code neither catches the ArithmeticException nor declares that it throws this exception. This is the essence of unchecked exceptions.

Consider the location of ArithmeticException in the class hierarchy, especially the fact that this is a subclass of java.lang.Exception. Here you have an exception that derives from java.lang.Exception but because it's also a subclass of java.lang.RuntimeException, it's an unchecked exception so you don't have to catch it.

java.lang.Object
  java.lang.Throwable
    java.lang.Exception
      java.lang.RuntimeException
        java.lang.ArithmeticException

If you want to catch anything that could possibly be thrown, catch a Throwable. However this may not be the safest thing to do because some of those Throwables could be fatal runtime conditions that perhaps should not be caught. Or if you do catch Throwable, you may want to re-throw Throwables that you can't deal with. It depends on the context.

Related