Checker CloseResource   as of Julia version 2.4 (built on 23 Oct 2017)

belongs to group Basic

Identify leakage of resources left open


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. Differently from the CloseWhereCreated checker, 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.

Action: 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.

Examples


Consider the following program:

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

public class TestCloseOfResources {
  private final FileWriter myOtherField;

  public TestCloseOfResources() throws IOException {
    myOtherField = new FileWriter("temp.txt");
    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");

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

This checker issues the following warnings:

TestCloseOfResources.java:8: [CloseResource: ResourceNotClosedAtEndOfMethodWarning] This closeable resource does not seem to be always closed by the end of this constructor. It seems leaked if an exception occurs at line 10 before being closed
TestCloseOfResources.java:25: [CloseResource: ResourceNotClosedAtEndOfMethodWarning] This closeable resource does not seem to be always closed by the end of this constructor. It seems leaked at line 34

since the resource created at line 8 should be closed inside a finally block, that guarantees the execution of the close operation, whatever happens in the middle. The resource created at line 25 might not be closed if System.currentTimeMillis() is an odd number. It is interesting to observe that Julia does not issue any warning elsewhere, since the other resources are always closed, on every execution path. In particular, this checker allows the programmer to open and return a resource, such as inside method test16(), as long as the callers of that method take care of closing the resource after calling the method, as happens in test19().