3

I use java.lang.ExceptionInInitializerError to rethrow caught exceptions in static initialisation blocks. I noticed it is not possible to construct with both a message and a cause; only one or the other.

  1. Is there a good reason why?
  2. What alternatives can you suggest for rethrowing checked exceptions as unchecked exceptions from a static init block? Ex: Rethrow as java.lang.RuntimeException which allows both message and cause.

UPDATE: Clarified #2 and added sample code.

public class Sample {

    private static final String _FILE_PATH = "blah/blah/blah";

    static {
        try {
            FileReader in = new FileReader(new File(_FILE_PATH));
        }
        catch (FileNotFoundException e) {
            // Option A: Without context message
            throw new ExceptionInInitializerError(e);
            // Option B: With context message
            String msg = String.format("Failed to open file for reading: '%s'", _FILE_PATH);
            throw new RuntimeException(msg, e);
        }
    }
}

Ref: Why doesn't Java allow to throw a checked exception from static initialization block?

Community
  • 1
  • 1
kevinarpe
  • 20,319
  • 26
  • 127
  • 154
  • The current example might be a little bit contrived, but a more common use case might be to extract a native library to the file system and then calling `System.load(...)`. In that case the extraction code could throw an (checked) IOException. – Marcono1234 Jan 10 '21 at 18:23

3 Answers3

1

As documented here, there is a constructor ExceptionInInitializerError(Throwable thrown), which you probably should be using instead: it conforms to standard exception chaining, which preserves the stack trace and does other useful stuff (see a sample chained-exception output).

Edit

As noted in this answer to the question you linked to: it is forbidden to allow a checked exception to fall out of a static block; unchecked exceptions are fine, but cannot be caught anywhere, unless one is doing manual dynamic class-loading with Class.forName (very uncommon).

This translates to "good luck catching anything you throw in a static initializer". Basically, whatever exception you construct and throw, it won't be much use.

Community
  • 1
  • 1
1

You want to throw an exception with both a message (that you write) and the exception itself. I like to do the same, providing context for the error and the exception. I would throw an Exception (or an instance of an Exception class that extends Exception or a sub class), not RuntimeException since you probably want the exception to be checked. Right?

Generally speaking you should throw checked excpetions in cases where your system could potentially recover (at a higher level) from an exception and runtime exceptions (unchecked) when the system cannot. (James Gosling's view)

CBass
  • 983
  • 6
  • 11
  • 1
    My question is specific to static init blocks. Please address this point. It is not possible to throw checked exceptions from static init blocks. – kevinarpe May 07 '13 at 04:27
  • I'm sorry. Misread your comment. Specifically within a static init block, you should throw a RuntimeException (or a derived exception). This is consistent with my answer in that in theory an exception occurring during initialization means the system has not been fully initialized, and therefore is not in a position to recover from said error. – CBass May 07 '13 at 13:37
0

It's an Error. Generally errors are what an application shouldn't even try to catch and recover from.

As for why it doesn't have a constructor with both the message and cause, it's probably because the developers of that class didn't deem it necessary since the main purpose of that class is to let you know "oops shit happened bro, can't recover..."

Personally I think that one of those is enough to identify the error.

Thihara
  • 7,031
  • 2
  • 29
  • 56