apidiff

Name

apidiff - compare different versions of an API

Synopsis

apidiff [options]

options
Command-line options

Description

The apidiff command reads source, class and HTML files that provide different versions of an API, compares corresponding declarations in the different versions and writes out an HTML report. The comparison includes:

Options

apidiff provides different groups of options, to specify:

All options have a long form, beginning with --. Some options may have a single-letter form, beginning with just -. For those options that take an argument, the value may be separated from the option name by either white space or '='. In general, as is common with most JDK tools, if an option is repeated, the rule is "last one wins". This rule is modified for the options that specify the APIs to be compared, such that "last one wins" only applies within the group of API-specific options used to define each API.

To see detailed information about how the options are processed, use --verbose options.

The APIs

To specify each of the APIs to be compared, use the --api name option followed by a series of API-specific options that apply to that API.

The API-specific options must at least include options to find the source or class files for the declarations to be compared. The options should also define the location of the generated documentation if that is to be included in the comparison. (When comparing the API documentation, it is not enough to just specify the location of that documentation.)

Note that the API-specific options for each API are separate and distinct from the API-specific options for any other API.

--api name

Specifies a name for the API and sets the current API for use by the API-specific options that immediately follow this option. The name will appear in the generated reports when identifying any differences. If the generated report will be publicly shared, it is recommended that the name should be reasonably meaningful to any readers. A longer, more descriptive label may also be given with the --label option.

The option, and the API-specific options that follow, should be provided for each API to be compared.

The order in which the --api options first appear on the command line determines the order in which any differences are reported. It is recommended to specify the options in chronological order, from the oldest version of the API to the most recent version of the API.

--api-directory directory
Specifies where to find the generated API documentation for the current API. If given, it should be the top-level directory of the documentation generated by the javadoc command for the API.
--jdk-build directory

Specifies a directory containing a JDK build from which to infer values for various options. The builds can either be for default-named configurations in separate repositories or work areas, or for differently named configurations in the same repository. (To create different configurations within the same JDK repository, use the --with-conf-name option when running sh ./configure to create the configuration.)

It is a matter of personal preference whether to use separate repositories or separate configurations within a single repository for the instances of the API to be compared.

  • Using separate repositories uses more disk space, but makes it more convenient to not have to specify the desired configuration every time you run make.
  • Using separate configurations in a single repository uses less disk space, but means that you will have to indicate which configuration to use every time you run make.

When using this option, it should not be necessary to give any additional javac-like options, like --module-path or --release.

For example,

  • --jdk-build repository/build/configuration-name
  • --jdk-build /Users/Duke/jdk-dev/build/macosx-aarch64
  • --jdk-build /Users/Duke/jdk-dev/build/macosx-aarch64-server-release
  • --jdk-build $HOME/OpenJDK/build/linux-x86_64-server-fastdebug
--label text
Specifies a short plain-text label for the API, to be included in the generated reports. For example, the full version string for the instance of the API being compared.

The following API options are similar to the corresponding javac option; see the javac documentation for more details about the arguments for those options.

--class-path path, -classpath path, or -cp path
Specifies where to find files for the class path for the current API.
--enable-preview
Enables preview language features for the current API.
--module-path path or -p path
Specifies where to find application modules for the current API.
--module-source-path module-source-path
Specifies where to find source files for the current API when comparing code in multiple modules.
--patch-module module=path
Overrides or augments a module in the current API with classes and resources in JAR files or directories.
--release release
Specifies the release version for the current API for any source and class files that may be read.
--source release or -source release
Specifies the source version for the current API for any source files that may be read.
--source-path path or -sourcepath path
Specifies where to find source files for the current API. Note that, unlike javac, you cannot use this option to specify where to find the source code for a single module. Use the --module-source-path option instead, possibly using the module-specific form of that option.
--system jdk | none
Overrides the location of system modules for the current API.

By convention, the APIs should be defined on the command in chronological order: oldest first, newest last. When comparing documentation comments or API descriptions, the APIs will be compared pairwise, with each of the older instances being compared against the newest instance.

The Elements to be Compared

The following options are used to specify the elements (declarations) to be compared within the APIs, specified by the various --api options and associated API-specific options.

These options apply equally to all the APIs to be compared: there is no need to repeat these options for each API to be compared.

