It is mandatory to handle checked exceptions in Java. The compiler enforces this rule by making sure ensuring that every possible checked exception is either declared using the throws
clause or handled within a try-catch
block. Unfortunately, this guarantee does not carry over to the JVM runtime environment, preventing the caller from determining which exceptions the callee can throw.
...
Wiki Markup |
---|
A common argument favoring undeclared checked exceptions (even unchecked exceptions) is that the caller does not have to define innumerable {{catch}} blocks for each specific checked exception that the callee can throw. Likewise, handling each exception within the callee is believed to clutter-up the code. One way to deal with this issue is to wrap the specific exceptions into a new exception, appropriate for the abstraction level. For example, a method may throw an {{IOException}} instead of specific exceptions such as {{FileNotFoundException}}. While exception handling should be as specific as possible, a compromise can be struck this way, to increase the code readability in complex systems \[[Venners 03|AA. Java References#Venners 03]\]. However, wrapping checked exceptions into a broader exception class may not provide enough context for a recovery at the top level. Unchecked exceptions and undeclared checked exceptions, on the other hand, help reduce clutter in code but are unsuitable when a client is expected to recover from an exceptional condition. |
Clients or callers are expected to know the exceptions that the underlying code can throw. For this reason, developers must sufficiently document all possible unchecked and undeclared checked exceptions. Undeclared checked exceptions are a special class of exceptions that need diligent documentation. Security critical software must almost always make this contract explicit. Yet another difficulty in dealing with them undeclared checked exceptions is that sensitive exceptions cannot be sanitized before delivery, in the absence of a dedicated exception reporter. IdeallyFor these reasons, undeclared checked exceptions should be avoided.
...
This noncompliant code example uses the sun.misc.Unsafe
class. All sun.*
classes are unsupported and undocumented because using them can cause portability and backward compatibility issues. This noncompliant code example is risky insecure from this standpoint and by from its capacity ability to throw undeclared checked exceptions.
...
Code Block | ||
---|---|---|
| ||
public class BadNewInstance { private static Throwable throwable; private BadNewInstance() throws Throwable { throw throwable; } public static synchronized void undeclaredThrow(Throwable throwable) { // These two should not be passed if (throwable instanceof IllegalAccessException || throwable instanceof InstantiationException) { throw new IllegalArgumentException(); // Unchecked, no declaration required } BadNewInstance.throwable = throwable; try { BadNewInstance.class.newInstance(); } catch (InstantiationException e) { /* dead code */ } catch (IllegalAccessException e) { /* dead code */ } finally finally {{ // Avoid memory leak BadNewInstance.throwable = null; } // Avoid} memory leak } } public class UndeclaredException { public static void main(String[] args) { // No declared checked exceptions BadNewInstance.undeclaredThrow(new Exception("Any checked exception")); } } |
...
Code Block | ||
---|---|---|
| ||
interface Thr<EXC extends Exception> {
void fn() throws EXC;
}
public class UndeclaredGen {
static void undeclaredThrow() throws RuntimeException {
@SuppressWarnings("unchecked") // Suppresses warnings
Thr<RuntimeException> thr = (Thr<RuntimeException>)(Thr)
new Thr<IOException>() {
public void fn() throws IOException {
throw new IOException();
}
};
thr.fn();
}
public static void main(String[] args) {
undeclaredThrow();
}
}
|
...
Wiki Markup |
---|
It is also possible to disassemble a class, remove any declared checked exceptions and reassemble the class so that checked exceptions are thrown at runtime when this class is used \[[Roubtsov 03|AA. Java References#Roubtsov 03]\]. Simply, compiling against a class that declares the checked exception and supplying one at runtime that doesn't, also suffices. Similarly, a different compiler than {{javac}} might handle checked exceptions differently. Yet another way to allow undeclared checked exceptions is to furtively use the {{sun.corba.Bridge}} class. All these methods are strongly discouraged. |
...