Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: general edit

...

Noncompliant Code Example

The finally clause This noncompliant code example uses a finally block that closes the reader object in this noncompliant code example. However, it is incorrectly assumed that the statements within occurring in the finally block cannot throw exceptions. Notably, the close() method can throw an IOException which prevents any subsequent clean-up lines from being executed. This is not detected at compile time as the type of exception that close() throws is the same as the type of exceptions that the methods read() and write() throw.

Code Block
bgColor#FFCCCC
public class Operation {
  private static void doOperation(String some_file) throws IOException {
    BufferedReader reader = new BufferedReader(new FileReader(some_file));
    // Do operations 
     
    } finally {
      reader.close();
      // ... Other clean-up code ...
    }
  }

  public static void main(String[] args) throws IOException {
    String path = "somepath";
    doOperation(path);
  }
}

Notably, the close() method can throw an IOException which prevents any subsequent clean-up statements from being executed. This is not detected at compile time because the type of exception that close() throws is the same as the type of exceptions that methods read() and write() throw.

Compliant Solution (1)

This compliant solution correctly places the close() statement in a try-catch block. As a result, an IOException can be handled without letting it propagate any further.

Code Block
bgColor#ccccff
public class Operation {
  static void doOperation(String some_file) throws IOException {
    BufferedReader reader = new BufferedReader(new FileReader(some_file));

    try {
      // Do operations
    } finally {
        try {    
          // Enclose in try-catch block
          reader.close();
        } catch (IOException ie) {
          // Forward to handler
        }
        // Other clean-up code
    }
  }

  public static void main(String[] args) throws IOException {
    String path = "somepath";
    doOperation(path);
  }
}

...

Code Block
bgColor#ccccff
public class Operation {
  static void doOperation(String some_file) throws IOException {
    BufferedReader reader = new BufferedReader(new FileReader(some_file));

    try {
      // Do operations
    } finally {
      closeIgnoringException(reader);
      // Other clean-up code 
    }
}

  private static void closeIgnoringException(BufferredReader s) {
    if (s != null) {
      try {
        s.close();
      } catch (IOException ie) {
        // Ignore exception if close fails
      }
    }
  }

  public static void main(String[] args) throws IOException {
    String path = doOperation("somepath";
    doOperation(path);
  }
}

Risk Assessment

Failing to handle an exception in a finally block can lead to unexpected results.

...