JDBC, укрепиться и попробовать-с-ресурсом


В настоящее время я работаю над проектом, который использует инструмент HP Fortify SCA для обнаружения проблем безопасности в базе кода. У меня возникла небольшая проблема с определением наилучшего подхода к правильной обработке ресурсов JDBC.

Код, который у меня есть в данный момент, выглядит следующим образом;

    try (Connection conn = new DatabaseService().getConnection();
            PreparedStatement ps = conn.prepareStatement(query);) {

        ps.setString(1, mString);

        try (ResultSet rs = ps.executeQuery();) {

            while (rs.next()) {
             ...Do logic...
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }

    } catch (SQLException e){
        e.printStackTrace();
    }
}

Проблема заключается в том, что Fortify отметит этот код, заявив, что если во вложенном операторе try произойдет исключение, то ссылка на conn и ps будет потеряна, и они они не будут закрыты должным образом. Является ли fortify правильным, чтобы отметить это, или это ложноположительный результат? Из того, что я понимаю, try-with-resource должен всегда закрывать свой ресурс, но, возможно, это не всегда происходит, когда они вложены подобным образом.

Я просмотрел другие связанные с этим вопросы и блоги по всему интернету, но мне не удалось получить никаких окончательных доказательств этого.

Наиболее документированное решение, которое всегда безопасно в этой ситуации, - это не использовать try-with-resource и оберните каждый ресурс с try-catch в блоки catch и finally более широкого оператора try-catch. Однако я предпочел бы избежать этого, потому что это ужасно многословно.

Заранее спасибо!

Edit: Итак, я понял, что кое-что упустил из кода, когда переписывал его в SO. В первоначальных блоках catch был оператор System.exit(1); (плохая практика, которую я знаю). Это означало бы, что если исключение было брошено во вложенном try-with-resource, то Fortify было бы правильно сказать conn и ps не будут должным образом закрыты.

Спасибо за ответы, без System.exit(1); все ресурсы в этой ситуации будут закрыты должным образом, и я выбрал ответ, указывающий на это.

2 2

2 ответа:

Использование try-with-resourceВсегда поддерживается на Java 7 и выше, независимо от того, какие инструменты находятся на его вершине.

Таким образом, если этот код компилируется (то есть вы находитесь на Java7+), вы можете спокойно игнорировать любые предупреждения, поскольку они действительно ложные срабатывания. Для классов JRE гарантируется автоматическое закрытие контракта на ресурсы.

Теперь, если вы решите написать свой собственный ресурс, который реализует AutoCloseable тогда это до вас, чтобы убедиться, что метод close() на самом деле закрывает ресурс =)

Переводчик Fortify Java, возможно, никогда не обновлялся с помощью этой конструкции Java 7+. Вы должны связаться с технической поддержкой Fortify и представить тестовый случай. Этот анализ неверен.

Далее, вы должны отметить это и другие идентичные выводы "не проблема" и двигаться дальше в своей жизни.