ExceptionInInitializerError is unrecoverable

by Martin Monperrus, Benoit Cornu
Java exception ExceptionInInitializerError, is an exception that wraps an exception thrown and not caught from a static block (i.e. an exception in an initializer) as follows:

public class StaticException1 {
  public static void main(String[] args) {
    new Obj();
  }
}

class Obj {
  static {
    if (1 == 1 + 0) {  // tricking the compiler
      throw new RuntimeException();
    }
  }
}
This results in

Exception in thread "main" java.lang.ExceptionInInitializerError
	at StaticException1.main(StaticException1.java:3)
Caused by: java.lang.RuntimeException
	at Obj.(StaticException1.java:10)
	... 1 more

Catching ExceptionInInitializerError

ExceptionInInitializerError is an error, but as all errors it can be caught using an appropriate catch catch(ExceptionInInitializerError e), catch(Error e) or catch(Throwable t).
public class StaticException2 {
  public static void main(String[] args) {
    try {
      new Obj2();
    } catch (ExceptionInInitializerError e) {
      System.err.println("caught in a static block "+e.getCause());
      // do something
    }
    System.out.println("going ahead");
  }
}

class Obj2 {
  static {
    if (1 == 1 + 0) { // tricking the compiler
      throw new RuntimeException();
    }
  }
}

Recovering from ExceptionInInitializerError

Although ExceptionInInitializerError can be caught, it is actually impossible to recover from it, because the class in which the exception occured is made unavailable for further use (such as instantiating the class), yielding a NoClassDefFoundError.

public class StaticException2 {
  public static void main(String[] args) {
    try {
      new Obj2();
    } catch (ExceptionInInitializerError e) {
      System.err.println("caught in a static block "+e.getCause());
      // do something
    }
     
    ////////////////////////
    // using Obj2 again
    new Obj2();
  }
}

class Obj2 {
  static {
    if (1 == 1 + 0) { // tricking the compiler
      throw new RuntimeException();
    }
  }
}

caught in a static block java.lang.RuntimeException
Exception in thread "main" java.lang.NoClassDefFoundError: Could not initialize class Obj2
	at StaticException2.main(StaticException2.java:12)


Consequently, ExceptionInInitializerError is actually unrecoverable, and it is a hard contract that static blocks never throw exceptions.

Open question: one may play with the class loader to overcome this, how?
Tagged as: