Java requires that each method must address every checked exception that can be thrown during its execution either by handling the exception within a try-catch
block or by declaring that the exception can propagate out of the method (via the throws
clause). Unfortunately, there are a few techniques that permit undeclared checked exceptions to be thrown at runtime. Such techniques foil the ability of caller methods to use the throws
clause to determine the complete set of checked exceptions that could propagate from an invoked method. Consequently such techniques must not be used to throw undeclared checked exceptions.
Noncompliant Code Example (
...
Class.newInstance()
)
Any checked exception thrown by the default constructor of java.lang.Class.newInstance()
is propagated to the caller, even though Class.newInstance()
declares that it throws only InstantiationException
and IllegalAccessException
. This noncompliant code example demonstrates one way to use Class.newInstance()
to throw arbitrary checked and unchecked exceptions.
This noncompliant code example also violates rule ERR07-J. Do not throw RuntimeException, Exception, or Throwable. It falls under EX0 of However, because of exception EX0, it does not violate rule ERR08-J. Do not catch NullPointerException or any of its ancestors.
Code Block | ||
---|---|---|
| ||
public class NewInstance { private static Throwable throwable; private NewInstance() throws Throwable { throw throwable; } public static synchronized void undeclaredThrow(Throwable throwable) { // These exceptions should not be passed if (throwable instanceof IllegalAccessException || throwable instanceof InstantiationException) { // Unchecked, no declaration required throw new IllegalArgumentException(); // Unchecked, no declaration required } NewInstance.throwable = throwable; try { // next line throws the Throwable argument passed in above, // even though the throws clause of class.newInstance fails // to declare that this may happen NewInstance.class.newInstance(); } catch (InstantiationException e) { /* unreachable */ } catch (IllegalAccessException e) { /* unreachable */ } finally { // Avoid memory leak NewInstance.throwable = null; } } } public class UndeclaredException { public static void main(String[] args) { // No declared checked exceptions NewInstance.undeclaredThrow( new Exception("Any checked exception")); } } |
...
This noncompliant code example attempts to catch undeclared checked exceptions thrown by Class.newInstance()
. It catches Exception
and dynamically checks whether the caught exception is an instance of the possible checked exception (carefully rethrowing all other exceptions, of course), as shown below.
Code Block | ||
---|---|---|
| ||
public static void main(String[] args) {
try {
NewInstance.undeclaredThrow(
new IOException("Any checked exception"));
} catch (Throwable e) {
if (e instanceof IOException) {
System.out.println("IOException occurred");
} else if (e instanceof RuntimeException) {
throw (RuntimeException) e;
} else {
// forward to handler
}
}
}
|
Compliant Solution (
...
Constructor.newInstance()
)
This compliant solution uses java.lang.reflect.Constructor.newInstance()
rather than Class.newInstance()
. The Constructor.newInstance()
method wraps any exceptions thrown from within the constructor into a checked exception called InvocationTargetException
.
Code Block | ||
---|---|---|
| ||
public static synchronized void undeclaredThrow(Throwable throwable) { // These exceptions should not be passed if (throwable instanceof IllegalAccessException || throwable instanceof InstantiationException || throwable instanceof NoSuchMethodException || throwable instanceof InvocationTargetException) { throw new IllegalArgumentException(); // Unchecked, no declaration required throw new IllegalArgumentException(); } NewInstance.throwable = throwable; try { Constructor constructor = NewInstance.class.getConstructor( new Class<?>[0] ); constructor.newInstance(); } catch (InstantiationException e) { /* unreachable */ } catch (NoSuchMethodException e) { /* unreachable */ } catch (IllegalAccessException e) { /* unreachable */ } catch (InvocationTargetException e) { System.out.println("Exception thrown: " + e.getCause().toString()); } finally { // Avoid memory leak NewInstance.throwable = null; } } |
...
This noncompliant code example is insecure both because it can throw undeclared checked exceptions and also because it uses the sun.misc.Unsafe
class. All sun.*
classes are unsupported and undocumented because their use can cause portability and backward compatibility issues.
Classes that are loaded by the bootstrap class loader have the permissions needed to call the static
factory method Unsafe.getUnsafe()
. Arranging to have an arbitrary class loaded by the bootstrap class loader without modifying the sun.boot.class.path
system property can be difficult. However, an alternative way to gain access is to change the accessibility of the field that holds an instance of Unsafe
through the use of reflection. This works only when permitted by the current security manager (which would violate rule ENV03-J. Do not grant dangerous combinations of permissions). Given access to Unsafe
, a call program can throw an undeclared checked exception by calling the Unsafe.throwException()
method.
...
An unchecked cast of a generic type with parametrized parameterized exception declaration can also result in unexpected checked exceptions. Any attempt to do so is All such casts are diagnosed by the compiler , unless the warnings are suppressed.
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(); } } |
...
Note that Thread.stop()
is deprecated, so this code also violates rule MET02-J. Do not use deprecated or obsolete classes or methods.
...
Related Guidelines
CWE-703, ". Improper Check check or Handling of Exceptional Conditions" handling of exceptional conditions | |
| CWE-248, ". Uncaught Exception" exception |
Bibliography
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="ca76f9d9b775e6c4-a32e29c2-4d0e47e2-b06bb4e4-3fd86addc362bec60a28123c"><ac:plain-text-body><![CDATA[ | [[Bloch 2008 | AA. Bibliography#Bloch 08]] | Item 2: ". Consider a builder when faced with many constructor parameters " | ]]></ac:plain-text-body></ac:structured-macro> |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="9a8e8a822ff0a79e-10192e5a-45274d82-9fe8b6ae-7aff51df178151e0917a7dd5"><ac:plain-text-body><![CDATA[ | [[Goetz 2004b | AA. Bibliography#Goetz 04b]] |
| ]]></ac:plain-text-body></ac:structured-macro> |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="90c5e61614f4f8c1-4423c673-41d14d84-b3b69065-3e99f2793ec7638714c737fc"><ac:plain-text-body><![CDATA[ | [[JLS 2005 | AA. Bibliography#JLS 05]] | Chapter 11: , Exceptions | ]]></ac:plain-text-body></ac:structured-macro> |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="de958f8f6a0d6101-4bb52f39-44634671-afce8402-a65c2d0838f0320882f9f371"><ac:plain-text-body><![CDATA[ | [[Roubtsov 2003 | AA. Bibliography#Roubtsov 03]] |
| ]]></ac:plain-text-body></ac:structured-macro> |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="43fa069bdbd554e6-fc766595-49d24d55-a2d8b263-7abdff5fd15feda21c416a96"><ac:plain-text-body><![CDATA[ | [[Schwarz 2004 | AA. Bibliography#Schwarz 04]] |
| ]]></ac:plain-text-body></ac:structured-macro> |
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="100dcb4a9f96bac7-2edce5ac-483e47b9-a5c9878c-c7194612f51579ae04dd5033"><ac:plain-text-body><![CDATA[ | [[Venners 2003 | AA. Bibliography#Venners 03]] | " Scalability of Checked Exceptions " | ]]></ac:plain-text-body></ac:structured-macro> |
...