Рубрики
Без рубрики

Лучшие результаты DeepCode # 3: Java отсутствует Закрыть или сбросить

Эй, Язык: Дефект Java: отсутствует~промывка~или~закрытие (Категория Общая 2) Дефект — Утечка ресурсов/Дата… Помеченный глубоким кодом, java, статический анализ кода, потоки.

Основные выводы Глубокого Кода (Серия из 13 частей)

Эй,

Язык: Java Дефект: отсутствует~промывка~или~закрытие (категория Общая 2) Дефект — Утечка ресурсов/Потеря данных Неспособность очистить файловый файл может привести к потере данных в худшем случае, в лучшем случае к утечке ресурсов.

Фон:

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

Давайте начнем с яркого примера здесь: Пример

...
public class DumpBytecodeVisitor
extends BytecodeVisitor
{
   private final PrintWriter out;
   private int indentLevel;
   public DumpBytecodeVisitor(Writer out)
   {
      this.out = new PrintWriter(out);
   }
...

Код создает новый Устройство записи принтера из существующего Устройства записи без автоматической очистки (см. Документацию Java по PrinterWriter ). Класс Java Printwriter записывает форматированные данные в базовый Writer .

Поиск кода приведенного выше примера из prestodb показывает: Он никогда не вызывает flush() или close() . Проблема в том, что код может пострадать от потери данных и плохой обработки ресурсов. Когда приложение завершается, операционная система в большинстве случаев обрабатывает открытые потоки, но буферизованные, еще не записанные данные теряются. Во-вторых, не закрывать поток – это просто плохая практика, поскольку обработчики потоков являются ценным ресурсом, и о них следует позаботиться. В JDK <7 приложение должно явно вызывать close() . Но, похоже, проблема не делать этого была настолько неизбежной, что Java добавила новый способ обработки открытых потоков: Инструкция try-with-resources . В Java 9 следующая конструкция автоматически закрывает поток:

BufferedWriter writer = new BufferedWriter(new FileWriter(filename);
try (writer) {
   writer.write(someString); //Write someting to file
}
catch(IOException e) {
   // Handle error conditions
}

Для автоматического закрытия потока (здесь BufferedWriter ) необходимо реализовать Автоматически закрываемый интерфейс. Устройство записи на принтере реализует его. Для статического анализа программы эта ошибка сложна, так как она легко может привести к ложным срабатываниям. Потоки могут быть сгенерированы, намеренно оставаясь открытыми во время выполнения приложения и передаваясь через код различным классам обработки (что является антипаттером). Таким образом, статический анализ программы должен отслеживать объект потока через поток программы для всех возможных путей приложения. Ни один путь не должен приводить к ситуации, когда поток не закрыт. С другой стороны, Статический анализ программы должен понимать эффект вышеупомянутого утверждения “попробуй с ресурсами”. Эта статья в блоге дает хороший обзор .

В нашем первоначальном примере необходимо изменить следующие вещи: (1) Класс, которому принадлежит поток, должен отвечать за его правильное закрытие. (2) Используя flush() или просто установив значение autoflush в значение true в конструкторе, класс должен обязательно записать данные.

Если вы не уверены в обработке открытия и закрытия или сброса в вашем коде, посетите deepcode.ai и дайте ему тест.

cu

0xff

Основные выводы Глубокого Кода (Серия из 13 частей)

Оригинал: “https://dev.to/deepcode/deepcode-s-top-findings-3-java-missing-close-or-flush-ifk”