# V6127. Closeable object is not closed. This may lead to a resource leak.

Анализатор обнаружил, что объект, реализующий интерфейс `Closeable`, не закрывается во всех путях исполнения.

Интерфейс `Closeable` сигнализирует о том, что объект содержит в себе данные, которые можно закрыть. Такие данные именуются ресурсами. Ими могут быть файлы или открытые соединения.

В случае, если пропадёт ссылка на объект, который удерживает ресурс, закрыть его не получится. Это может привести к утечке памяти, ресурса ОС или другим негативным последствиям.

В данном примере открытый файл не закрывают после использования:

    public void objectIsNotClosed(File f) {
      try {
        FileInputStream fis = new FileInputStream(f); // <=
        int data;
        while ((data = fis.read()) != -1) {
          System.out.print((char) data);
        }
      } catch (IOException e) {
        // Exception handling
      }
    }

Объект не закрывается в блоке `try`, и после выхода из него возможности закрыть файловый поток не будет.

Чтобы избежать утечки дескриптора, необходимо у объекта файлового потока вызвать метод `close`:

    public void objectIsClosedInFinally(File f)  {
      FileInputStream fis = null;
      try {
        fis = new FileInputStream(f);
        int data;
        while ((data = fis.read()) != -1) {
          System.out.print((char) data);
        }
      } catch (IOException e) {
        // Exception handling
      } finally {
        if (fis != null) {
          try {
            fis.close();
          } catch (IOException e) {
            // Exception handling
          }
        }
      }
    }

Также в Java 7 появилась более лаконичная и удобная возможность управлять ресурсами — `try-with-resources`. Подробнее про неё можно прочитать в документации.

Важно отметить, что в ней Oracle рекомендуют использовать именно `try-with-resources`, нежели предыдущий способ закрытия ресурса.

Предыдущий пример с использованием `try-with-resources`:

    public void objectIsClosed(File f) {
      try (FileInputStream fis = new FileInputStream(f)){
        int data;
        while ((data = fis.read()) != -1) {
          System.out.print((char) data);
        }
      } catch (IOException e) {
        // Exception handling
      }
    }

Также в рамках диагностики рассматривается случай, когда `Closeable` объект создаётся в конструкторе, который потенциально может выбросить исключение. Такая реализация не является безопасной, потому что в случае выброса исключения `Closeable` объект создастся, но ссылка на него будет утрачена, и не будет возможности его закрыть.

Выявляемые диагностикой ошибки классифицируются согласно ГОСТ Р 71207–2024 как критические и относятся к типу: Ошибки утечек памяти, незакрытых файловых дескрипторов и дескрипторов сетевых соединений [* см. примечание касательно языков C#, Java].

Данная диагностика классифицируется как:

CWE-459 CWE-772 CERT-FIO04-J