When to catch java.lang.Error?
Generally, never.
However, sometimes you need to catch specific errors.
If you're writing framework-ish code (loading 3rd party classes), it might be wise to catch LinkageError
(no class def found, unsatisfied link, incompatible class change).
I've also seen some stupid 3rd-party code throwing subclasses of Error
, so you'll have to handle those as well.
By the way, I'm not sure it isn't possible to recover from OutOfMemoryError
.
Catching all java.lang.Error for logging purposes and allowing them to work their way up the stack
You said: "I tried this..."
} catch (Throwable e) {
e.printStackTrace();
throw e;
}
You should try instead:
} catch (Error e) {
e.printStackTrace();
throw e;
}
Errors are not checked exceptions. You don't have to declare them in any method signature. Just put that in your outermost method and it will do what you want.
Edit:
If you want to also catch and rethrow Exception, let's think about it. You have three kinds of Throwable: Error, Exception and RuntimeException. Error and RuntimeException are not checked, but Exception which are not RuntimeException are.
So, you can do the same thing for RuntimeException as we do for Error:
} catch (RuntimeException e) {
e.printStackTrace();
throw e;
} catch (Error e) {
e.printStackTrace();
throw e;
}
And what about Exception who are not RuntimeException? The thing to understand is that these are checked exceptions and if they are not declared in the methods that the code is calling, then they will not be thrown. So you don't need to catch/rethrow them. If some of the methods called actually throw such an exception, then you will have to catch/rethrow it and mark your method as throwing that exception, but you would have to do that anyway since they are coming from methods the outer method is calling.
Catching Java errors
Other than giving advice on how to technically overcome the problem, I'd like to take a moment and explain why it's considered "bad practice" in the first place.
Let's start off by clarifying what the Error
class is.
In java, errors and exceptions (which are the main types) are thrown. Throwing one of the above is done by using the throw
keyword. Every class which extends the basic java.lang.Throwable
can be thrown.
There are two classes which inherit from the basic Throwable
class: Exception
and Error
. The difference between those two is explained in their documentations:
An Error is a subclass of Throwable that indicates serious
problems that a reasonable application should not try to catch. Most
such errors are abnormal conditions. [...]
Source
The class Exception and its subclasses are a form of Throwable
that indicates conditions that a reasonable application might want
to catch.
Source
As explained above, errors and exceptions are separated because of their different origins. An Error
normally indicates a problem, which the application can not recover from. Therefore, they should not be caught.
The same is true for a RuntimeException
, but it is used to indicate a problem with a high-level layer (e.g. methods). Whereas the Error
indicates a low-level problem (e.g. the runtime).
So, now that you understood that you shall only catch exceptions and errors which you are able to recover from, the answer to your question should be clear.
Yes, it's perfectly reasonable to catch the UnsatisfiedLinkError
, because your application can recover from it.
I covered the above (in more detail and with examples) and some extended information in an article on my Blog.
Is it appropriate to catch java.lang.ExceptionInInitializerError in multi-threaded application?
It is only appropriate to catch this error if you are going to print an error message and then immediately terminate the application.
The problem is that the class whose initialization has failed will be permanently stuck, as will any other class whose initialization depends on the class. This will lead to more exceptions whenever something attempts to use one of these classes.
The only possibility of fixing this is if all of the affected classes are loaded via a child classloader ... that can be abandoned / replaced with a new one. This is possible in theory, but often impossible in practice.
My recommendation would be NOT do the initialization in a static initializer if you anticipate that the initialization may fail due to something that the user does. Instead, do the initialization explicitly; e.g. using lazy initialization the first time that a Singleton getInstance
method is called.
Why is the Catch(Exception) almost always a bad Idea?
Because when you catch exception you're supposed to handle it properly. And you cannot expect to handle all kind of exceptions in your code. Also when you catch all exceptions, you may get an exception that cannot deal with and prevent code that is upper in the stack to handle it properly.
The general principal is to catch the most specific type you can.
Related Topics
How to Know If Other Threads Have Finished
Remove Diacritical Marks (Ń Ǹ Ň ñ Ṅ Ņ Ṇ Ṋ Ṉ ̈ Ɲ Ƞ ᶇ ɳ ȵ) from Unicode Chars
How to Supply Value to an Annotation from a Constant Java
How to Read a Specific Line Using the Specific Line Number from a File in Java
Java - Method Name Collision in Interface Implementation
Get a Resource Using Getresource()
How to Check If the User Is Pressing a Key
How to Decrypt File in Java Encrypted with Openssl Command Using Aes
How to Get the Exact Middle of a Screen, Even When Re-Sized
How to Convert a Stack Trace to a String
Handling Parenthesis While Converting Infix Expressions to Postfix Expressions
The Case Against Checked Exceptions
What Are the Differences Between the Different Saving Methods in Hibernate
Ignoring New Fields on JSON Objects Using Jackson
Why Would You Ever Implement Finalize()