>
>
>
V6078. Potential Java SE API compatibil…


V6078. Potential Java SE API compatibility issue.

This diagnostic rule detects Java SE APIs that will be removed or marked as deprecated in newer Java SE versions.

New Java SE versions are usually backward-compatible with the earlier versions. That is, an application developed on Java SE 8 should run without problems on Java SE 11. However, small compatibility issues between Java SE versions are still possible. They can be caused by changes to some of the APIs: methods or classes may get removed or deprecated, or their behavior may change, and so on.

If your company's policy about addressing compiler warnings is strict, you can solve some of the problems right away. For example, you could stop using a method or a class marked as deprecated, because such methods or classes are likely to cause your application to behave differently or even crash when moving to a new Java version.

The JDK also includes a tool called 'jdeps', which can help trace your application's dependencies on the JDK's internal APIs. But developers will typically run this tool only when they are about to port the application to a new Java version, while a wiser approach is to start thinking about this at the coding stage, and avoid dependencies on an API that is expected to be removed in the future Java SE releases.

The V6078 diagnostic will warn you beforehand if your code depends on certain functions and classes of Java SE APIs that you may have problems with in the newer Java versions. For instance, you will face such issues when your application is reported to be crashing on a user's machine after updating to a fresher Java version. Besides, it is highly likely that sooner or later you will need to clean up your code base from outdated APIs, so it better to perform such a cleaning on a regular basis instead of increasing your technical dept for the future.

The warning is issued in the following cases:

  • A method/class/package has been removed in the target Java version;
  • A method/class/package has been marked as deprecated in the target Java version;
  • A method's signature has changed.

The rule currently supports compatibility analysis for Oracle Java SE 8 through 14. The V6078 rule is disabled by default. To enable the rule, you will need to activate and configure it.

IntellJ IDEA

When working in the IntelliJ IDEA plugin, you can enable the rule and configure it at the 'Settings > PVS-Studio > API Compatibility Issue Detection' tab in the settings:

  • Source Java SE is the Java version that your application is based on
  • Target Java SE is the Java version that you want to check the compatibility of APIs used in your application (Source Java SE) against
  • Exclude packages are the packages you want to exclude from the compatibility analysis (packages are comma-separated)

Gradle

When working from the Gradle plugin, you need to configure the analyzer's settings in build.gardle:

apply plugin: com.pvsstudio.PvsStudioGradlePlugin
pvsstudio {
    ....
    compatibility = true
    sourceJava = /*version*/  
    targetJava = /*version*/
    excludePackages = [/*pack1, pack2, ...*/]
}

Maven

When working from the Maven plugin, you need to configure the analyzer's settings in pom.xml:

<build>
  <plugins>
    <plugin>
      <groupId>com.pvsstudio</groupId>
      <artifactId>pvsstudio-maven-plugin</artifactId>
      ....
      <configuration>
        <analyzer>
          ....
          <compatibility>true</compatibility>
          <sourceJava>/*version*/</sourceJava>
          <targetJava>/*version*/</targetJava>
          <excludePackages>/*pack1, pack2, ...*/</excludePackages>        
        </analyzer>
      </configuration>
    </plugin>
  </plugins>
</build>

Running the analyzer core directly

If you run the analyzer directly from the command line, use the following parameters to activate the compatibility analysis of selected Java SE APIs:

java -jar pvs-studio.jar /*other options*/ --compatibility 
--source-java /*version*/ --target-java /*version*/ 
--exclude-packages /*pack1 pack2 ... */

Example of V6078 warnings

Suppose we are working on an application based on Java SE 8 and have the following class:

/* imports */
import java.util.jar.Pack200;
public class SomeClass
{
  /* code */
  public static void someFunction(Pack200.Packer packer, ...)
  {
    /* code */
    packer.addPropertyChangeListener(evt -> {/* code */});
    /* code */
  }
}

Different rule settings will produce different results:

  • Source Java SE – 8, Target Java SE – 9
    • The 'addPropertyChangeListener' method will be removed.
  • Source Java SE – 8, Target Java SE – 11
    • The 'addPropertyChangeListener' method will be removed.
    • The 'Pack200' class will be marked as deprecated.
  • Source Java SE – 8, Target Java SE – 14
    • The 'Pack200' class will be removed.

The 'addPropertyChangeListener' method of the class 'Pack200.Packer' was removed in Java SE 9. Next, in Java SE 11, the 'Pack200' class was marked as deprecated. And finally, in the version 14, that class was removed altogether.

Therefore, running your application on Java 11, you will get a 'java.lang.NoSuchMethodError', while running it on Java 14, you will get a 'java.lang.NoClassDefFoundError'.

Knowing about all these changes, you will be forewarned about potential issues of using such an APIs, and can immediately consider finding an alternative APIs for the task at hand.