Java Deprecated APIs and SuppressWarnings "deprecation" - practical approach

Rann Lifshitz :

I have seen many examples of using the Deprecated annotation on APIs in order to mark them as 'need to be replaced soon'.

However, in almost all of these cases the code developers not only kept using the deprecated APIs, but also suppressed the deprecation warning.

It seems like the best intentions of the API developers end up creating more code which is irrelevant to the implemented business logic - if an API is deprecated but is continually used with the associated warnings being suppressed it seems like a degradation of the code at best and a potential application breaking point when replacing deprecated libraries at worst IMHO.

Is there a practical solution to this problem? At the very least, a way to tag this occurrence as a code smell, if it indeed stays for a relatively long time in the CR?

Please suggest an actual solution you might be using (library, SCA, CR plugin, etc.....)

Are there any planned JRE/JDK features that might help with this situation? My research has currently not found anything.

References:

Jens Bannmann :

Step 1: Announce the removal

One may think that deprecating an API means announcing it will be removed, but this is not the only use case (as described in relevant articles of e.g. Java 7 and Java 9):

  • The API is dangerous (for example, the Thread.stop method).

  • There is a simple rename (for example, AWT Component.show/hide replaced by setVisible).

  • A newer, better API can be used instead.

  • The deprecated API is going to be removed.

To further complicate things, before Java 9, no deprecated API in the JDK was ever removed (see 20 Years Of Java Deprecation), so it is understandable if developers do not take deprecation seriously - neither in the JDK nor elsewhere.

Therefore, you need to communicate clearly that the API is really, really going to be removed. The way to do this depends on the version of Java your API is compiled with.

Java 8 or lower

In these Java versions, there is no formal way to explicitly distinguish the various deprecation use cases. The best you can do is adding the Javadoc tag @deprecated and not only giving the reason of deprecation and listing alternatives, but also explicitly announcing your intention to remove the API.

Java 9 or above

Since Java 9, with Enhanced Deprecation, you can now write

@Deprecated(forRemoval=<boolean>)

to explicitly document your intention. I think that together with Javadoc @deprecated (which should detail the reason for deprecation and list alternatives), this standardized flag is a fair warning.

With this flag set to true, the compiler will warn for each use of the deprecated element like this:

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

This warning is enabled by default (instead of having to be enabled with -Xlint:deprecation) and is not suppressed with @SuppressWarnings("deprecation"). Instead, one would have to suppress it with the new @SuppressWarnings("removal"), which might make developers think twice about doing so without a really good reason.

Additionally, you can explicitly state the library version which introduced the deprecation with

@Deprecated(since="<version>")

Seeing this in Javadoc or the sources can help developers assess how urgent it is update their code.

Step 2a: Runtime warning

If feasible for the situation, add a runtime reminder: when the deprecated API is used, have it log a warning to the console or log file (using whatever logging mechanism you use) announcing that this will no longer work with the next major release. To avoid spam, you could only log that once (e.g. private static boolean warningLogged).

Step 2b: Static code analysis

Static code analyzers like SonarQube (also available as a hosted service) can be set up to flag each of these warnings. The SonarQube rule "deprecated code should not be used" should even work if the compiler's deprecation usage warning is suppressed.

SonarQube also tracks when a certain issue (i.e. a rule violation) was introduced (based on version control) and you can interactively filter its issue lists based on that date. For example, you could list all usages of deprecated code that have been in your code base for over a year so that you can prioritize work on fixing them.

Step 3: Remove the API

Not actually removing the API would give your API users the impression that they don't need to bother changing their code.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=468414&siteId=1