Checker CloseResource

belongs to group Basic
Identify leakage of resources left open

Frameworks supported by this checker

  • java up to 11
  • android up to API level 28
  • dotnet

Warnings generated by this checker

  • CloseableNotStoredIntoLocalWarning: a closeable has not been immediately stored into a local variable [ CWE400 ]
  • ResourceNotClosedAtEndOfMethodWarning: a resource should be closed by the end of the method where it is created [ CWE772 ]

Options accepted by this checker

  • none

Annotations understood by this checker

  • @com.juliasoft.julia.checkers.closeWhereCreated.AutoClosedResource
  • @com.juliasoft.julia.checkers.closeWhereCreated.CanBeInitializedInTryWithResource
  • @com.juliasoft.julia.checkers.closeWhereCreated.ResourceThatDoesNotNeedToBeClosed
  • @com.juliasoft.julia.checkers.closeWhereCreated.ResourceThatMustBeClosed


Description

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.

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.

Resources such as files or database connections should be disposed, or otherwise the system might run into an out of resource exception. The dispose operation should always be performed, in every execution path. For this reason, the using 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.

Action: Guarantee that all resources are closed, typically by using a using 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.

Resources such as files or database connections should be closed, or otherwise the system might run into an out of resource exceptionand in an android context, should be release resources such as Mediaplayer, Mediarecorder etc., unless the application has a special need to keep the object around. In addition to unnecessary resources (such as memory and instances of codecs) being held, failure to call this method immediately if a MediaPlayer object is no longer needed may also lead to continuous battery consumption for mobile devices, and playback failure for other applications if no multiple instances of the same codec are supported on a device (AndroidAPIa>) The close/release 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/released after being open or creation, 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/released at the end, at least for some frequent scenarios.

Action: Guarantee that all resources are closed/released, 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().

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().

Consider the following program:

package example.closeresource;

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

import android.app.Activity;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends Activity{

	protected void onCreate(Bundle bundle) {
		super.onCreate(bundle);

		queryDatabase();
		
		useMediaPlayer();
		
		try {
			writeFile();
		} catch (IOException e) {
			Log.e(TestAndroidResources.class.getName(), "Unable to write file !");
		}

	}

	private void queryDatabase() {
		
		SQLiteDatabase database = openOrCreateDatabase("MyDataBase", Context.MODE_PRIVATE, null);

		final Cursor myQueryCursor = database.query("table", new String[] { "columnLabel1", "columnLabel2" }, "selection",
				new String[] { "selectionArgs1", "selectionArgs2" }, "groupBy", "having", "orderBy");
		
		database.query("anotherTable", new String[] { "anotherColumnLabel1", "anotherColumnLabel2" }, "anotherSelection",
				new String[] { "anotherSelectionArgs1", "anotherSelectionArgs2" }, "anotherGroupBy", "anotherHaving", "anotherOrderBy");
		
	}
	
	private void useMediaPlayer() {
		
		MediaPlayer mp = new MediaPlayer();
		try {
			mp.setDataSource("myFile");
			mp.prepare();
			mp.start();
		} catch (IOException e) {
			mp.release();
		}
		
	}
	
	private void writeFile() throws IOException {mediaplayer android release
		  FileWriter file = new FileWriter("tmp.txt");
		  file.write("Hello World !");
		  file.close();
	}
	
}

MainActivity.java:28: [CloseResource: CloseableNotStoredIntoLocalWarning] Instances of class "Cursor" should be immediately stored into a local variable, for later being closed", source="com/juliasoft/julia/tests/checks/closeResource/TestAndroidResources.java
MainActivity.java:35: [CloseResource: ResourceNotClosedAtEndOfMethodWarning] This instance of class "Cursor" does not seem to be always closed by the end of this method. It seems leaked if an exception occurs at line 38 before being closed
MainActivity.java:57: [CloseResource: ResourceNotClosedAtEndOfMethodWarning] This instance of class "FileWriter" does not seem to be always closed by the end of this method. It seems leaked if an exception occurs at line 58 before being closed
MainActivity.java:45: [CloseResource: ResourceNotClosedAtEndOfMethodWarning] This instance of class "MediaPlayer" does not seem to be always closed by the end of this method. It seems leaked if an exception occurs at line 47 before being closed
MainActivity.java:33: [CloseResource: ResourceNotClosedAtEndOfMethodWarning] This instance of class "SQLiteDatabase" does not seem to be always closed by the end of this method. It seems leaked if an exception occurs at line 35 before being closed

The warnings are all relative to close/release resources. The resources created at lines 33,35 are used but not closed. At line 28, the resource is created but it is not immediately stored into a local variable, for later being closed. The resource created at line 57 should be closed inside a finally block, that guarantees the execution of the close operation, whatever happens in the middle (for example with an exception the resource cannot be closed). The same solution applies to the resource created at line 45, because without a finally if the execution does not throws exception the resource is not released.