APIDIFF(1) 1.0 | CodeTools (original) (raw)
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:
- structural changes, such as whether an element was added, changed or removed, using information in source or class files
- documentation contained in documentation comments, using information in source files
- generated API documentation, using information found in documentation generated by the
javadoc
tool
Options
apidiff
provides different groups of options, to specify:
- the APIs to be compared,
- the elements(declarations) in those APIs to be compared,
- the output options for the report to be generated, and
- other options.
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 thecurrent API. If given, it should be the top-level directory of the documentation generated by thejavadoc
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 correspondingjavac
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 thecurrent 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, unlikejavac
, 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 onlyprotected
: public and protected declarationspackage
: public, protected and package-private declarationsprivate
: 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 byjavadoc
) 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
ordocs-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 theapidiff
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
andjavadoc
.
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,
java.base/java.nio.**
matches all types in thejava.nio
packages and corresponding subpackages, in thejava.base
modulejava.compiler/**
matches all packages and types in thejava.compiler
module
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:
- module
- module
/*
- [ module
/
] package - [ module
/
] package.*
- [ module
/
] package.
type - [ module
/
] package.
type.*
- [ module
/
] package.
type#
field - [ module
/
] package.
type#
<init>
(
parameters)
- [ module
/
] package.
type#
method(
parameters)
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,
java.base/*
matches thejava.base
module, all packages injava.base
, and all types in those packages.java.base/java.lang.*
matches thejava.lang
package in thejava.base
module, and all types in that package. Note that it does not include subpackages, such asjava.lang.reflect
, or any types in those subpackages.java.base/java.lang.String
just matches the typejava.lang.String
.java.base/java.lang.String#equals(Object)
just matches theequals(Object)
.
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 thejavadoc
tool for each of the instances of the API being compared. This is often a directory whose path ends inapi
, although that is not a requirement. To eliminate any false positive differences being introduced by changes to thejavadoc
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.
- If you want to compare the files in two separate JDK builds, for each instance use the following:
- the
--api
option to introduce the set of API-specific options that follow - the
--jdk-build
option to specify the location of the build containing the files to be compared, such asbuild/macosx-x64
,build/linux-x86_64-server-release
, or the path for any directory that is used for a custom configuration.
The directory specified with--jdk-build
should contain the following files: - the "marker" file
spec.gmk
, - the JDK image, in
images/jdk
, - one or more documentation bundles, in
images/*docs*
, if API descriptions should be compared, and - the source code, in
support/src.zip
, if documentation comments should be compared
In conjunction with this option, use thejdk-docs
option to specify the name of the docs bundle to be compared, when there is more than one. Note this option applies to all instances to be compared, and need only be given once; it is not specific to the current API. Use the--compare-doc-comments
and--compare-api-descriptions
as needed to indicate the comparisons to be included in the report.
If neither are specified,--compare-api-descriptions
is the default.
- the
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.
- If you just want to compare some or all of the declarations in different instances of JDK, without comparing the documentation comments or API documentation, for each instance use the following:
- the
--api
option to introduce the set of API-specific options that follow - the
--system
option to point to the instance of JDK
- the
- If you want to compare the declarations and the corresponding API descriptions generated by
javadoc
, for each instance of JDK use the following:- the
--api
option to introduce the set of API-specific options that follow - the
--system
option to point to the instance of JDK - the
--api-directory
option to point to the corresponding documentation generated by thejavadoc
tool
- the
- If you want to compare the declarations and the corresponding documentation comments, it is recommended to use the following:
- the
--api
option to introduce the set of API-specific options that follow - the
--system
option to point to the instance of JDK - a series of
--patch-module
options to specify the location of the source for each of the modules to be compared
- the
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 ofjavadoc
used to generate the documentation. Therefore, it is highly recommended to use the same version ofjavadoc
to generate the documentation for all the versions to be compared. When building JDK, although the standarddocs
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 likedocs-reference-api
with the--with-docs-reference-jdk
option toconfigure
, 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 injavadoc
in the versions being compared, it is reasonable to use the standard docs
ordocs-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 calledcom.example
:
--api before --module-source-path com.example=src/main/java
In both cases, you can specify any additional dependencies on the module path.
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 byjavadoc
and the Standard Doclet.
- Comparing documentation comments is easy, and does not require API documentation to have been generated. However, it is just a simple text comparison of the text of the documentation comments, and so does not take into account any of the analysis and processing that is done by the Standard Doclet. Most notably, it does not take
{@inheritDoc}
into account, and so might miss some differences in any inherited documentation. - Comparing API descriptions is better for comparing the documentation as generated by the Standard Doclet, and as seen by the end user reading the API specification. However, it does require that API documentation needs to be generated beforehand, and generally using the same version of
javadoc
for all the versions of the API that are being compared.
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 <span class="katex"><span class="katex-mathml"><math xmlns="http://www.w3.org/1998/Math/MathML"><semantics><mrow><mi>U</mi><mi>S</mi><mi>E</mi><mi>R</mi><mi>a</mi><mi>t</mi></mrow><annotation encoding="application/x-tex">USER at </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height:0.6833em;"></span><span class="mord mathnormal" style="margin-right:0.10903em;">U</span><span class="mord mathnormal" style="margin-right:0.00773em;">SER</span><span class="mord mathnormal">a</span><span class="mord mathnormal">t</span></span></span></span>(date -u)"