Revapi Java Extension

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

Identifying Problematic Element

When Revapi reports the found API problems it needs to pinpoint the element it is "talking about". Therefore it assigns a one-line representation to each API element to identify it. It tries to follow the conventions of Java syntax but needs to go beyond it to express additional information.

First, let’s go through some simple examples.

class com.example.MyClass

This somewhat obviously refers to a class called MyClass in the com.example package.

class com.example.MyGenericClass<T extends java.lang.Number>

This again refers to the class but you can see that Revapi also includes the type parameters in the class name. Note that the bounds of the type parameters are specified using fully qualified class names.

interface com.example.MyInterface

Here we see that different kinds of classes are distinguished. Revapi uses @interface for annotation types, enum for enumerations, interface for interfaces and class for ordinary classes.

missing-class com.example.Whoops

What’s this? Here, Revapi tries to convey that the class in question wasn’t found anywhere on the classpath.

method java.lang.String com.example.MyClass::myMethod(int, long)

If you are familiar with the method reference syntax in Java 8, you may guess that the above refers to a method called myMethod declared in the com.example.MyClass class that returns a java.lang.String and accepts an int as its first argument and a long as its second argument. As with classes, the type mentioned in the method identifier may include the type parameters. The method identifier also includes the throws declaration if present on the method.

parameter java.lang.String com.example.MyClass::myMethod(int, ===long===)

If Revapi needs to "talk" about a single parameter of a method, it encloses the parameter in ===. The above therefore identifies the second parameter of the method myMethod.

field com.example.MyClass.myField

Quite intuitively, the above identifies the field called myField in the class com.example.MyClass.

method void com.example.MySuperClass::superMethod() @ com.example.MyClass

This is again a little bit cryptic. The above identifies the method superMethod declared in com.example.MySuperClass as seen in com.example.MyClass. In another words, Revapi distinguishes between a declared method and inherited method. This is because a public method in a private class can be made "accessible" in the API if the private class is inherited by some public class in the API.

Types
class the.fully.qualified.class.name.including.Any<Type extends Params>

where class can be class, interface, enum or @interface depending on the kind of class in question, or in case the type is missing in the API:

missing-class fully.qualified.class.name.including.Any<Type extends Params>
Methods

Declared method:

method ReturnType fully.qualified.class.name.of.the.declaring.class::methodName(All, The, Params) throws Any, Exceptions

Inherited method:

method ReturnType fully.qualified.class.name.of.the.declaring.class::methodName(All, The, Params) throws Any, Exceptions @ the.class.that.inherits.the.Method

Revapi distinguishes between declared and inherited methods because a public method in a private class can be made "accessible" in the API if the private class is inherited by some public class in the API.

Method Parameters

This is where the syntax differs most from java. The === highlight the parameter in question among the others. Note also that the parameter names are not available because more often than not they’re not available in the bytecode.

Parameter on a declared method:

parameter ReturnType class.name.of.declaring.class::methodName(===ParameterType===, Other, Params)

Parameter on an inherited method:

parameter ReturnType class.name.of.declaring.class::methodName(===ParameterType===, Other, Params) @ class.name.of.inheriting.class

Because method parameter is tied to the method, the distinction between a declared and inherited method is exhibited in the identifier of the method parameter, too.

Fields

Declared field:

field fully.qualified.class.name.of.declaring.class.fieldName

Inherited field:

field fully.qualified.class.name.of.declaring.class.fieldName @ class.that.inherits.the.Field

As with methods, the distinction between a declared and inherited field is quite important.

Match Parameters

In addition to a human-readable representation of the element outlined above, the differences can also be matched by their additional parameters. Each of the below differences lists the parameters that can be matched against.

For example the java.class.noLongerImplementsInterface difference defines the match parameter interface. This can be used when matching the difference for example in the revapi.ignore extension:

{
  "regex": true,
  "code": "java\\.class\\.noLongerImplementsInterface",
  "old": "class my\\..*",
  "interface": "my\\.Interface"
}

The above will instruct Revapi to not report the removal of my.Interface from the list of implemented interfaces on any class in the my package (or any other subpackage).

All types of differences report the elementKind parameter that can have 1 of the following values:

class

The element is an ordinary class

interface

The element is an interface

enum

The element is an enum class

@interface

The element is an annotation class

constructor

The element is a constructor

enumConstant

The element is an enum constant

field

The element is a field

method

The method is a method

parameter

The element is a method parameter

annotation

The element is an annotation of another element

Additionally, if the analyzer is configured to report example use chains for given difference (see the java extension configuration), there will be 1 or 2 more parameters with the example use chains present: exampleUseChainInOldApi and/or exampleUseChainInNewApi.

Detected Differences

All the differences detected by the extension are defined in the Code enumeration. Below, you can find a short discussion of each type of the difference.

Missing API Class

Code

java.missing.oldClass or java.missing.newClass

Binary severity

potentially breaking

Source severity

potentially breaking

Semantic severity

NA

By default, Revapi will report any type that should belong to the API but cannot be found neither in the API libraries themselves or in the supporting libraries. It can also be configured to ignore such missing classes or to abort the API check altogether. If it is configured to report them (which is the default), one of the above codes will be emitted depending on whether the missing class is found in the old version of the API or the new one.

The missing class behavior can be configured by the revapi.java.missing-classes configuration property with the possible values of ignore, report and error, e.g.:

