You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 3 Next »

JDK 1.7 introduced the "try-with-resources" statement [JLS 2011] §14.20.3, "try-with-resources" that makes it much easier to deal with resources that implement the java.lang.AutoCloseable interface, including those that implement the java.io.Closeable interface.

Using the try-with-resources statement avoids problems that can arise when closing resources with an ordinary try-catch-finally block, such as failing to close a resource because an exception is thrown as a result of closing another resource, or masking an important exception when a resource is closed.

Noncompliant Code Example

This noncompliant code example uses an ordinary try-finally block to try to close two resources.  However, if closing the Bufferedreader br results in an exception being thrown, then the BufferedWriter bw will not be closed.

String inPath = ...; // input file path
String outPath = ...; // output file path

BufferedReader br = null;
BufferedWriter bw = null;
try {
  br = new BufferedReader(new FileReader(inPath));
  bw = new BufferedWriter(new FileWriter(outPath));

 // process the input and produce the output
} finally {
  if (br != null) {
    br.close();
  }
  if (bw != null) {
    bw.close();
  }
}

Compliant Solution

This compliant solution uses a try-with-resources statement which will guarantee that both br and bw are closed, irrespective of any exceptions being thrown during the close operations.

String inPath = ...; // input file path
String outPath = ...; // output file path

try (
      BufferedReader br = new BufferedReader(new FileReader(inPath));
      BufferedWriter bw = new BufferedWriter(new FileWriter(outPath));
    ) {

  // process the input and produce the output
}

Noncompliant Code Example

This noncompliant code example uses an ordinary try-finally block to try to close a resource.  However, if there is an exception thrown both during the processing of the input and when closing the Bufferedreader br, then the exception thrown as a result of processing the input will be lost, and important information about that exceptional circumstance may be missed.

String inPath = ...; // input file path

BufferedReader br = null;
try {
  br = new BufferedReader(new FileReader(inPath));

  // process the input and produce the output
} finally {
  if (br != null) {
    br.close();
  }
}

Compliant Solution

 

This compliant solution uses a try-with-resources statement which will not suppress any exceptions thrown during the processing of the input while still guaranteeing that br is closed.

String inPath = ...; // input file path

try (
      BufferedReader br = new BufferedReader(new FileReader(inPath));
    ) {
  // process the input and produce the output

} catch (IOException ex) {
  System.err.println("thrown exception: " + ex.toString());
  Throwable[] suppressed = ex.getSuppressed();
  for (int i = 0; i < suppressed.length; i++) {
    System.err.println("suppressed exception: "
        + suppressed[i].toString());
  }
}

If only one exception is thrown, either during opening, processing, or closing of the file, it will be printed by the "thrown exception: " statement. If an exception is thrown during processing, and another one is thrown while trying to close the file, then the "thrown exception: " statement will print the exception encountered while closing the file, and the "suppressed exception: " statement will print the exception encountered during processing.

Applicability

Failing to use a try-with-resources statement when dealing with closeable resources may result in some resources not being closed, or important exceptions being masked, possibly resulting in a denial of service attack.

Bibliography

  • No labels