Java


JAVA.ALLOC.LEAK.NOTSTORED : Closeable Not Stored (Java)

Summary

A closeable has not been immediately stored into a local variable.

Resources such as files or database connections should be closed, or otherwise the system might run into an out of resource exception. The close operation should always be performed, in every execution path. For this reason, the try-with-resource or finally constructs should be used.

This checker verifies that resources are always closed after being open, for every execution path. This checker recognizes and accepts as correct code where a resource is stored into a field or returned from a method and is then closed at the end, at least for some frequent scenarios.

Properties

Class Name Closeable Not Stored (Java)
Significance reliability
Mnemonic JAVA.ALLOC.LEAK.NOTSTORED
Categories
CWE CWE:400 Uncontrolled Resource Consumption
CERT-Java CERT-Java:FIO04-J Release resources when they are no longer needed
  CERT-Java:MSC05-J Do not exhaust heap space
  CERT-Java:SER10-J Avoid memory and resource leaks during serialization
Availability Available for Java only.
Enabling Checks for this warning class are enabled by default. To disable them, add the following WARNING_FILTER rule to the project configuration file.
WARNING_FILTER += discard class="Closeable Not Stored (Java)"

Example

import java.io.FileWriter;
import java.io.IOException;

public class TestCloseOfResources {
  private final FileWriter myOtherField;

  public TestCloseOfResources() throws IOException {
    myOtherField = new FileWriter("temp.txt"); /* Closeable Not Closed (Java)
                                                * warning issued here - myOtherField should be closed inside a 'finally' block. 
                                                * If an exception occurs during the execution myOtherField.write, the program will not be able 
                                                * to perform the close at the next line.
                                                */
    myOtherField.write("wo sind die Helden der Vergangenheit?");
    myOtherField.close();
  }

  public TestCloseOfResources(int i) throws IOException {
    myOtherField = new FileWriter("temp.txt");

    try {
      myOtherField.write("wo sind die Helden der Vergangenheit?");
    }
    finally {
      myOtherField.close();
    }
  }

  public TestCloseOfResources(float f) throws IOException {
    myOtherField = new FileWriter("temp.txt"); /* Closeable Not Closed (Java)
                                                * warning issued here - myOtherField may not be closed 
                                                * if the result of System.currentTimeMillis() is an odd number. 
                                                */

    try {
      myOtherField.write("wo sind die Helden der Vergangenheit?");
    }
    finally {
      if (System.currentTimeMillis() % 2 == 0)
        myOtherField.close();
    }
  }

  public void test3() throws IOException {
    FileWriter writer = null;;

    try {
      writer = new FileWriter("temp.txt");
      writer.write("wo sind die Helden der Vergangenheit?");
    }
    finally {
      if (writer != null)
        writer.close();
    }
  }

  public void test4() throws IOException {
    try (FileWriter writer = new FileWriter("temp.txt")) {
      writer.write("wo sind die Helden der Vergangenheit?");
    }
  }

  public FileWriter test16() throws IOException {
    return new FileWriter("temp.txt");
  }

  public void test19() throws IOException {
    FileWriter writer = test16();

    try {
      writer.write("wo sind die Helden der Vergangenheit?");
    }
    finally {
      writer.close();
    }
  }
  
  public void test99() throws IOException {
    new FileWriter("temp.txt").write("wo sind die Helden der Vergangenheit?");  /* Closeable Not Stored (Java)
                                                * warning issued here - the resource is not stored into a local variable so 
                                                * there is no way to close it.
                                                */
  }
  
  public void test100() throws IOException {
  
    FileWriter writer = new FileWriter("temp.txt");

    try {
      writer.write("wo sind die Helden der Vergangenheit?");
    }
    finally {
      writer.close();
    }
  }
}

Resolution

Guarantee that all resources are closed, typically by using a try-with-resource or a finally construct. In general, avoid storing resources into fields or returning resources from methods or letting a method close a resource passed to it as a parameter.

Relevant Configuration File Parameters

The following configuration file parameters affect checks for this warning class.