{
    "revapi" : {
        "java" : {
            "missing-classes" : "ignore"
        }
    }
}
Match parameters

package

the package of the class

classSimpleName

the simple name of the class

elementKind

See Match Parameters for possible values

Element No Longer Deprecated

Code

java.element.noLongerDeprecated

Binary severity

equivalent

Source severity

equivalent

Semantic severity

NA

An element (class, method or field) is marked as deprecated in the old version of the API but not in the new version. This represents no danger in terms of API breakage and is reported only because it is useful to know for the library users to know about such cases.

Match parameters

annotationType

exactly @java.lang.Deprecated.

elementKind

See Match Parameters for possible values

Element Now Deprecated

Code

java.element.nowDeprecated

Binary severity

equivalent

Source severity

equivalent

Semantic severity

NA

An element (class, method or field) is marked as deprecated in the new version of the API but not in the old version. This represents no danger in terms of API breakage and is reported only because it is useful to know for the library users to know about such cases.

Match parameters

annotationType

exactly @java.lang.Deprecated.

elementKind

See Match Parameters for possible values

Class Visibility Increased

Code

java.class.visibilityIncreased

Binary severity

equivalent

Source severity

equivalent

Semantic severity

NA

The class is more visible in the new version of the API than it used to be in the old version. This is no API breakage and is reported for completeness sake. The visibility is ordered as follows: private < package private < protected < public.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

oldVisibility

The visibility of the type as it was in the old version.

newVisibility

The visibility of the type in the new version.

elementKind

See Match Parameters for possible values

Class Visibility Reduced

Code

java.class.visibilityReduced

Binary severity

breaking

Source severity

breaking

Semantic severity

NA

Reducing the visibility of an API class is a breaking change. It means that classes that could inherit or use the class might no longer be able to. Thus a library user might face compilation errors at compile time or linkage errors at runtime when trying to use the new version of the library.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

oldVisibility

The visibility of the type as it was in the old version.

newVisibility

The visibility of the type in the new version.

elementKind

See Match Parameters for possible values

Class Kind Changed

Code

java.class.kindChanged

Binary severity

breaking

Source severity

breaking

Semantic severity

NA

There are 4 kinds of java classes: class, interface, annotation type, enum. This difference is reported when a class changes from one to the other. This is of course incompatible change and will break the library users at both compile time and at runtime.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

oldKind

The kind of the type as it was in the old version.

newKind

The kind of the type in the new version.

elementKind

See Match Parameters for possible values

Class No Longer Final

Code

java.class.noLongerFinal

Binary severity

equivalent

Source severity

equivalent

Semantic severity

NA

A class that used to be final is now not. This is no API breakage and is reported for completeness sake.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

oldModifiers

The sorted modifiers on the class in the old version.

newModifiers

The sorted modifiers on the class in the new version.

elementKind

See Match Parameters for possible values

Note
Modifiers are sorted according to the Java style guidelines in the following order: public protected private abstract static final transient volatile default synchronized native strictfp.

Class Now Final

Code

java.class.nowFinal

Binary severity

breaking

Source severity

breaking

Semantic severity

NA

A class became final in the new version of the library. This is a breaking change because any library user that extended the class will no longer be compatible with the new version of the library, in which the class cannot be extended.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

oldModifiers

The sorted modifiers on the class in the old version.

newModifiers

The sorted modifiers on the class in the new version.

elementKind

See Match Parameters for possible values

Note
See Class No Longer Final for the ordering of the modifiers.

Class No Longer Abstract

Code

java.class.noLongerAbstract

Binary severity

equivalent

Source severity

equivalent

Semantic severity

NA

A class that used to be abstract is now not. This is no API breakage and is reported for completeness sake.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

oldModifiers

The sorted modifiers on the class in the old version.

newModifiers

The sorted modifiers on the class in the new version.

elementKind

See Match Parameters for possible values

Note
See Class No Longer Final for the ordering of the modifiers.

Class Now Abstract

Code

java.class.nowAbstract

Binary severity

breaking

Source severity

breaking

Semantic severity

NA

A concrete class became abstract in the new version of the library. This is a breaking change because it is no longer possible to create instances of such class.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

oldModifiers

The sorted modifiers on the class in the old version.

newModifiers

The sorted modifiers on the class in the new version.

elementKind

See Match Parameters for possible values

Note
See Class No Longer Final for the ordering of the modifiers.

Class Added

Code

java.class.added

Binary severity

non breaking

Source severity

non breaking

Semantic severity

NA

A new class appeared in the new version of the API. This is a non-breaking change reported for completeness sake.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

elementKind

See Match Parameters for possible values

Class Removed

Code

java.class.removed

Binary severity

breaking

Source severity

breaking

Semantic severity

NA

A class present in the old version of the library is no longer present. This is of course a breaking change because the users of the API will no longer be able to use that class in any capacity.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

elementKind

See Match Parameters for possible values

External Class Exposed In API

Code

java.class.externalClassExposedInAPI

Binary severity

non-breaking

Source severity

non-breaking

Semantic severity

potentially breaking

This is reported for classes from dependencies that are exposed in the API (for example as a return value). This is generally discouraged practice because it makes updating the dependency version a more complex task (you want a bugfix but you don’t want the changed API to leak to your users).

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

elementKind

See Match Parameters for possible values

External Class No Longer Exposed In API

Code

java.class.externalClassNoLongerExposedInAPI

Binary severity

non-breaking

Source severity

non-breaking

