The Android platform contains a large number of shared Java libraries
that can optionally be included in the classpath of apps with the
<uses-library>
tag in the app manifest. Apps link
against these libraries, so treat them like the rest of the Android API
in terms of compatibility, API review, and tooling support. Note, however,
that most libraries don't have these features.
The java_sdk_library
module type helps manage libraries
of this kind. Device manufacturers can use this mechanism for their own
shared Java libraries, to maintain backward compatibility for their APIs.
If device manufacturers use their own shared Java libraries through the
<uses-library>
tag instead of the bootclass path,
java_sdk_library
can verify that those Java libraries are
API-stable.
The java_sdk_library
implements optional SDK APIs for use by
apps. Libraries implemented through java_sdk_library
in your
build file (Android.bp
) perform the following operations:
- The stubs libraries are generated to include
stubs
,stubs.system
, andstubs.test
. These stubs libraries are created by recognizing@hide
,@SystemApi
, and@TestApi
annotations. - The
java_sdk_library
manages API specification files (such ascurrent.txt
) in an API subdirectory. These files are checked against the latest code to ensure that they’re the most current versions. If they aren’t, you receive an error message that explains how to update them. Manually review all update changes to ensure that they match your expectations.
To update all APIs, usem update-api
. To verify that an API is up-to-date, usem checkapi
. - The API specification files are checked against the most recently
published Android versions to ensure that the API is backward-compatible
with earlier releases. The
java_sdk_library
modules provided as part of AOSP place their previously released versions inprebuilts/sdk/<latest number>
. - With respect to the API specification files checks, you can do one of the following three things:
- Allow the checks to proceed. (Don’t do anything.)
- Disable checks by adding the following to
java_sdk_library
:
unsafe_ignore_missing_latest_api: true,
- Provide empty APIs for new
java_sdk_library
modules by creating empty text files namedmodule_name.txt
in theversion/scope/api
directory. - If the implementation library for the runtime is installed, an XML file gets generated and installed.
How java_sdk_library works
A java_sdk_library
called X
creates the following:
- Two copies of the implementation library: one library called
X
and another calledX.impl
. LibraryX
is installed on-device. LibraryX.impl
is there only if explicit access to the implementation library is needed by other modules, such as for use in testing. Note that explicit access is rarely needed. - Scopes can be enabled and disabled to customize access. (Similar to Java keyword-access modifiers, a public scope provides a wide range of access; a test scope contains APIs only used in testing.) For each enabled scope the library creates the following:
- A stubs source module (of
droidstubs
module type) - consumes the implementation source and outputs a set of stub sources along with the API specification file. - A stubs library (of
java_library
module type) - is the compiled version of the stubs. The libs used to compile this aren’t the same as those supplied to thejava_sdk_library
, which ensures the implementation details don’t leak into the API stubs. - If you need additional libraries to compile the stubs, use the
stub_only_libs
andstub_only_static_libs
properties to supply them.
If a java_sdk_library
is called “X
”, and is being
compiled against as “X
”, always refer to it that way and don’t modify
it. The build will select an appropriate library. To ensure that you have the
most appropriate library, inspect your stubs to see if the build introduced
errors. Make any necessary corrections using this guidance:
- Verify you have an appropriate library by looking on the command line and inspecting which stubs are listed there to determine your scope:
- Scope is too wide: The depending library needs a certain scope of APIs. But you see APIs included in the library that fall outside of that scope, such as system APIs included with the public APIs.
- Scope is too narrow: The depending library doesn’t have access to all the requisite libraries. For example, the depending library needs to use the system API but gets the public API instead. This usually results in a compilation error because needed APIs are missing.
- To fix the library, do only one of the following:
- Change the
sdk_version
to select the version you need. OR - Explicitly specify the appropriate library, such as
<X>.stubs
or<X>.stubs.system
.
java_sdk_library X usage
The implementation library X
gets used when it’s referenced from
apex.java_libs
. However, due to a Soong limitation, when library
X
is referenced from another java_sdk_library
module
within the same APEX library, X.impl
explicitly
must be used, not library X
.
When the java_sdk_library
is referenced from elsewhere, a stubs
library is used. The stubs library is selected according to the depending
module’s sdk_version
property setting. For example, a module that
specifies sdk_version: "current"
uses the public stubs, whereas a
module that specifies sdk_version: "system_current"
uses the
system stubs. If an exact match can’t be found, the closest stub library gets
used. A java_sdk_library
that only provides a public API will
supply the public stubs for everyone.
Examples and sources
The srcs
and api_packages
properties must
be present in the java_sdk_library
.
java_sdk_library { name: "com.android.future.usb.accessory", srcs: ["src/**/*.java"], api_packages: ["com.android.future.usb"], }
AOSP recommends (but doesn’t require) that new java_sdk_library
instances explicitly enable the API scopes they want to use. You can also
(optionally) migrate existing java_sdk_library
instances to
explicitly enable the API scopes they’ll use:
java_sdk_library { name: "lib", public: { enabled: true, }, system: { enabled: true, }, … }
To configure the impl
library used for runtime, use all
the normal java_library
properties, such as hostdex
,
compile_dex
, and errorprone
.
java_sdk_library { name: "android.test.base", srcs: ["src/**/*.java"], errorprone: { javacflags: ["-Xep:DepAnn:ERROR"], }, hostdex: true, api_packages: [ "android.test", "android.test.suitebuilder.annotation", "com.android.internal.util", "junit.framework", ], compile_dex: true, }
To configure stubs libraries, use the following properties:
merge_annotations_dirs
andmerge_inclusion_annotations_dirs
.api_srcs
: The list of optional source files that are part of the API but not part of the runtime library.stubs_only_libs
: The list of Java libraries that are in the classpath when building stubs.hidden_api_packages
: The list of package names that must be hidden from the API.droiddoc_options
: Additional argument for metalava.droiddoc_option_files
: Lists the files that can be referenced from withindroiddoc_options
using$(location <label>)
, where<file>
is an entry in the list.annotations_enabled
.
The java_sdk_library
is a java_library
, but it isn’t a
droidstubs
module and so doesn't support all of the droidstubs
properties. The following example was taken from the
android.test.mock library build
file.
java_sdk_library { name: "android.test.mock", srcs: [":android-test-mock-sources"], api_srcs: [ // Note: The following aren’t APIs of this library. Only APIs under the // android.test.mock package are taken. These do provide private APIs // to which android.test.mock APIs reference. These classes are present // in source code form to access necessary comments that disappear when // the classes are compiled into a Jar library. ":framework-core-sources-for-test-mock", ":framework_native_aidl", ], libs: [ "framework", "framework-annotations-lib", "app-compat-annotations", "Unsupportedappusage", ], api_packages: [ "android.test.mock", ], permitted_packages: [ "android.test.mock", ], compile_dex: true, default_to_stubs: true, }
Maintain backward compatibility
The build system checks whether the APIs have maintained backward
compatibility by comparing the latest API files with the generated
API files at build time. The java_sdk_library
performs the
compatibility check using the information provided by prebuilt_apis
.
All libraries built with java_sdk_library
must have API files
in the latest version of api_dirs
in prebuilt_apis
.
When you release the version, the API lists files and stubs
libraries can be obtained with dist build with PRODUCT=sdk_phone_armv7-sdk
.
The api_dirs
property is list of API version directories
in prebuilt_apis
. The API-version directories must be
located at the Android.bp
directory level.
prebuilt_apis { name: "foo", api_dirs: [ "1", "2", .... "30", "current", ], }
Configure the directories with the version/scope/api/
structure under the prebuilts directory. version
corresponds to the API level and scope
defines
whether the directory is public, system, or test.
version/scope
contains Java libraries.version/scope/api
contains API.txt
files. Create empty text files namedmodule_name.txt
andmodule_name-removed.txt
here.├── 30 │ ├── public │ │ ├── api │ │ │ ├── android.test.mock-removed.txt │ │ │ └── android.test.mock.txt │ │ └── android.test.mock.jar │ ├── system │ │ ├── api │ │ │ ├── android.test.mock-removed.txt │ │ │ └── android.test.mock.txt │ │ └── android.test.mock.jar │ └── test │ ├── api │ │ ├── android.test.mock-removed.txt │ │ └── android.test.mock.txt │ └── android.test.mock.jar └── Android.bp