--access public|protected|package|private

Specifies the access of the declarations to be compared. The default is protected.

  • public: public declarations only
  • protected: public and protected declarations
  • package: public, protected and package-private declarations
  • private: all declarations

Note: this option does not apply to the parts of the serialized form of a serializable class, even if those parts are provided by private methods and fields.

--exclude pattern
Specifies the patterns for modules or packages to be excluded from the comparison. The default is that none of the elements specified with --include options are excluded.
--include pattern
Specifies the patterns for modules or packages to be included in the comparison. There must be at least one --include option.
--compare-api-descriptions boolean
Specifies that the API descriptions (as generated by javadoc) should be compared for each element being compared. The option defaults to true if an API directory is given for each instance of the API to be compared and if documentation comments are not to be compared. (See --compare-doc-comments). When the option is enabled, either explicitly or by default, the API directory must be specified for each instance of the API to be compared, and set to the location of the files generated by javadoc that corresponds to the source and class files being compared. The API directory for an API can be specified explicitly, with the --api-directory option, or indirectly, with the --jdk-build and --jdk-docs options.
--compare-api-descriptions-as-text boolean
Specifies that the HTML for the API descriptions (as generated by javadoc) should be compared as plain text for each element being compared. If the argument is true, this option also implies --compare-api-descriptions true.
--compare-doc-comments boolean
Specifies that the documentation comments should be compared for each element being compared. This implies that the source files should be available for each instance of the API being compared; if they are not available, the documentation comments will not be compared. The option defaults to false if the API descriptions are to be compared, and true otherwise. (See --compare-api-descriptions).
--jdk-docs name
In conjunction with the --jdk-build option, specifies the name of the documentation bundle to use when more than one is available. It need not be specified if all the APIs specified by --jdk-build have exactly one directory matching the name images/*docs*: this is typically the case when building the OpenJDK docs or docs-jdk targets. For example, docs, javase-docs, reference-docs.

Output Options

--output-directory directory or -d directory
Specifies the directory in which to write the report about the comparison. The directory will be created if it does not already exist.
--title text
Specifies a title for the report, to be used in each generated page.
--description html
Specifies a short description for the report, to be used on the top level summary page.
--info-text name=html

Specifies information to be included in different positions on each page. name can be one of:

  • top: at the top of each page; this may be used to indicate the status of the pages.
  • header: in the header bar on each page; if not specified, a default value is generated, based on the names of the APIs being compared.
  • footer: in the footer bar on each page; if not specified, a default value is generated, based on the names of the APIs being compared.
  • bottom: at the bottom of each page; this may be used to indicate copyright and license information,
--notes file
Specifies a file containing notes to be added for various elements.
--main-stylesheet file
Specifies an alternate stylesheet to use in the generated report instead of the system default.
--extra-stylesheet file
Specifies an additional stylesheet to use in the generated report.

This option may be useful when comparing HTML documentation that contains references to custom styles.

--resource-files file-or-directory
Specifies resource files to be copied from one or more API directories.

This option may be useful when comparing HTML documentation that depend on some non-HTML resource files.

Other Options

--help, -help, -h, -?
Displays command-line help.
--version, -v
Displays the version of the tool.
--verbose flag[,flag]*

Specifies the kinds of verbose output. flag may be one of all, none, or one of the following, optionally preceded by - to negate the flag: module, package, type, time, options.

Flag Description
module Report on the modules being compared
package Report on the modules and packages being compared
type Report on the modules, packages, and classes and interfaces being compared
time Report the time taken to perform the comparison and generate the reports
options Report how the command-line options are processed
@filename
Reads options from a file. To shorten or simplify the apidiff command, you can specify one or more files that contain arguments for the apidiff command. This lets you create apidiff commands of any length on any operating system. The syntax for the contents of the file is similar to that for other JDK commands, like javac and javadoc.

Exit Status

apidiff exits with one of the following values:

Exit status Description
0 No differences were found
1 Differences were found
2 There was an error in the command-line arguments
3 An error occurred

The --help and --version options exit with a status of 0.

The Current API

The current API is the API specified by the most recent --api option on the command line, and is the API for which any subsequent API-specific options will apply.

The "current API" is cancelled when any option is given that is not specific to any one API. Additional options for an API can be given by repeating the --api option to set the API as the current API again.

Patterns

Patterns provide a way to specify groups of similarly-named modules, packages and types to be included or excluded from the comparison.

A pattern consists of a module-part and/or a type_part.

module-part: : | qualified-identifier / | qualified-identifier.* /

type-part: : | ** | qualified-identifier | qualified-identifier.* | qualified-identifier.**

A module-part that is just a qualified identifier matches the named module. A module-part that ends in a wildcard matches all module names that begin with the given qualified identifier.

A type-part that is just a qualified identifier matches the named type. A type-part that ends in a single * matches all types in the package with the given qualified identifier. A type-part that ends in ** matches all types in all packages that begin with the given qualified identifier. A type-part of ** can only be used in conjunction with a non-empty module part.

apidiff cannot compare a combination of types in named modules and types in the unnamed module, and so either all patterns must include a module part, or none must.

For example,

Depending on how you invoke apidiff, you may need to quote the pattern to prevent the * characters being interpreted by a command shell.

Notes

A "notes" file is used to specify links to be injected into the generated report for some elements.

The file is a plain text file. Blank lines and lines beginning with # are ignored. The remaining lines are interpreted as a series of blocks, each of which must start with a line containing a URL and a short plain-text description, followed by a series of lines, each containing a signature describing an element or set of elements. For each block, a link based on the URL and description, will be added to any element appearing in the generated report that matches any of the corresponding signatures.

The following signatures are supported:

Signatures should not contain any white-space characters. Signatures ending in /* or .* match the specified item, and any enclosed elements down to the level of a type element. For methods and constructors, parameters is a comma-separated list of parameter types, omitting any type parameters, and using just the simple name of any declared types.

For example,

Configuring the APIs to be compared

At a minimum, the source or class files must be provided for each instance of the API to be compared. If the API does not provide or is not part of a module, use the --source-path and --class-path options. If the API provides or is part of one or more modules, use the --source-path, --module-source-path, --module-path, and related options.

If you want to compare the content of documentation comments, you must provide source files for all the elements to be compared; any dependencies of those source files can be specified as either source or class files.

If you want to compare the API descriptions, you must provide the locations of the directories generated by the javadoc tool for each of the instances of the API being compared. This is often a directory whose path ends in api, although that is not a requirement. To eliminate any false positive differences being introduced by changes to the javadoc tool itself, the same or equivalent versions of javadoc should be used for each API to be compared.

If you want to compare all the exported packages in a module, use --include <module>/**. If you want to compare the contents of specific packages in a module, use --include <module>/<package>.* or --include <module>/<package>.**. The .** form will also include the contents of any subpackages. You can use multiple --include options to include different parts of an API in the comparison.

Configuring instances of JDK to be compared

apidiff can be used to compare different instances of JDK, but that can be tricky to set up, depending on the kind of comparison that is required. That being said, there is a "convenience" option to specify a JDK build, as generated by the standard JDK makefiles.

While the --jdk-build option provides a convenient way to have the tool automatically generate the equivalent underlying options, you can instead specify those options directly.

When using --patch-module, you do not need to specify all the source directories for the module: you just need to specify the source directories containing the classes whose documentation comments are to be compared. Any supporting declarations will be found in the JDK specified by the --system option.

If the list of --patch-module options is large, it may be convenient to place them in a file and use the @file option to specify the location of the file. You might also choose to put all the options for an API in an API-specific @file.

If you want to compare the API descriptions as well as the documentation comments, you can combine the recommended options for the two modes, specifying both --patch-module options for the source files and --api-directory for the generated documentation.

If you are using the --jdk-build option, and the corresponding images directory has multiple matches for images/*docs*, you will need to use the --jdk-docs option to disambiguate which documentation directory to use. The value that you give should be the name of one of those subdirectories of the images directory. The --jdk-docs option is not specific to any individual API, and need only be given once on the command-line. It will be used as needed to disambiguate the documentation directory to be used for any API that is defined by using the --jdk-build option.

If you want to see or understand how the options are used internally, you can use --verbose options, possibly implicitly as part of --verbose all.

Comparing different releases of JDK

When comparing any generated API documentation, the comparison is sensitive to any variations caused by the version of javadoc used to generate the documentation. Therefore, it is highly recommended to use the same version of javadoc to generate the documentation for all the versions to be compared. When building JDK, although the standard docs and docs-jdk targets will use the version of javadoc in the same repository, you can specify the version of JDK to be used for targets like docs-reference-api with the --with-docs-reference-jdk option to configure, allowing you to specify the same version of JDK and hence the same version of javadoc to be used to generate the API documentation for each build to be compared. Generally, the JDK version used to generate the documentation should be at least as recent as the latest version to be compared.

When comparing recent API changes in JDK, such as when creating a report for a CSR request, when there is no change in javadoc in the versions being compared, it is reasonable to use the standard docs or docs-jdk targets to generate the API documentation to be compared.

Comparing non-JDK APIs

If the API does not define any modules, use an appropriate combination of the --source-path, --class-path, and --api-directory options. You can put either the compiled classes or a JAR file on the class path. If you want to compare documentation comments, put the source files on the source path. If you want to compare the API documentation, use the --api-directory to specify the root directory of the documentation.

For example, to set up an API to be able to compare the API documentation associated with a JAR file:

--api before --class-path build/example.jar --api-directory build/docs/api

To set up an API to be able to compare the documentation comments for a project:

--api before --source-path src/main/java

In both cases, you can specify any additional dependencies on the class path.

If the API defines one or more modules, use an appropriate combination of the --module-source-path, --module-path, and --api-directory options. You can put either the module or a directory of modules on the module path, where a module is anything that can be recognized as such by javac. If you want to compare documentation comments, put the source files on the module source path. If you want to compare the API documentation, use the --api-directory to specify the root directory of the documentation.

For example, to set up an API to be able to compare the API documentation associated with the modules for a project:

--api before --module-path build/modules --api-directory build/docs/api

To set up an API to be able to compare the documentation comments for a project that defines a module called com.example:

--api before --module-source-path com.example=src/main/java

In both cases, you can specify any additional dependencies on the module path.

Comparing documentation comments or API descriptions

As well as comparing the declarations found in source files or compiled class files, apidiff can compare documentation comments and/or the API documentation generated by javadoc and the Standard Doclet.

Operation

The tool operates by creating an instance of the Java compiler front-end (as found in the jdk.compiler module) from which it can obtain the selected elements to be compared, using the Java Language Model API and Compiler Tree API.

Note: Because the compiler is reading the source and class files for each instance of the API being compared, the release of the JDK platform used to run apidiff must be at least as recent as each of the releases used to compile the instances to be compared.

When comparing the API descriptions for each selected element, the tool attempts to find the relevant content in the API documentation that is provided using the --api-directory or --jdk-build options. The tool does not attempt to run javadoc locally to generate the page on the fly.

Examples

To compare APIs in the java.base module in JDK builds /local/baseline-jdk and /local/updated-jdk, and place the result in the directory out, run the following command:

bin/apidiff \
    --api jdk \
    --jdk-build /local/baseline-jdk/build/linux-x86_64-server-fastdebug \
    --api sv \
    --jdk-build /local/updated-jdk/build/linux-x86_64-server-fastdebug \
    --jdk-docs docs \
    -d out \
    --compare-api-descriptions true \
    --include 'java.base/**'

To compare the changes for the fix for an issue such as JDK-8330183, using two separate configurations in the same repo, use a command like this:

apidiff \
    --api jdk24 --jdk-build build/baseline \
    --api 8330183 --jdk-build build/macosx-aarch64-server-release  \
    --include 'java.compiler/**' \
    --output-directory build/apidiff

While the previous example is minimal, it could be augmented by providing additional details to be included in the output, and additional options to be explicit about some of the desired settings.

apidiff \
    --api jdk24 --jdk-build build/baseline --label "The baseline for the changes"\
    --api 8330183 --jdk-build build/macosx-aarch64-server-release --label "Add SourceVersion.RELEASE_24" \
    --include 'java.compiler/**' \
    --output-directory build/apidiff \
    --compare-api-descriptions true \
    --jdk-docs docs \
    --info-text top="This proposal is not yet final" \
    --title "Diffs for JDK-8330183 CSR" \
    --description "Generated by $USER at $(date -u)"