Semantic severity

NA

An opposite of External Class Exposed In API. This is non-breaking, because the class is still accessible on the classpath so users that used to rely on it can still access it. The class is just no longer exposed in the API (which will usually cause other differences to be reported, too).

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

elementKind

See Match Parameters for possible values

Class No Longer Implements Interface

Code

java.class.noLongerImplementsInterface

Binary severity

breaking

Source severity

breaking

Semantic severity

NA

This is a breaking change because it is no longer possible to cast the class to the no longer implemented interface.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

interface

The fully qualified name of the interface that is no longer implemented.

elementKind

See Match Parameters for possible values

Class Now Implements Interface

Code

java.class.nowImplementsInterface

Binary severity

non breaking

Source severity

non breaking

Semantic severity

NA

No API breakage reported for the completeness sake.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

interface

The fully qualified name of the interface that is now implemented.

elementKind

See Match Parameters for possible values

Final Class Inherits From New Class

Code

java.class.finalClassInheritsFromNewClass

Binary severity

equivalent

Source severity

equivalent

Semantic severity

NA

A final class inherits from a new class. This represents no API breakage and is reported for completeness sake. Inheriting from a new class may introduce new methods or fields to the class but cannot remove any (method changes are reported separately).

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

superClass

The fully qualified name of the new super class.

elementKind

See Match Parameters for possible values

Non-final Class Inherits From New Class

Code

java.class.nonFinalClassInheritsFromNewClass

Binary severity

potentially breaking

Source severity

potentially breaking

Semantic severity

NA

While this change is usually OK, it might cause trouble to the users of the API if the newly inherited class contains final methods. If the users of the library happen to define methods of the same name in the class that inherits from the checked one, they will get compilation or linkage errors.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

superClass

The fully qualified name of the new super class.

elementKind

See Match Parameters for possible values

Class Now Checked Exception

Code

java.class.nowCheckedException

Binary severity

non breaking

Source severity

breaking

Semantic severity

NA

A class newly inherits from java.lang.Exception. This is a source incompatibility because such exceptions need to be declared in the throws declarations of the methods.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

elementKind

See Match Parameters for possible values

Class No Longer Inherits From Class

Code

java.class.noLongerInheritsFromClass

Binary severity

breaking

Source severity

breaking

Semantic severity

NA

The checked class no longer inherits from a super class that it used to. This means that it can no longer be cast to that super class nor can the methods declared in the super class be called using the instance of the checked class.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

superClass

The fully qualified name of the superclass that is no longer inherited.

elementKind

See Match Parameters for possible values

Class Is Non-Public Part of API

Code

java.class.nonPublicPartOfAPI

Binary severity

non breaking

Source severity

non breaking

Semantic severity

breaking

While this is non-breaking from the pure API compatibility point of view, it is a very strange design decision. This means that a class that is not publicly accessible (i.e. is private or package private) is used in a public capacity (i.e. return type of a method, type of a method parameter, type of an accessible field, implemented interface).

By default, Revapi even outputs the "usage chain" from some public API element to the non-public class.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

elementKind

See Match Parameters for possible values

Note
This is NOT reported on a non-accessible class that is used solely as a super class of another API classes or that is only implemented by other API classes. An implementation of a private interface or inheriting from a non-public super class is a valid design decision.

Type Parameters of The Super Type Changed

Code

java.class.superTypeTypeParametersChanged

Binary severity

potentially breaking

Source severity

potentially breaking

Semantic severity

NA

The checked class inherits from a generic class. The type parameters used on the generic super class changed between old and new version. Because of type erasure, this might not cause any binary incompatibility (but it can) and it can potentially break the compilation, too.

This is generally a quite dangerous thing to do, because it can change the erased signatures of the methods or fields inherited from the super class (which would be the cause of the binary and source incompatibilities).

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

oldSuperType

The old signature of the super type.

newSuperType

The new signature of the super type.

elementKind

See Match Parameters for possible values

Annotation Added

Code

java.annotation.added

Binary severity

equivalent

Source severity

equivalent

Semantic severity

potentially breaking

An element is newly annotated by given annotation. This poses no risk during compilation or at linkage time but may cause semantic differences between the versions because of the way the annotations can be used (code generation, processing, reflection, etc.).

Match parameters

annotationType

The fully qualified name of the annotation type, preceded by @ (e.g. @java.lang.annotation.Target).

elementKind

See Match Parameters for possible values

Annotation Removed

Code

java.annotation.removed

Binary severity

equivalent

Source severity

equivalent

Semantic severity

potentially breaking

An element is no longer annotated by given annotation. This poses no risk during compilation or at linkage time but may cause semantic differences between the versions because of the way the annotations can be used (code generation, processing, reflection, etc.).

Match parameters

annotationType

The fully qualified name of the annotation type, preceded by @ (e.g. @java.lang.annotation.Target).

elementKind

See Match Parameters for possible values

Annotation Attribute Value Changed

Code

java.annotation.attributeValueChanged

Binary severity

equivalent

Source severity

equivalent

Semantic severity

potentially breaking

An attribute of some annotation on some element changed its value. This poses no risk during compilation or at linkage time but may cause semantic differences between the versions because of the way the annotations can be used (code generation, processing, reflection, etc.).

Match parameters

attribute

The name of the attribute that changed value

annotationType

The fully qualified name of the annotation type, preceded by @ (e.g. @java.lang.annotation.Target).

