применить CheckReturnValue ко всему проекту - PullRequest
1 голос
/ 06 августа 2020

Я работаю над большим устаревшим приложением Java 8 (Android). Недавно мы обнаружили ошибку, вызванную игнорированием результата метода. В частности, вызывающий метод send() не предпринимал правильных действий в случае сбоя отправки. Это было исправлено, но теперь я хочу добавить некоторый статистический c анализ, чтобы помочь определить, существуют ли в нашем коде другие существующие ошибки такого же характера. И, кроме того, чтобы предотвратить добавление новых ошибок той же природы в будущем.

Мы уже используем Find Bugs, PMD, Checkstyle, Lint и SonarQube. Итак, я подумал, что у одного из них, вероятно, уже есть нужный мне чек, но его просто нужно включить. Но после нескольких часов поиска и тестирования я не думаю, что это так.

Для справки, это код, с которым я тестировал:

public class Application {
    public status void main(String[] args) {
        foo(); // I want this to be caught
        Bar aBar = new Bar();
        aBar.baz(); // I want this to be caught
    }
    
    static boolean foo() {
        return System.currentTimeMillis() % 2 == 0;
    }
}

public class Bar {
    boolean baz() {
        return System.currentTimeMillis() % 2 == 0;
    }
}

Я хочу поймать это на стороне вызывающего , поскольку некоторые вызывающие абоненты могут использовать значение, а другие - нет. (Метод send(), описанный выше, был этим случаем)

Я обнаружил следующие существующие правила анализа c, но они, похоже, применимы только к очень специфическим c обстоятельствам, чтобы избежать ложных срабатываний и не работать на мой пример:

Пока что лучшим вариантом кажется №3, но он требует мне аннотировать КАЖДЫЙ метод или класс в моем ОГРОМНОМ проекте. Java 9+, похоже, позволяет аннотировать на уровне пакета, но для меня это не вариант. Даже если бы это было так, в проекте МНОГО пакетов. Мне действительно нужен способ настроить это для применения ко всему моему проекту через одно / несколько мест, вместо того, чтобы изменять каждый файл.

Наконец, я наткнулся на этот ответ на переполнение стека , который показал Мне кажется, что IntelliJ имеет эту проверку с проверкой «Сообщать обо всех проигнорированных небиблиотечных вызовах». Кажется, что это работает, если выделить в среде IDE. Но я хочу, чтобы это привело к сбою CI. Я обнаружил, что есть способ запустить это через командную строку с помощью инструментов intelliJ , но при этом по-прежнему выводится файл XML / JSON, и мне нужно будет написать собственный код для анализа этого вывода. Мне также нужно установить инструменты IDE на машину CI, что кажется излишним.

Кто-нибудь знает лучший способ достичь того, чего я хочу? Я не могу быть первым, кто заботится только о ложных отрицаниях и не беспокоюсь о ложных срабатываниях. Я чувствую, что должно быть управляемо иметь любое возвращаемое значение, которое в настоящее время не используется, чтобы либо регистрироваться, либо явно указывалось, что возвращаемое значение намеренно игнорируется через аннотацию или присвоение переменной соглашения, как они это делают в Вероятность ошибок

Ответы [ 2 ]

1 голос
/ 07 августа 2020

Сценарий ios, подобный тому, который вы описываете, неизменно приводит к существенному дефекту программного обеспечения (истинная ошибка во всех отношениях); делалось более разочаровывающим и запутанным, потому что код молча терпит неудачу и позволял проблеме оставаться скрытой. Ваше желание выявить подобные скрытые дефекты (и исправить их) легко понять; однако (я смиренно предлагаю) анализ кода stati c может быть не лучшей стратегией:

  • Работая с проблемами, которые вы express в своем вопросе: правило CheckReturnValue выполняется высокий риск создания каскада из //Ignore комментариев кода, предложений правила violationSuppress и / или @suppressRule аннотаций, которые намного превышают количество положительных обнаруженных дефектов по правилу.

  • Язык программирования Java дополнительно увеличивает вероятность большого количества подавленных правил после учета Java сборки мусора и оценки того, как сборка мусора влияет на разработку программного обеспечения. Исходя из понимания того, что Java сборка мусора основана на подсчете ссылок на экземпляры объекта, что только экземпляры со счетчиком ссылок 0 (ноль) имеют право на сборку мусора, разработчикам Java имеет смысл избегать ненужных ссылок, и естественно принять практику игнорирования неважных возвращаемых значений вызова методов. Игнорируемые экземпляры просто выпадут из локального стека вызовов, большинство из них достигнет счетчика ссылок 0 (ноль), сразу же станут подходящими для go сборки мусора и быстро станут

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

  • Основываясь на вашем описании сценария и возникающем в результате дефекте / ошибке, похоже, что ближайшей root причиной проблемы является сбой модульного тестирования или сбой интеграционного тестирования. Реализация операции отправки, которая может (и почти наверняка в какой-то момент) потерпит неудачу, как модульное тестирование, так и интеграционное тестирование, безусловно, должны были включать в себя несколько сценариев возможных сбоев ios и обработку проверенных сценариев сбоев. Я, конечно, не знаю, но готов поспорить, что если вы сосредоточитесь на создании и запуске модульных и интеграционных тестов, качество системы будет улучшаться на каждом этапе, улучшения будут очевидны, и вы можете очень хорошо раскройте некоторые или все скрытые ошибки, которые являются причиной вашего беспокойства, беспокойства, стресса и беспокойства.

  • Рассмотрите возможность сохранения сути вашего текущего состояния c анализ кода исследования живы, но измените свой подход в новом направлении. В первый раз, когда я прочитал ваш вопрос, меня поразило осознание того, что проверки кода, которые вы хотели бы выполнить, существуют в нескольких несвязанных местах по всей базе кода и быстро становятся чрезмерно сложными, c подробности проверок отличаются во многих частях кода, и каждый из частных случаев делает общие усилия нереальными c. По сути, то, что вы хотели бы реализовать, представляет собой сквозную цель, которая попадает в значительную часть базы кода, а детали реализации сделали довольно простую хорошую идею смехотворно сложной. Ваш вопрос - это почти хрестоматийный пример проблемы, которую лучше всего решить с использованием сквозного аспектно-ориентированного подхода.

Если у вас есть время и интерес, пожалуйста, взгляните на AspectJ framework, возможно, закодируйте несколько исследовательских аспектов и дайте мне знать, что вы думаете. Я хотел бы услышать ваши мысли, если вам захочется в какой-то момент пообщаться с разработчиками. Я действительно надеюсь, что это будет полезно -

0 голосов
/ 07 августа 2020

Вы можете использовать инспекцию intelliJ IDEA: Java | Вероятные ошибки | Результат вызова метода игнорируется с включенной опцией « Сообщать обо всех проигнорированных небиблиотечных вызовах ». Он перехватывает оба случая, представленные в вашем примере кода.

...