Revapi Java Extension

Revapi extension to check API of java classes in jar archives.

The Java extension somewhat obviously provides API checking capability for Java libraries. It contains a large number of checks that check different aspects of changes in the API, but it, too, is extensible. That is useful in cases where Java methods are annotated using annotations like JPA or JAXB. One can imagine new checks on methods and fields annotated by those annotations to perform additional analysis for DB schema changes or XML serialization changes.

Detected differences

The Revapi java extension performs a thorough class and method signature analysis and detects quite a large number of (potential) problems and changes of the code in the two versions of the API.

Note
There are over 80 kinds of detected changes (of which some don’t represent an actual problem with the API but merely a compatible change (a change nevertheless)).

You can review all the detected differences here, but as a sneak peak consider the following detected changes:

  • checked exception added/removed to/from method signature - both of these are source incompatible but binary compatible changes,

  • formal type parameter added to class/method signature - this is again source incompatible but binary compatible,

  • non-final method replaced by a final method in superclass - huh, binary compatible, source potentially incompatible, potentially producing VerifyError at linkage time. What is this actually? V1 of the library contained a class C with method m(). Class C inherited from class B. V2 changed this such that C still inherits from B but method m() is now final and declared in B. This change is OK unless client code inherits from C and overrides the method in question.

  • serialVersionUid unchanged - reported when there’s been a change in the class that would change the automatically generated serialization version, but the manually assigned serialVersionUid field remained with the same value in the new version of the library.

  • non-public part of API - a class that is non-public was detected to be reachable from the public API. I.e. there exists a non-public type that is used in a public capacity - as a return type or a parameter of an accessible method - this is checked recursively. E.g. in the example below, the Internal class is flagged:

//------------------------ API.jar

public class API {
  public Model getModel() {
    return null;
  }
}

//------------------------ Dependency.jar

public class Model {
  protected Internal getState() {
    return null;
  }
}

/*package private*/ class Internal {
}

This is because the api class API returns the Model class from its public method and therefore makes the Model class formally part of the API even though it comes from a dependency. The Model class then is non-final and returns an Internal instance from its method. Thus, it is conceivable that a user of the API.jar might want to extend and use the Model class at which point he’d be unable to use the correct type of the getState() result.

SPI

The Java extension can be augmented through its small SPI that declares a hook interface into the java checking process that represents the Revapi’s API elements as Java’s own model elements. The checking framework then can use the Java plaform’s own rich functionality for examining the classes in the checked libraries (note, that this API is NOT the reflection API, because it actually doesn’t load the library classes into Java runtime).

You can walk through the example Java check to see how to extend the Java checks.

Back to top

Msb3 Maven skin by Marek Romanowski.