oldValue

The old value of the attribute.

newValue

The new value of the attribute.

elementKind

See Match Parameters for possible values

Annotation Attribute Added

Code

java.annotation.attributeAdded

Binary severity

equivalent

Source severity

equivalent

Semantic severity

potentially breaking

An annotation on some element newly specifies an explicit value of an attribute. This poses no risk during compilation or at linkage time but may cause semantic differences between the versions because of the way the annotations can be used (code generation, processing, reflection, etc.).

Match parameters

attribute

The name of the attribute that was added

annotationType

The fully qualified name of the annotation type, preceded by @ (e.g. @java.lang.annotation.Target).

value

The value of the attribute.

elementKind

See Match Parameters for possible values

Annotation Attribute Removed

Code

java.annotation.attributeRemoved

Binary severity

equivalent

Source severity

equivalent

Semantic severity

potentially breaking

An annotation on some element no longer specifies an explicit value of an attribute. This poses no risk during compilation or at linkage time but may cause semantic differences between the versions because of the way the annotations can be used (code generation, processing, reflection, etc.).

Match parameters

attribute

The name of the attribute that was removed,

value

The value of the attribute that was removed,

annotationType

The fully qualified name of the annotation type, preceded by @ (e.g. @java.lang.annotation.Target).

elementKind

See Match Parameters for possible values

Annotation No Longer Inherited

Code

java.annotation.noLongerInherited

Binary severity

non breaking

Source severity

non breaking

Semantic severity

potentially breaking

An annotation type used to be annotated with the @Inherited annotation but is no more. This poses no risk during compilation or at linkage time but may cause semantic differences between the versions because of the way the annotations can be used (code generation, processing, reflection, etc.).

Match parameters

annotationType

exactly @java.lang.annotation.Inherited.

elementKind

See Match Parameters for possible values

Annotation Now Inherited

Code

java.annotation.nowInherited

Binary severity

non breaking

Source severity

non breaking

Semantic severity

potentially breaking

An annotation type is now annotated with the @Inherited annotation. This poses no risk during compilation or at linkage time but may cause semantic differences between the versions because of the way the annotations can be used (code generation, processing, reflection, etc.).

Match parameters

annotationType

exactly @java.lang.annotation.Inherited.

elementKind

See Match Parameters for possible values

Static Field Added

Code

java.field.addedStaticField

Binary severity

non breaking

Source severity

non breaking

Semantic severity

NA

No API breakage, provided for completeness sake. Note that this si reported only for publicly accessible fields.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

fieldName

the name of the field

elementKind

See Match Parameters for possible values

Field Added

Code

java.field.added

Binary severity

non breaking

Source severity

non breaking

Semantic severity

NA

No API breakage, provided for completeness sake. Note that this si reported only for publicly accessible fields.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

fieldName

the name of the field

elementKind

See Match Parameters for possible values

Field Removed

Code

java.field.removed

Binary severity

breaking

Source severity

breaking

Semantic severity

NA

The field was removed from the class. This is an API breakage because the field can no longer be accessed. Note that this si reported only for publicly accessible fields.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

fieldName

the name of the field

elementKind

See Match Parameters for possible values

Constant Field Removed

Code

java.field.removedWithConstant

Binary severity

non-breaking

Source severity

breaking

Semantic severity

potentially breaking

The field with a constant value was removed from the class. This is source incompatible because the field can no longer be accessed. It is binary compatible though because the field is actually never used because all its uses are inlined. Note that this si reported only for publicly accessible fields.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

fieldName

the name of the field

elementKind

See Match Parameters for possible values

Field Moved To Superclass

Code

java.field.movedToSuperclass

Binary severity

equivalent

Source severity

equivalent

Semantic severity

NA

The field was moved to a super class. From the point of view of the field user this represents no noticeable change.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

fieldName

the name of the field

oldClass

The class the field used to be declared in.

newClass

The class the field is now declared in.

elementKind

See Match Parameters for possible values

Inherited Field Now Declared On Class

Code

java.field.inheritedNowDeclared

Binary severity

equivalent

Source severity

equivalent

Semantic severity

NA

A field that was previously inherited is now declared on the class. From the point of view of the field user this represents no noticeable change. If the field was also removed from the super class, it will be reported separately.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

fieldName

the name of the field

oldClass

The class the field used to be declared in.

newClass

The class the field is now declared in.

elementKind

See Match Parameters for possible values

Constant Field Removed

Code

java.field.removed

Binary severity

non breaking

Source severity

breaking

Semantic severity

potentially breaking

An accessible static final field (i.e. a constant) was removed from the class. This breaks compilation but actually causes no problem at runtime (i.e. when the new API is swapped for the old API without recompiling the users of the API). This is because the constants are inlined during compilation. Because the value is no longer declared or used in the API but the user of the API still can operate with the value, this is also reported as potentially breaking the semantics.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

fieldName

the name of the field

elementKind

See Match Parameters for possible values

Constant Field Changed Value

Code

java.field.constantValueChanged

Binary severity

non breaking

Source severity

non breaking

Semantic severity

breaking

A constant field changed its value. At compilation time, the new value is used, but at runtime (i.e. when the new API is swapped for the old API without recompiling the users of the API) the users of the API will still use the old value, because the constant values are inlined. This is therefore reported as breaking the semantics.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

fieldName

the name of the field

oldValue

The old value of the constant field.

newValue

The new value of the constant field.

elementKind

