Versions Compared

Key

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

Wiki Markup Programs must not catch {{java.lang.NullPointerException}}. A {{NullPointerException}} exception thrown at runtime indicates the existence of an underlying {{null}} pointer dereference that must be fixed in the application code (see [EXP11EXP01-J. Never dereference null pointers|EXP11-J. Never dereference null pointers]). Handling the underlying null pointer dereference by catching the {{NullPointerException}} rather than fixing the underlying problem is inappropriate for several reasons. First, _avoiding_ the exception by catching {{NullPointerException}} adds significantly more performance overhead than simply adding the necessary checks \[[Bloch 2008|AA. Bibliography#Bloch 08]\]. Second, when there are multiple expressions in a {{try}} block that are capable of throwing a {{NullPointerException}}, it is difficult or impossible to determine which expression is responsible for the exception because the {{NullPointerException}} {{catch}} block handles any {{NullPointerException}} thrown from any location in the {{try}} block. Third, programs rarely remain in an expected and usable state after a {{NullPointerException}} has been thrown. Attempts to continue execution after first catching and logging (or worse, suppressing) the exception rarely Do not use a null in a case where an object is required for more information). Handling the underlying null pointer dereference by catching the NullPointerException rather than fixing the underlying problem is inappropriate for several reasons. First, catching NullPointerException adds significantly more performance overhead than simply adding the necessary null checks [Bloch 2008]. Second, when multiple expressions in a try block are capable of throwing a NullPointerException, it is difficult or impossible to determine which expression is responsible for the exception because the NullPointerException catch block handles any NullPointerException thrown from any location in the try block. Third, programs rarely remain in an expected and usable state after a NullPointerException has been thrown. Attempts to continue execution after first catching and logging (or worse, suppressing) the exception rarely succeed.

Likewise, programs must not catch RuntimeException or its ancestors , Exception, or Throwable. Few, if any, methods are capable of handling all possible runtime exceptions. When a method catches RuntimeException, it may receive exceptions unanticipated by the designer, including NullPointerException and ArrayIndexOutOfBoundsException. Many catch clauses simply log or ignore the enclosed exceptional condition and attempt to resume normal execution; this practice often violates rule ERR00-J. Do not suppress or ignore checked exceptions. Runtime exceptions often indicate bugs in the program that should be fixed by the developer , and often cause control flow vulnerabilities.

Noncompliant Code Example (NullPointerException)

This noncompliant code example defines an isName() method that takes a String argument and returns true if the given string is a valid name. A valid name is defined as two capitalized words separated by one or more spaces. Rather than checking to see whether the given string is null, the method catches NullPointerException and returns false.

Code Block
bgColor#FFcccc
languagejava#ffcccc

boolean isName(String s) {
  try {
    String names[] = s.split(" ");

    if (names.length != 2) {
      return false;
    }
    return (isCapitalized(names[0]) && isCapitalized(names[1]));
  } catch (NullPointerException e) {
    return false;
  }
}

Compliant Solution

This compliant solution explicitly checks the String argument for null rather than catching NullPointerException.:

Code Block
bgColor#ccccff

boolean isName(String s) {
  if (s == null) {
    return false;
  }
  String names[] = s.split(" ");
  if (names.length != 2) {
    return false;
  }
  return (isCapitalized(names[0]) && isCapitalized(names[1]));
}

Compliant Solution

This compliant solution performs no null check omits an explicit check for a null reference and permits a NullPointerException to be thrown.:

Code Block
bgColor#ccccff

boolean isName(String s) /* throwsThrows NullPointerException */ {
  String names[] = s.split(" ");
  if (names.length != 2) {
    return false;
  }
  return (isCapitalized(names[0]) && isCapitalized(names[1]));
}

Omitting the null check means that the program fails more quickly than if the program had returned false and lets an invoking method discover the null value. A function method that throws a NullPointerException without a null check must provide a precondition that the argument being passed to it is not null.

Noncompliant Code Example (

...

Null

...

Object Pattern)

This noncompliant code example is derived from the logging service null object design pattern described by Henney \[[Henney 2003|AA. Bibliography#Henney 03]\]. The logging service is composed of two classes: one that prints the triggering activity's details to a disk file using the {{FileLog}} class, and another that prints to the console using the {{ConsoleLog}} class. An interface, {{Log}}, defines a {{write()}} method that is implemented by the respective log classes. Method selection occurs polymorphically at runtime. The logging infrastructure is subsequently used by a {{Service}} service Null Object design pattern described by Henney [Henney 2003]. The logging service is composed of two classes: one that prints the triggering activity's details to a disk file using the FileLog class and another that prints to the console using the ConsoleLog class. An interface, Log, defines a write() method that is implemented by the respective log classes. Method selection occurs polymorphically at runtime. The logging infrastructure is subsequently used by a Service class.

Code Block
bgColor#FFcccc

public interface Log {
  void write(String messageToLog);
}

public class FileLog implements Log {
  private final FileWriter out;

  FileLog(String logFileName) throws IOException {
    out = new FileWriter(logFileName, true);
  }

  public void write(String messageToLog) {
    // writeWrite message to file
  }
}

public class ConsoleLog implements Log {
  public void write(String messageToLog) {
    System.out.println(messageToLog); // writeWrite message to console
  }
}

class Service {
  private Log log;

  Service() {
    this.log = null; // noNo logger
  }

  Service(Log log) {
    this.log = log; // setSet the specified logger
  }

  public void handle() {
    try {
      log.write("Request received and handled");
    } catch (NullPointerException npe) {
      // Ignore
    }
  }

  public static void main(String[] args) throws IOException {
    Service s = new Service(new FileLog("logfile.log"));
    s.handle();

    s = new Service(new ConsoleLog());
    s.handle();
  }
}

Each Service object must support the possibility that a Log object may be null because clients may choose not to perform logging. This noncompliant code example eliminates null checks by using a try-catch block that ignores NullPointerException.

This design choice suppresses genuine occurrences of NullPointerException in violation of ERR00-J. Do not suppress or ignore checked exceptions. It also violates the design principle that exceptions should be used only for exceptional conditions ; because ignoring a null Log object is part of the ordinary operation for of a server.

Compliant Solution (Null Object Pattern)

The null object Null Object design pattern provides an alternative to the use of explicit null checks in code. It reduces the need for explicit null checks through the use of an explicit, safe null object rather than a null reference.

This compliant solution modifies the no-argument constructor of class Service to use the do-nothing behavior provided by an additional class, Log.NULL; it leaves the other classes unchanged.

Code Block
bgColor#ccccff

public interface Log {

  public static final Log NULL = new Log() {
    public void write(String messageToLog) {
      // doDo nothing
    }
  };

  void write(String messageToLog);
}

class Service {

  private final Log log;

  Service(){
    this.log = Log.NULL;
  }

  // ...
}

Declaring the log reference final ensures that its value is assigned during initialization.

An acceptable alternative implementation uses a setter method and a getter method accessor methods to control all interaction with the reference to the current log. The setter accessor method to set a log ensures use of the null object in place of a null reference. The getter accessor method to get a log ensures that any retrieved instance is either an actual logger or a null object (but never a null reference). Instances of the Null Object null object are immutable and are inherently thread-safe. Classes that provide setter or getter methods must comply with the second exception of OBJ09-J. Defensively copy private mutable class members before returning their references.

Wiki MarkupSome system designs require returning a value from a method rather than implementing _ do-nothing _ behavior. One acceptable approach is use of an exceptional value object that throws an exception before the method returns \ [[Cunningham 1995|AA. Bibliography#Cunningham 95]\]. This approach can be a useful alternative to returning {{null}}.

In distributed environments, the null object must be passed by copy to ensure that remote systems avoid the overhead of a remote call argument evaluation on every access to the null object. Null object code for distributed environments must also implement the Serializable interface.

Code that uses this pattern must be clearly documented to ensure that security-critical messages are never discarded because the pattern has been misapplied.

Noncompliant Code Example (Division)

In this This noncompliant code example , assumes that the original version of the division() method was declared to throw only ArithmeticException. However, the caller catches a the more general Exception type (Exception) to report arithmetic problems rather than catching the specific exception ArithmeticException type (ArithmeticException). This practice is insecure risky because future changes to the method signature could add more exceptions to the list of potential exceptions the caller must handle. In this example, a newer version revision of the division() method can potentially throw IOException in addition to ArithmeticException. However, the compiler cannot tell the caller's developer that he must provide will not diagnose the lack of a corresponding handler because his existing code the invoking method already catches IOException as a result of catching Exception. Consequently, the recovery process may might be inappropriate for the specific exception type that is thrown. Furthermore, the developer has failed to anticipate that catching Exception also catches unchecked exceptions.

Code Block
bgColor#FFcccc

public class DivideException {
  public static void main(String[] args) {
division(int totalSum, int totalNumber)
    throws tryArithmeticException, IOException  {
    int average division(200, 5);
      division(200, 0); = totalSum / totalNumber;
    // DivideAdditional byoperations zero
that may   } catch (Exception e) {throw IOException...
      System.out.println("Divide by zero exception Average: " + e.getMessage(average));
    }
  }

  public static void divisionmain(int totalSum, int totalNumber) throws ArithmeticException, IOException String[] args) {
    try {
    int average  = totalSum / totalNumber;
    // Additional operations that may throw IOException...
division(200, 5);
      division(200, 0); // Divide by zero
    } catch (Exception e) {
      System.out.println("AverageDivide by zero exception : " 
 + average);
  }
}
                       + e.getMessage());
    }
  }
}

Noncompliant Code Example

This noncompliant code example attempts improvement to solve the problem by specifically catching ArithmeticException. However, it continues to catch Exception and consequently catches both unanticipated checked exceptions and also unanticipated runtime exceptions.

Code Block
bgColor#FFcccc

try {
  division(200, 5);
  division(200, 0); // Divide by zero
} catch (ArithmeticException ae) {
  throw new DivideByZeroException();
} catch (Exception e) {
  System.out.println("Exception occurred :" + e.getMessage());
}

Note that DivideByZeroException is a custom exception type that extends Exception.

Compliant Solution

This compliant solution catches only the specific anticipated exceptions (ArithmeticException and IOException). All other exceptions are permitted to propagate up the call stack.

Code Block
bgColor#ccccff

import java.io.IOException;

public class DivideException {
  public static void main(String[] args) {
    try {
      division(200, 5);
      division(200, 0); // Divide by zero
    } catch (ArithmeticException ae) {
      throw new DivideByZeroException();  // DivideByZeroException extends Exception so is checked
    } catch (IOExceptionthrow ex) new DivideByZeroException();  
    } catch (IOException ex) {
      ExceptionReporter.report(ex);
    }
  }

  public static void division(int totalSum, int totalNumber)
                              throws ArithmeticException, IOException  {
    int average  = totalSum / totalNumber;
    // Additional operations that may throw IOException...
    System.out.println("Average: "+ average);
  }
}

Note that DivideByZeroException is a custom exception type that extends Exception.

The ExceptionReporter class is documented in ERR00-J. Do not suppress or ignore checked exceptions.

Compliant Solution (Java

...

SE 7)

Java 1.SE 7 allows a single catch block to catch multiple exceptions . This allows one catch block to handle exceptions of different types, which prevents redundant code. This compliant solution catches the specific anticipated exceptions (ArithmeticException and IOException) and handles them with one catch clause. All other exceptions are permitted to propagate to the next nearest dynamically enclosing catch clause of a try statement on the stack.

Code Block
bgColor#ccccff

import java.io.IOException;

public class DivideException {
  public static void main(String[] args) {
    try {
      division(200, 5);
      division(200, 0); // Divide by zero
    } catch (ArithmeticException | IOException ex) {
      ExceptionReporter.report(ex);
    }
  }

  public static void division(int totalSum, int totalNumber)
                              throws ArithmeticException, IOException  {
    int average  = totalSum / totalNumber;
    // Additional operations that may throw IOException...
    System.out.println("Average: "+ average);
  }
}

...

Exceptions

EXC14ERR08-J-EX0: A catch block may catch all exceptions to process them before rethrowing them (filtering sensitive information from exceptions before the call stack leaves a trust boundary, for example). Refer to ERR06to ERR01-J. Do not allow exceptions to expose sensitive information, as well as and weaknesses CWE 7 and CWE 388 for more information. In such cases, a catch block should catch Throwable rather than Exception or RuntimeException.

This code sample catches all exceptions and wraps them in a custom DoSomethingException before rethrowing them.:

Code Block
bgColor#ccccff

class DoSomethingException extends Exception {
  public DoSomethingException(Throwable cause) {
    super(cause);
  }

  // otherOther methods

};

private void doSomething() throws DoSomethingException {
  try {
    // codeCode that might throw an Exception
  } catch (Throwable t) {
    throw new DoSomethingException(t);
  }
}

Exception wrapping is a common technique to safely handle unknown exceptions. For another example, see rule ERR10ERR06-J. Do not let code throw undeclared checked exceptions.

unmigratedERR08-wikiJ-markup*EXC14-EX1*: Task processing threads such as worker threads in a thread pool or the Swing event dispatch thread are permitted to catch {{RuntimeException}} when they call untrusted code through an abstraction such as {{Runnable}} \[the Runnable interface [Goetz 2006|AA. Bibliography#Goetz 06], pg. 161\, p. 161].

EXC14ERR08-J-EX2: Systems that require substantial fault tolerance or graceful degradation are permitted to catch and log general exceptions such as Throwable at appropriate levels of abstraction. For example:

  • A real-time control system that catches and logs all exceptions at the outermost layer, followed by warm-starting the system so that real-time control can continue. Such approaches are clearly justified when program termination would have safety-critical or mission-critical consequences.
  • A system that catches all exceptions that propagate out of each major subsystem, logs the exceptions for later debugging, and subsequently shuts down the failing subsystem (perhaps replacing it with a much simpler, limited-functionality version) while continuing other services.

Risk Assessment

Catching NullPointerException may mask an underlying null dereference, degrade application performance, and result in code that is hard to understand and maintain. Likewise, catching RuntimeException, Exception, or Throwable may unintentionally trap other exception types and prevent them from being handled properly.

Recommendation

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

ERR14

ERR08-J

medium

Medium

likely

Likely

medium

Medium

P12

L3

L1

Automated Detection

...

Automated detection of code that catches RuntimeException, Exception, or Throwable is trivial. Sound automated determination of whether such code complies with the exceptions to this rule is infeasible. Heuristic techniques may be helpful.

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

Related Guidelines

MITRE CWE:

CWE-230 "Improper Handling of Missing Values"

 

CWE-232 "Improper Handling of Undefined Values"

 

CWE-690 "Unchecked Return Value to NULL Pointer Dereference"

 

CWE-395 "Use of NullPointerException Catch to Detect NULL Pointer Dereference"

 

CWE-396 "Declaration of Catch for Generic Exception"

 

CWE-7 "J2EE Misconfiguration: Missing Custom Error Page"

 

CWE-537 "Information Exposure Through Java Runtime Error Message"

 

CWE-536 "Information Exposure Through Servlet Runtime Error Message"

The Elements of Java Style:

Rule 87: Do not silently absorb a run-time or error exception

Bibliography

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="f513707e-30f6-4a5e-bd86-8be88a46c218"><ac:plain-text-body><![CDATA[

[[Cunningham 1995

AA. Bibliography#Cunningham 95]]

 

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

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="be259862-f5fa-4d9e-a590-f44794f0fb18"><ac:plain-text-body><![CDATA[

[[Doshi 2003

AA. Bibliography#Doshi 03]]

 

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

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="a1344ee7-d188-4cb0-b7bb-87c7ef6e4ceb"><ac:plain-text-body><![CDATA[

[[Grand 2002

AA. Bibliography#Grand 02]]

Chapter 8, Behavioral patterns, the Null Object

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

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="98f475d8-aa10-4f88-a878-dd575dd7e063"><ac:plain-text-body><![CDATA[

[[Henney 2003

AA. Bibliography#Henney 03]]

 

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

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="211ec01d-d609-4948-9f48-37671964e80a"><ac:plain-text-body><![CDATA[

[[JLS 2005

AA. Bibliography#JLS 05]]

[Chapter 11, Exceptions

http://java.sun.com/docs/books/jls/third_edition/html/exceptions.html]

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

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="55b880bd-301b-4d7c-87ab-172943594ba6"><ac:plain-text-body><![CDATA[

[[J2SE 2011

AA. Bibliography#J2SE 11]]

Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking

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

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="28e2a4ce-f472-456e-813c-91d0cdea5fdd"><ac:plain-text-body><![CDATA[

[[Muller 2002

AA. Bibliography#Muller 02]]

 

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

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="b12ecb62-ca98-419c-beb8-a7aa45e7ee69"><ac:plain-text-body><![CDATA[

[[Schweisguth 2003

AA. Bibliography#Schweisguth 03]]

 

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

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="9a9767ba-7b6b-44c2-8bae-887de0828a94"><ac:plain-text-body><![CDATA[

[[Tutorials 2008

AA. Bibliography#tutorials 08]]

[Exceptions

http://java.sun.com/docs/books/tutorial/essential/exceptions/index.html]

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

ToolVersionCheckerDescription
CodeSonar
Include Page
CodeSonar_V
CodeSonar_V

JAVA.STRUCT.EXCP.GEH
JAVA.STRUCT.EXCP.INAPP

Generic Exception Handler (Java)
Inappropriate Exception Handler (Java)

Parasoft Jtest
Include Page
Parasoft_V
Parasoft_V
CERT.ERR08.NCNPEDo not catch 'NullPointerException'
SonarQube
Include Page
SonarQube_V
SonarQube_V

S1181

S1696

Throwable and Error should not be caught

"NullPointerException" should not be caught

SpotBugs

Include Page
SpotBugs_V
SpotBugs_V

DCN_NULLPOINTER_EXCEPTIONImplemented (since 4.5.0)


...

Image Added Image Added Image AddedERR13-J. Do not throw RuntimeException, Exception, or Throwable      06. Exceptional Behavior (ERR)      07. Visibility and Atomicity (VNA)