Java Устаревшие API и SuppressWarnings "устаревшие" - практический подход - PullRequest
0 голосов
/ 12 мая 2018

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

Однако почти во всех этих случаях разработчики кода не только использовали устаревшие API, но и подавили предупреждение об устаревании .

Похоже, что лучшие намерения разработчиков API заканчиваются тем, что они создают больше кода, который не имеет отношения к реализованной бизнес-логике - если API устарел, но постоянно используется с подавлением связанных предупреждений, это похоже на ухудшение кода в лучшем случае и потенциальная критическая точка приложения при замене устаревших библиотек в худшем случае ИМХО.

Есть ли практическое решение этой проблемы? По крайней мере, как пометить это явление как запах кода, если оно действительно остается в ЧР относительно долгое время?

Пожалуйста, предложите реальное решение, которое вы могли бы использовать (библиотека, SCA, плагин CR и т. Д. .....)

Существуют ли запланированные функции JRE / JDK, которые могут помочь в этой ситуации? Мое исследование в настоящее время ничего не нашло.

Ссылки:

Ответы [ 3 ]

0 голосов
/ 12 мая 2018

Шаг 1: объявить об удалении

Можно подумать, что отказ от API означает объявление о его удалении, но это не единственный вариант использования (как описано в соответствующих статьях, например, Java 7 и Java 9 ):

  • API опасен (например, метод Thread.stop).

  • Существует простое переименование (например, AWT Component.show/hide заменено на setVisible).

  • Вместо этого можно использовать более новый и лучший API.

  • Устаревший API будет удален.

Чтобы еще больше усложнить ситуацию, до Java 9 ни один устаревший API в JDK никогда не удалялся (см. 20 лет устаревания Java ), поэтому понятно, что разработчики не воспринимают устаревание серьезно - ни в JDK, ни где-либо еще.

Следовательно, вам необходимо четко сообщить, что API действительно, действительно будет удален . Способ сделать это зависит от версии Java, с которой скомпилирован ваш API.

Java 8 или ниже

В этих версиях Java не существует формального способа явного различения различных вариантов использования устаревших. Лучшее, что вы можете сделать, это добавить тег Javadoc @deprecated, не только указав причину устаревания и перечислив альтернативы, но и явно объявив о своем намерении удалить API.

Java 9 или выше

Начиная с Java 9, с Enhanced Deprecation , теперь вы можете писать

@Deprecated(forRemoval=<boolean>)

для явного документирования вашего намерения. Я думаю, что вместе с Javadoc @deprecated (который должен детализировать причину устаревания и перечислить альтернативы), этот стандартизированный флаг является справедливым предупреждением.

Если для этого флага установлено значение true, компилятор будет предупреждать о каждом использовании устаревшего элемента, например:

YourClass.java:<line>: warning: [removal] <method> in <class> has been
deprecated and marked for removal

Это предупреждение включено по умолчанию (вместо того, чтобы включать его с помощью -Xlint:deprecation) и не подавляется с помощью @SuppressWarnings("deprecation"). Вместо этого нужно было бы подавить его с помощью нового @SuppressWarnings("removal"), что может заставить разработчиков дважды подумать об этом без действительно веской причины.

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

@Deprecated(since="<version>")

Просмотр этого в Javadoc или источниках может помочь разработчикам оценить, насколько срочно необходимо обновить их код.

Шаг 2a: предупреждение во время выполнения

Если это возможно для ситуации, добавьте напоминание времени выполнения: когда устаревший API используется, он должен записать предупреждение в консоль или файл журнала (используя любой используемый механизм ведения журнала), объявляя, что это больше не будет работать со следующей основной выпуск. Чтобы избежать спама, вы можете войти в систему только один раз (например, private static boolean warningLogged).

Шаг 2b: Статический анализ кода

Статические анализаторы кода, такие как SonarQube (также доступны как размещенная служба ), могут быть настроены для пометки каждого из этих предупреждений. Правило SonarQube «не рекомендуется использовать устаревший код» должно работать, даже если предупреждение об использовании устаревшего компилятора подавлено.

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

Шаг 3: Удалить API

Фактическое удаление API не даст вашим пользователям API впечатление, что им не нужно беспокоиться об изменении своего кода.

0 голосов
/ 12 мая 2018

Есть ли практическое решение этой проблемы?

Практично с чьей точки зрения?

С точки зрения разработчиков, которые обычно игнорируют / подавляют предупреждения об устаревании, у них уже есть свое «решение» ... которое должно игнорировать проблему. Но обратная сторона в том, что другие люди не могут помешать им сделать это. Но обратная сторона обратной стороны состоит в том, что ... в конечном счете ... это не дело других людей.

С точки зрения разработчиков, которые хотят отказаться от поддерживаемых ими API, у них уже есть решение. Просто сделай это. Затем выполните следующий шаг, фактически удалив устаревшие API. Обратной стороной является то, что это будет раздражать некоторых людей, а другие будут сожжены. (Особенно люди, которые обычно игнорируют / подавляют предупреждения об устаревании. Но см. Выше: это их проблема.)

С точки зрения кого-то, чья забота / ответственность заключается в поддержании качества / целостности кода в кодовой базе организации, да, есть проблема. Но решение относительно прямолинейно:

  • Запретить коду использование @suppress ("deprecation") `.
  • Запретить сценарии сборки, которые отключают предупреждения об устаревании.
  • Выполните приведенные выше действия через плагины сервера SCI, пользовательские правила проверки стиля или (если хотите быть грубыми), "подбросив" исходный код.
  • Возьмите (метафорическую) большую палку программистам, которые являются повторными преступниками.

Существуют ли запланированные функции JRE / JDK, которые могут помочь в этой ситуации?

Как уже отмечалось, улучшенная поддержка аннотаций в Java 9+ (см. JEP 277 ):

  • обеспечивает более информативную пометку об устаревании, а
  • предоставляет инструмент (jdeprscan) для сканирования на предмет нарушений устаревания API Java SE.
0 голосов
/ 12 мая 2018

Устаревший API бесполезен, поскольку он помечен @Deprecated.Если клиенты API все еще могут успешно использовать его после того, как годы были помечены как устаревшие, тогда будет правильным сказать, что поставщик API не помогает им каким-либо практическим способом.

Есть ли практическийрешение этой проблемы?

Да: пусть амортизация означает устаревание, а после льготного периода делает устаревший API недоступным, если удаление является правильным способом решения этой проблемы.Если, например, вы отказываетесь от API с рисками безопасности, не удаляя его в будущем выпуске, делает устаревание бесполезным и может рассматриваться как способствующий возникновению проблемы.

Аннотация @Deprecated - это немного больше, чем документация,что, как вы заметили, другие разработчики могут просто игнорировать.

Устаревание Java 9+, возможно, более информативно, но окончательное решение по-прежнему остается за разработчиком, использующим API, который не решает проблему.

...