Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

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 defeat 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())

This noncompliant code example throws undeclared checked exceptions. The undeclaredThrow() method takes a Throwable argument and invokes a function that will throw the argument without declaring it. Although undeclaredThrow() catches any exceptions the function declares that it might throw, it nevertheless throws the argument it is given without regard to whether the argument is one of the declared exceptions. This noncompliant code example also violates ERR07-J. Do not throw RuntimeException, Exception, or Throwable. However, because of exception ERR08-J-EX0, it does not violate ERR08-J. Do not catch NullPointerException or any of its ancestors.
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 ERR07-J. Do not throw RuntimeException, Exception, or Throwable. It falls under EX0 of ERR08-J. Do not catch NullPointerException or any of its ancestors.:

Code Block
bgColor#FFcccc

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 {
      // nextNext 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) { /* unreachableUnreachable */
    } catch (IllegalAccessException e) { /* unreachableUnreachable */
    } 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"));
  }
}

Noncompliant Code Example (Class.newInstance() Workarounds)

When the programmer wishes to catch and handle the possible undeclared checked exceptions, the compiler refuses to believe that any can be thrown in the particular context. 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
bgColor#FFcccc

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 {
      // forwardForward 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
bgColor#ccccff

public static synchronized void undeclaredThrow(Throwable throwable) {
  // These exceptions should not be passed
  if (throwable instanceof IllegalAccessException ||
      throwable instanceof InstantiationException) ||{
    throwable// instanceofUnchecked, NoSuchMethodExceptionno ||
    throwable instanceof InvocationTargetException) {declaration required
    throw new IllegalArgumentException(); // Unchecked, no declaration required
  }

  NewInstance.throwable = throwable;
  try {
    Constructor constructor =
        NewInstance.class.getConstructor( new Class<?>[0] );
    constructor.newInstance();
  } catch (InstantiationException e) { /* unreachable */
  } catch (NoSuchMethodException e) { /* unreachable *Unreachable */
  } catch (IllegalAccessException e) { /* unreachableUnreachable */
  } catch (InvocationTargetException e) {
    System.out.println("Exception thrown: "
        + e.getCause().toString());
  } finally { // Avoid memory leak
    NewInstance.throwable = null;
  }
}

Noncompliant Code Example (sun.misc.Unsafe)

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 approach works only when permitted by the current security manager (which would violate rule ENV04ENV03-J. Do not grant ReflectPermission with target suppressAccessChecksdangerous combinations of permissions). Given access to Unsafe, a call program can throw an undeclared checked exception by calling the Unsafe.throwException() method.

Code Block
bgColor#FFcccc

import java.io.IOException;
import java.lang.reflect.Field;
import sun.misc.Unsafe;

public class UnsafeCode {
  public static void main(String[] args)
      throws SecurityException, NoSuchFieldException,
             IllegalArgumentException, IllegalAccessException {
    Field f = Unsafe.class.getDeclaredField("theUnsafe");
    f.setAccessible(true);
    Unsafe u = (Unsafe) f.get(null);
    u.throwException(new IOException("No need to declare this checked exception"));
  }
}

Noncompliant Code Example (Generic Exception)

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
bgColor#FFcccc

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();
  }
}

Noncompliant Code Example (Thread.stop(Throwable))

...

According to the Java API \ [[API 2006|AA. Bibliography#API 06]\API 2014], class {{Thread}}:

Wiki Markup\[{{Thread.stop()}}\] may be used to generate exceptions that its target thread is unprepared to handle (including checked exceptions that the thread could not possibly throw, were it not for this method). For example, the following method is behaviorally identical to Java's throw operation, but circumvents the compiler's attempts to guarantee that the calling method has declared all of the checked exceptions that it may ] This method was originally designed to force a thread to stop and throw a given Throwable as an exception. It was inherently unsafe (see Thread.stop() for details), and furthermore could be used to generate exceptions that the target thread was not prepared to handle.

For example, the following method is behaviorally identical to Java's throw operation but circumvents the compiler's attempts to guarantee that the calling method has declared all of the checked exceptions that it may throw.

Code Block
bgColor#FFcccc

static void sneakyThrow(Throwable t) {
  Thread.currentThread().stop(t);
}

Note that the Thread.stop() is methods are deprecated, so this code also violates MET02-J. Do not use deprecated or obsolete classes or methods.

Noncompliant Code Example (Bytecode Manipulation)

Wiki MarkupIt 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 the class is used \ [[Roubtsov 2003|AA. Bibliography#Roubtsov 03]\]. Compiling against a class that declares the checked exception and supplying at runtime a class that lacks the declaration also suffices. Similarly, a compiler other than {{javac}} might handle checked exceptions differently. Undeclared checked exceptions can also be produced through crafted use of the {{can also result in undeclared checked exceptions. Undeclared checked exceptions can also be produced through crafted use of the sun.corba.Bridge}} class. All of these methods are strongly discouragedpractices are violations of this rule.

Risk Assessment

Failure to document undeclared checked exceptions can result in checked exceptions that the caller is unprepared to handle, consequently violating the safety property.

Recommendation Rule

Severity

Likelihood

Remediation Cost

Priority

Level

ERR10ERR06-J

low Low

unlikely Unlikely

high High

P1

L3

Related Vulnerabilities

...

Related Guidelines

...

[[MITRE 2009

AA. Bibliography#MITRE 09]]

CWE

[CWE-703http://cwe.mitre.org/data/definitions/703.html] ", Improper Check or Handling of Exceptional Conditions" ]]></ac:plain-text-body></ac:structured-macro>

 

CWE-248 ", Uncaught Exception"

Bibliography

[API 2014]Thread.stop(Throwable)

[Bloch 2008

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="e0253494-0a32-4a1f-91b8-8fa277be1be7"><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="59648251-26cf-4e11-ba5d-e6ddb6dd7a5a"><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="ae029d56-6ef4-405d-ab49-a9c2e8f04727"><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="4a6cedde-14f4-43a5-a939-98573c6343ce"><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="5c792b92-3cc2-457d-8613-7b930e0e0643"><ac:plain-text-body><![CDATA[

[[Schwarz 2004

AA. Bibliography#Schwarz 04]]

 

]]></ac:plain-text-body></ac:structured-macro>

Builder When Faced with Many Constructor Parameters"

[Goetz 2004b]

 

[JLS 2015]

Chapter 11, "Exceptions"

[Roubtsov 2003]

 

[Schwarz 2004]

 

[Venners 2003]

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="1a989acb-3873-4a09-8034-647d15e06f87"><ac:plain-text-body><![CDATA[

[[Venners 2003

AA. Bibliography#Venners 03]]

"Scalability of Checked Exceptions"

]]></ac:plain-text-body></ac:structured-macro>

 

...

Image Added Image Added Image Added

 Image Removed      06. Exceptional Behavior (ERR)      Image Removed