See Match Parameters for possible values

Field Now Constant

Code

java.field.nowConstant

Binary severity

equivalent

Source severity

equivalent

Semantic severity

potentially breaking

This is no API breakage but has consequences for the user code. As a constant, the field will now be inlined in the user code, which is something that didn’t happen before. You may want to re-evaluate that decision.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

fieldName

the name of the field

value

The constant value of the field.

elementKind

See Match Parameters for possible values

Field No Longer Constant

Code

java.field.noLongerConstant

Binary severity

equivalent

Source severity

equivalent

Semantic severity

breaking

When compiling an API user against the new version of the API, the value of the field is taken. When swapping the new version of the API for the old version of the API without recompiling the old value coming from the inlined constant value from the old version of the API is used. I.e. the code works and therefore this is neither a source nor binary incompatibility, but it is marked as a semantic incompatibility, because the behavior described above is most probably NOT what the API author had in mind when making the change.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

fieldName

the name of the field

value

The constant value the field used to have.

elementKind

See Match Parameters for possible values

Field Now Final

Code

java.field.nowFinal

Binary severity

potentially breaking

Source severity

potentially breaking

Semantic severity

NA

A field that could previously be assigned to is now final and cannot be changed. This is therefore both source and binary incompatibility.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

fieldName

the name of the field

elementKind

See Match Parameters for possible values

Field No Longer Final

Code

java.field.noLongerFinal

Binary severity

non breaking

Source severity

non breaking

Semantic severity

NA

This is no API breakage and is reported for completeness' sake.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

fieldName

the name of the field

elementKind

See Match Parameters for possible values

Field No Longer Static

Code

java.field.noLongerStatic

Binary severity

breaking

Source severity

breaking

Semantic severity

NA

A static field has become an instance field. Accessing the field is no longer possible through its class and therefore this is both source and binary incompatibility.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

fieldName

the name of the field

elementKind

See Match Parameters for possible values

Field Now Static

Code

java.field.nowStatic

Binary severity

breaking

Source severity

non breaking

Semantic severity

NA

According to the Java specification, the Java runtime will throw IncompatibleClassChangeError when an instance field has become static and the new version of API is used against the user code compiled against the old version of API. When recompiling the user code against the new version, everything works fine.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

fieldName

the name of the field

elementKind

See Match Parameters for possible values

Field Type Changed

Code

java.field.typeChanged

Binary severity

breaking

Source severity

breaking

Semantic severity

NA

The field has a different type than it used to in the old version of the API. This is incompatible change.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

fieldName

the name of the field

oldType

The fully qualified name of the old field type.

newType

The fully qualified name of the new field type.

elementKind

See Match Parameters for possible values

Field serialVersionUID Unchanged

Code

java.field.serialVersionUIDUnchanged

Binary severity

equivalent

Source severity

equivalent

Semantic severity

potentially breaking

This is reported on the serialVersionUID fields of classes that didn’t change between the versions even though the default UIDs would be different for the two versions of the the class. While this doesn’t break the compilation nor does it break binary compatibility, it possibly may cause semantic problems because serialization may misbehave. This depends on if and how the readObject and writeObject methods on the class are implemented, which is beyond the scope of this check.

The behavior of this check can be configured using the revapi.java.checks.serialVersionUID.changeDetection configuration attribute. The default value of this attribute is structural meaning that the difference is reported only for classes that somehow change structurally between versions (i.e. a field is added/deleted or its type changed). When specifying jvm as the change detection algorithm the default serialVersionUID is computed for both old and new version of the class. This is more "sensitive" than the structural change because it also considers any changes to methods or static fields of the class (but it nevertheless is the algorithm that the JVM itself uses for computing the default serialization UID of a class).

Example of the configuration in both XML and JSON:

<revapi.java>
  <checks>
    <serialVersionUID>
      <changeDetection>structural</changeDetection>
    </serialVersionUID>
  </checks>
</revapi.java>

or

{
  "extension": "revapi.java",
  "configuration": {
    "checks": {
      "serialVersionUID": {
        "changeDetection": "jvm"
      }
    }
  }
}
Match parameters

package

the package of the class

classSimpleName

the simple name of the class

fieldName

the name of the field

elementKind

See Match Parameters for possible values

Field Visibility Increased

Code

java.field.visibilityIncreased

Binary severity

equivalent

Source severity

equivalent

Semantic severity

NA

No API breakage, reported for completeness' sake.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

fieldName

the name of the field

oldVisibility

The visibility of the type as it was in the old version.

newVisibility

The visibility of the type in the new version.

elementKind

See Match Parameters for possible values

Field Visibility Reduced

Code

java.field.visibilityReduced

Binary severity

breaking

Source severity

breaking

Semantic severity

NA

Field’s visibility was reduced, which means that code that used to be able to access it might no longer be able to.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

fieldName

the name of the field

oldVisibility

The visibility of the type as it was in the old version.

newVisibility

The visibility of the type in the new version.

elementKind

See Match Parameters for possible values

Enum Constant Order Changed

Code

java.field.enumConstantOrderChanged

Binary severity

non breaking

Source severity

non breaking

Semantic severity

potentially breaking

The constants of an enumeration were re-ordered. This can lead to problems in user code that uses the Enum.ordinal() method to determine the order of an enum constant and relies on a specific value.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

fieldName

the name of the field

oldOrdinal

The old ordinal number of the enum value.

newOrdinal

