Japitools

Java API compatibility testing tools

japicompat

Next, you can perform the test for compatibility between these two files:

$ japicompat jdk11.japi.gz kaffe.japi.gz

The full list of flags supported by japicompat is as follows:

japicompat [-svqhtjw] [-o <outfile>] [-i <ignorefile>] <original api> <api to check>

The meanings of these options are as follows:

-s

By default, japicompat tests for binary compatibility as defined by the JLS, plus a couple of additions (see below for details). You can turn off these additions by passing the -s flag to japicompat, for example:

$ japicompat -s jdk11.japi.gz kaffe.japi.gz

The s stands for "sun", "standard", "specification", or if you like more colorful language, "single-buttocked" (one buttock=half an...). See "What exactly does japicompat test?" below for exactly what tests get turned off by this flag.

-v

By default, japicompat only checks for errors that break binary compatibility. However, japicompat can also check for some "minor" compatibility problems. To activate these additional checks, use the "-v" flag. The v stands for "verbose".

$ japicompat -v jdk11.japi.gz kaffe.japi.gz

Specifically, the -v flag enables the following additional checks:

  • SerialVersionUID checking: japicompat reports a minor error if a Serializable class has a different SerialVersionUID between the two releases.
  • Deprecation checking: japicompat reports a minor error if a class or member was deprecated in the original API but is not deprecated in the API being checked.

-q

By default, japicompat provides progress reports as it runs. In unix terminology, these are sent to stderr (the actual results are sent to stdout unless the -o flag is used). The -q flag turns off these progress reports - only real errors will be sent to stderr.

-h

Generate output in HTML format. The HTML files produced depend on the japi.css file in the design directory to get attractive presentation.

-t

Generate output in text format. This is the default.

-j

Generate output in raw machine readable form. The format produced is called "japio" format, and by convention should be saved with a ".japio" file extension. The standalone japiotext and japiohtml utilities can be used to convert this format into html or text (actually, japicompat calls japiotext or japiohtml internally if the -h or -t flags are used). Japio files can also be used with the -i flag to support ignoring errors caused by incompatibilities between JDK versions.

-w

By default japicompat will produce warnings if run against japi files originally generated by older versions of japitools that had known bugs that japifix cannot eliminate. Use the -w flag to turn off these warnings, or better yet, generate your japi files with the latest version ;)

-o <outfile>

Send the output to <outfile> instead of stdout. The format of this file depends on the -h, -t and -j flags.

-i <ignorefile>

Suppose you are attempting to implement the Java API. You have (pretty much) completed coverage of the early JDK versions (1.0 and 1.1) but still have some distance to achieve full coverage of 1.4 (this is an accurate description of all Free Software Java implementations at the time of writing). Using japicompat to compare your implementation with JDK 1.4 gives accurate results, but you might also want to show your coverage of the earlier versions.

Unfortunately Sun has not followed their own binary compatibility rules between JDK releases, let alone the expanded rules that japicompat tests for. So when you run a comparison between JDK 1.1 and your implementation, you will get spurious error reports when you're compatible with 1.4 but not 1.1.

Obviously what you really want is to ignore errors like this, and japicompat provides a way to do so. First, run a comparison between 1.1 and 1.4 using the -j switch. Then run the comparison between 1.1 and your implementation, passing the "-i" option with the output of the previous run. For example:

$ japicompat -jvo ignore-11-14.japio jdk11.japi.gz jdk14.japi.gz
$ japicompat -hvo jdk11-myimpl.html -i ignore-11-14.japio jdk11.japi.gz myimpl.japi.gz

(In this example I also passed the -v flag but didn't pass -s. You should use the same combination of these two flags for both runs of japicompat to avoid getting bad results)

You can also get the same effect by running:

$ japicompat -hvo jdk11-myimpl.html -i jdk14.japi.gz jdk11.japi.gz myimpl.japi.gz

This is obviously simpler and quicker to type, but requires the comparison between jdk11 and jdk14 to be run every single time. Making the japio file manually allows for it to be saved and used again the next time, which lets japicompat run about twice as fast.

<original api> <api to check>

The japi files corresponding to the APIs to be compared.

japicompat specifically tests that the second argument is backwardly-compatible with the first. Therefore, a perfect implementation of JDK 1.1 would produce no errors regardless of the order of the arguments, but a perfect implementation of JDK1.1 plus parts of JDK1.2 should be tested as follows:

$ japicompat jdk11.japi.gz myimpl.japi.gz
$ japicompat myimpl.japi.gz jdk12.japi.gz

It is probably impossible to make an implementation that passes both these tests, since Sun's own JDK1.2 produces numerous errors when tested against JDK1.1. See the discussion of the -i option above for a way to cope with this situation.

Either compressed (.japi.gz) or uncompressed (.japi) files can be passed to japicompat: The file extension is used to determine whether or not to pipe input through gzip or not.