@PostConstruct & Checked exceptions
Asked Answered
F

3

41

In the @PostConstruct doc it says about the annotated methods:

"The method MUST NOT throw a checked exception."

How would one deal with e.g. an IOException which can be thrown in such a method? Just wrap it in a RuntimeException and let the user worry about the faulty initial state of the object? Or is @PostConstruct the wrong place to validate and initialize objects which got their dependencies injected?

Frustule answered 5/1, 2012 at 9:34 Comment(5)
Interesting, I hadn't noticed that. Seems like an odd restriction, given that the method is called reflectively.Offbeat
PostConstruct method is for initializing objects. Why would you put something that throws IOException in an initialize method?Maurits
@Medopal: I'm checking for the existence of DB tables in the init method of a service, which throws IOExceptionFrustule
@medopal redirecting or sending an HTTP error code also throw IOExceptionRating
Is this constraint mostly from a philosophical viewpoint as in Exception must not be thrown while initializing objects or there is a bigger practical issue attached to it? I didn't fully understand this part why PostConstruct must not throw a checked exceptionProtractile
S
52

Yes, wrap it in a runtime exception. Preferebly something more concrete like IllegalStateException.

Note that if the init method fails, normally the application won't start.

Schott answered 5/1, 2012 at 9:40 Comment(0)
U
5

Generally, if you want or expect application start-up failure when one of your beans throws an exception you can use Lombok's @SneakyThrows.

It is incredibly useful and succinct when used correctly:

@SneakyThrows
@PostConstruct
public void init() {
    // I usually throw a checked exception
}

There's a recent write-up discussing its pros and cons here: Prefer Lombok’s @SneakyThrows to rethrowing checked exceptions as RuntimeExceptions

Enjoy!

Underclay answered 11/9, 2018 at 21:17 Comment(1)
You can have similar effect without using Lombok. Assuming you throw SomeCheckedException in your init method you could write public void init() throws SomeCheckedException { and result should be the same as with Lombok @SneakyThrows.Lewan
T
0

Use a softened exception like so, in effect wrapping in RuntimeException:

private static RuntimeException softenException(Exception e) {
    return new RuntimeException("Softened exception.", e);
}

Then usage is like:

} catch (IOException e) {
        throw softenException(e);
}
Tadzhik answered 21/5, 2018 at 21:28 Comment(2)
How can this work? From what I see, you cannot just take an arbitrary exception and cast it to a RuntimeException. Sure the code will compile, but have you tried running this on the said IOException? I'm pretty sure you'll get a ClassCastException due to the fact that IOException does not inherit from RuntimeException. To truly get a RuntimeException you have to wrap the original exception in a new instance of RuntimeException or a subclass of choice.Singlehandedly
Yeah, my code doesn't work right, but hopeully the basic idea, as you can see, is possible.Tadzhik

© 2022 - 2024 — McMap. All rights reserved.