The new ordinal number of the enum value.

elementKind

See Match Parameters for possible values

Default Value Added To Method

Code

java.method.defaultValueAdded

Binary severity

non breaking

Source severity

non breaking

Semantic severity

NA

This is only relevant on annotation types, of which the attributes are represented by method declarations. Declaring a default value to an annotation attribute is not an API breakage and is only reported for completeness' sake.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

value

the default value of the annotation attribute represented by the method

elementKind

See Match Parameters for possible values

Method’s Default Value Changed

Code

java.method.defaultValueChanged

Binary severity

non breaking

Source severity

non breaking

Semantic severity

potentially breaking

This is only relevant on annotation types, of which the attributes are represented by method declarations. Changing a default value is both source and binary compatible but might cause a semantic incompatibility (depending on how the annotation is used). Elements annotated using this annotation that didn’t provide an explicit value for this attribute will suddenly be understood to have the new default value of the attribute when used with the new version of the API. This might or might not be a problem.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

oldValue

the old default value of the annotation attribute represented by the method

newValue

the new default value of the annotation attribute represented by the method

elementKind

See Match Parameters for possible values

Default Value Removed From Method

Code

java.method.defaultValueRemoved

Binary severity

non breaking

Source severity

breaking

Semantic severity

breaking

An annotation attribute no longer declares a default value. This is source incompatible change because elements annotated without explicitly specifying the value for the attribute will no longer compile. This also breaks semantics because annotation processor that relies on the new version of the annotation type will break with a user library that was compiled against the old version of the API (and therefore didn’t have to declare the default value of the attribute).

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

value

the removed default value of the annotation attribute represented by the method

elementKind

See Match Parameters for possible values

Method Added To Interface

Code

java.method.addedToInterface

Binary severity

non breaking

Source severity

breaking

Semantic severity

potentially breaking

This is a source-incompatible change because all implementations that were written against the old version of the interface will not have the implementation of the new method and therefore will not compile.

On contrary, this is binary compatible, because no code that used the old version of the interface could have called the method through the interface. The linker doesn’t check for missing method implementations so the linkage also goes without a problem.

There might be semantic problems though. It might break in situations where the interface serves the purpose of an SPI - a library declares an SPI interface to be implemented by users and then uses these SPI implementations inside the library. If the new version of the library assumes that the SPI implementations provide the impl of the new method and it is provided with the SPI implementation of the old version of the interface, things will break with NoSuchMethodError when the caller tries to call the SPI method backed by the old SPI implementation.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

elementKind

See Match Parameters for possible values

Default Method Added To Interface

Code

java.method.defaultMethodAddedToInterface

Binary severity

non breaking

Source severity

non breaking

Semantic severity

NA

This represents no API breakage and is included for completeness' sake.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

elementKind

See Match Parameters for possible values

Static Method Added To Interface

Code

java.method.staticMethodAddedToInterface

Binary severity

non breaking

Source severity

non breaking

Semantic severity

NA

This represents no API breakage and is included for completeness' sake.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

elementKind

See Match Parameters for possible values

Method With No Default Value Added To Annotation Type

Code

java.method.attributeWithNoDefaultAddedToAnnotationType

Binary severity

non breaking

Source severity

breaking

Semantic severity

breaking

While technically a variant of Method Added To Interface, this is similar in consequences to Default Value Removed From Method. This is not binary incompatible, there can be no code compiled against the previous version of the API that would try to access or use the new attribute in any way. This is source incompatible though, because any code that declares annotations according to the old version of the API will fail to compile against the new version of the API because it will not define explicit value for the new attribute. This also breaks semantics because any element annotated without such attribute won’t be possible to process using a processor that depends on the new version of the API and therefore assumes an explicit value for the annotation attribute.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

elementKind

See Match Parameters for possible values

Method With Default Value Added To Annotation Type

Code

java.method.attributeWithDefaultAddedToAnnotationType

Binary severity

non breaking

Source severity

non breaking

Semantic severity

NA

This does not break compatibility and is reported for completeness' sake.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

elementKind

See Match Parameters for possible values

Abstract Method Added

Code

java.method.abstractMethodAdded

Binary severity

breaking

Source severity

breaking

Semantic severity

NA

Abstract method added to a class. All the code compiled against the old version of the API will not provide a concrete implementation of it and will therefore break.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

elementKind

See Match Parameters for possible values

Method Added

Code

java.method.added

Binary severity

non breaking

Source severity

non breaking

Semantic severity

NA

A new concrete method added to a concrete class. This is always safe.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

elementKind

See Match Parameters for possible values

Final Method Added To Non-final Class

Code

java.method.finalMethodAddedToNonFinalClass

Binary severity

potentially breaking

Source severity

potentially breaking

Semantic severity

NA

This will break user code if the a subclass of the checked class declared a method that happens to have a same signature as the newly introduced final method.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

elementKind

See Match Parameters for possible values

Inherited Method Moved To Class

Code

java.method.inheritedMovedToClass

Binary severity

equivalent

Source severity

equivalent

Semantic severity

NA

A method that was inherited in the old version is now declared in the class (or interface). This is a compatible change. Note that if the super class is part of the API, the removal of the method from that class will be reported separately.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

oldClass

the class that the method was originally declared in

newClass

the class that now declares the method

elementKind

See Match Parameters for possible values

Method Removed

Code

java.method.removed

Binary severity

breaking

Source severity

breaking

Semantic severity

NA

Removing a method from a class is an incompatible change.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

elementKind

See Match Parameters for possible values

Method Moved To Superclass

Code

java.method.movedToSuperClass

Binary severity

equivalent

Source severity

equivalent

Semantic severity

NA

A method that was declared in the class in the old version is now declared in one of its super types. If such move should represent a compatibility breakage it is reported differently, like for example Method Replaced By Abstract In Superclass. Otherwise this is a compatible change and is reported for completeness' sake.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

oldClass

the class that the method was originally declared in

newClass

the class that now declares the method

elementKind

See Match Parameters for possible values

Attribute Removed From Annotation Type

Code

java.method.attributeRemovedFromAnnotationType

Binary severity

breaking

Source severity

breaking

Semantic severity

NA

This is identical to Method Removed but specialized for annotation types.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

elementKind

See Match Parameters for possible values

Method No Longer Final

Code

java.method.noLongerFinal

Binary severity

non breaking

Source severity

non breaking

Semantic severity

NA

No API breakage, reported for completeness' sake.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

oldModifiers

the modifiers on the method in the old version

newModifiers

the modifiers on the method in the new version

elementKind

See Match Parameters for possible values

Method Now Final

Code

java.method.nowFinal

Binary severity

breaking

Source severity

breaking

Semantic severity

NA

Any subclasses that overrode the method will break both at compile time and at runtime.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

oldModifiers

the modifiers on the method in the old version

newModifiers

the modifiers on the method in the new version

elementKind

See Match Parameters for possible values

Method Now Final In Final Class

Code

java.method.nowFinalInFinalClass

Binary severity

equivalent

Source severity

equivalent

Semantic severity

NA

The class is final and cannot be subclassed. Therefore making its method final makes no difference.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

oldModifiers

the modifiers on the method in the old version

newModifiers

the modifiers on the method in the new version

elementKind

See Match Parameters for possible values

Method No Longer Static

Code

java.method.noLongerStatic

Binary severity

breaking

Source severity

breaking

Semantic severity

NA

When a method becomes a member method, it no longer can be called from the static context. This breaks both binary and source compatibility.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

oldModifiers

the modifiers on the method in the old version

newModifiers

the modifiers on the method in the new version

elementKind

See Match Parameters for possible values

Method Now Static

Code

java.method.nowStatic

Binary severity

breaking

Source severity

non breaking

Semantic severity

NA

A static method can be called in the same way as member method, so on the source level, this change is compatible. It is not binary compatible though because static methods are called using a different bytecode instruction.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

oldModifiers

the modifiers on the method in the old version

newModifiers

the modifiers on the method in the new version

elementKind

See Match Parameters for possible values

Method Now Abstract

Code

java.method.nowAbstract

Binary severity

breaking

Source severity

breaking

Semantic severity

NA

If a method becomes abstract, all the inheriting classes will have to implement it even though they didn’t have to before.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

oldModifiers

the modifiers on the method in the old version

newModifiers

the modifiers on the method in the new version

elementKind

See Match Parameters for possible values

Method No Longer Abstract

Code

java.method.noLongerAbstract

Binary severity

non breaking

Source severity

non breaking

Semantic severity

NA

This is a compatible change reported for the completeness' sake.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

oldModifiers

the modifiers on the method in the old version

newModifiers

the modifiers on the method in the new version

elementKind

See Match Parameters for possible values

Method Visibility Increased

Code

java.method.visibilityIncreased

Binary severity

equivalent

Source severity

equivalent

Semantic severity

NA

No API breakage, reported for completeness' sake.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

oldVisibility

The visibility of the type as it was in the old version.

newVisibility

The visibility of the type in the new version.

elementKind

See Match Parameters for possible values

Method Visibility Reduced

Code

java.method.visibilityIncreased

Binary severity

breaking

Source severity

breaking

Semantic severity

NA

A method might no longer be visible to code that used to call it. This is a breaking change.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

oldVisibility

The visibility of the type as it was in the old version.

newVisibility

The visibility of the type in the new version.

elementKind

See Match Parameters for possible values

Method Return Type Changed

Code

java.method.returnTypeChanged

Binary severity

breaking

Source severity

potentially breaking

Semantic severity

NA

While changing the return type always breaks at runtime (i.e. when swapping the new API for the old API without recompiling the user code), it might be OK at compile time due to implicit conversions of primitive types.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

oldType

the old return type

newType

the new return type

elementKind

See Match Parameters for possible values

Method Return Type Changed Covariantly

Code

java.method.returnTypeChangedCovariantly

Binary severity

breaking

Source severity

non breaking

Semantic severity

NA

Covariant return types represent no problem on source level because the new return type can always be cast to the old return type and therefore the users of the old version of the API can work with the new type. This a binary incompatibility though because the method signature changes and users of the old version of the API would get nasty NoSuchMethodError errors at link time.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

oldType

the old return type

newType

the new return type

elementKind

See Match Parameters for possible values

Type Parameters of The Return Type Changed

Code

java.method.returnTypeTypeParametersChanged

Binary severity

non breaking

Source severity

breaking

Semantic severity

NA

If the return type of the method is a generic type and its type parameters change between old and new version of the API it is a source incompatible change. It is binary compatible because of type erasure.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

oldType

the old return type

newType

the new return type

elementKind

See Match Parameters for possible values

Number of Method Parameters Changed

Code

java.method.numberOfParametersChanged

Binary severity

breaking

Source severity

breaking

Semantic severity

NA

Obviously, this is a breaking change - you can no longer call the method with the same parameters.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

elementKind

See Match Parameters for possible values

Method Parameter Type Changed

Code

java.method.parameterTypeChanged

Binary severity

breaking

Source severity

potentially breaking

Semantic severity

NA

This is a binary incompatibility but may be source compatible if the changed types are primitive and the new one is strictly bigger than the old one and the old one is implicitly convertible to it.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

parameterIndex

the index of the method parameter

oldType

the old type of the parameter

newType

the new type of the parameter

elementKind

See Match Parameters for possible values

Method Parameter Type Parameter Changed

Code

java.method.parameterTypeParameterChanged

Binary severity

non breaking

Source severity

potentially breaking

Semantic severity

NA

This problem is reported on method parameters with a generic type if one or more of the type parameters of the generic type changed. This is binary compatible because of the type erasure but it can break source compatibility.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

parameterIndex

the index of the method parameter

oldType

the old type of the parameter

newType

the new type of the parameter

elementKind

See Match Parameters for possible values

Method Now Throws a Checked Exception

Code

java.method.exception.checkedAdded

Binary severity

non breaking

Source severity

breaking

Semantic severity

NA

A method now throws a checked exception. This binary compatible but is not source compatible because the code using the new version of the method will have to be modified to handle the checked exception.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

exception

the fully qualified name of the added exception type

elementKind

See Match Parameters for possible values

Method Now Throws a Runtime Exception

Code

java.method.exception.runtimeAdded

Binary severity

non breaking

Source severity

non breaking

Semantic severity

potentially breaking

This is both source and binary compatible but represents a danger for the semantics of the user code that might want to catch the newly thrown exception.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

exception

the fully qualified name of the added exception type

elementKind

See Match Parameters for possible values

Method No Longer Throws a Checked Exception

Code

java.method.exception.checkedRemoved

Binary severity

non breaking

Source severity

breaking

Semantic severity

NA

A method no longer throws a checked exception. This binary compatible but is not source compatible because the code using the new version of the method fail to compile - the checked exception can no longer be thrown from the method and therefore the catch clauses for it will be invalid.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

exception

the fully qualified name of the removed exception type

elementKind

See Match Parameters for possible values

Method No Longer Throws a Runtime Exception

Code

java.method.exception.checkedRemoved

Binary severity

non breaking

Source severity

non breaking

Semantic severity

NA

This is a compatible change added for completeness' sake.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

exception

the fully qualified name of the removed exception type

elementKind

See Match Parameters for possible values

Method Now Default

Code

java.method.nowDefault

Binary severity

equivalent

Source severity

equivalent

Semantic severity

NA

The method is now a default method. This is completely transparent.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

oldModifiers

the modifiers on the method in the old version

newModifiers

the modifiers on the method in the new version

elementKind

See Match Parameters for possible values

Method No Longer Default

Code

java.method.noLongerDefault

Binary severity

breaking

Source severity

breaking

Semantic severity

NA

The method is no longer default. This means that any implementations of the inteface with the method will now have to supply an implementation for it.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

methodName

the name of the method added

oldModifiers

the modifiers on the method in the old version

newModifiers

the modifiers on the method in the new version

elementKind

See Match Parameters for possible values

Element Now Parameterized

Code

java.generics.elementNowParameterized

Binary severity

non breaking

Source severity

non breaking

Semantic severity

potentially breaking

In and of itself, this is a compatible change but may cause semantic confusion if the user code compiled against the old API wasn’t honoring the new semantics introduced with the generic type parameter (e.g. old code was using raw List and the new version of the API parameterized the list to List<E>. The old code used to insert variety of types into the list but the new version of the API suggests it is not possible. Everything will still work correctly, but new user code might start assuming uniform types in the list).

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

elementKind

See Match Parameters for possible values

Optionally

methodName

the name of the method if it is the newly parameterized element

Formal Type Parameter Added

Code

java.generics.formalTypeParameterAdded

Binary severity

non breaking

Source severity

breaking

Semantic severity

NA

This is not a binary incompatibility due to type erasure but it is a source incompatible change. Classes declared against the old version of the API will no longer compile with the new version because they will be missing the definition of the formal type parameter.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

elementKind

See Match Parameters for possible values

Optionally

methodName

the name of the method if it is the newly parameterized element

Formal Type Parameter Removed

Code

java.generics.formalTypeParameterRemoved

Binary severity

non breaking

Source severity

breaking

Semantic severity

NA

This is not a binary incompatibility due to type erasure but it is a source incompatible change. Classes declared against the old version of the API will no longer compile with the new version because they will be declaring a type parameter that is no longer required.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

elementKind

See Match Parameters for possible values

Optionally

methodName

the name of the method if it is the newly parameterized element

Formal Type Parameter Changed

Code

java.generics.formalTypeParameterChanged

Binary severity

non breaking

Source severity

breaking

Semantic severity

NA

The constraints on the formal type parameter have changed. This is again source incompatible because the user code declared against the old version of the API will use wrong constraints.

Match parameters

package

the package of the class

classSimpleName

the simple name of the class

oldTypeParameter

The old type parameter that changed.

newTypeParameter

The new type parameter.

elementKind

See Match Parameters for possible values

Optionally

methodName

the name of the method if it is the newly parameterized element

Back to top

Msb3 Maven skin by Marek Romanowski.