Implementing Java SDK Library

The Android platform contains a large number of shared Java libraries that can optionally be included in the classpath of apps using the <uses-library> tag in the app manifest. Because apps link against these libraries, they should be treated like the rest of the Android API in terms of compatibility, API review, and tooling support. However, most libraries don't have these features.

Android 10 introduces java_sdk_library, a new build rule to fix compatibility issues for shared Java libraries. 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 is a Java library that implements optional SDK APIs to apps. Libraries implemented through java_sdk_library in your make file (Android.bp) perform the following operations:

  • The stubs libraries are generated to include stubs, stubs.system, and stubs.test. These stubs libraries are created by recognizing @hide, @SystemApi, and @TestApi annotations. At build time, they are automatically referenced when the SDK version is current, system_current, and test_current, respectively.
  • Android gets API lists through stubs files, and verifies that the APIs are maintained in a backward-compatible manner by comparing current APIs lists in master to the APIs lists in the most recent published Android version.
  • If the implementation library for the runtime is installed, an XML file is generated and installed.
Build flow with Java SDK library
Figure 1. Build flow with Java SDK library

Examples and sources

The minimum component for the stubs libraries are the mandatory srcs and api_packages properties.

java_sdk_library {
        name: "com.android.future.usb.accessory",
        srcs: ["src/**/*.java"],
        api_packages: ["com.android.future.usb"],
    }

To build the impl library used for runtime, populate all 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 create stubs libraries, populate the droidstubs properties, such as srcs_lib, srcs_lib_whitelist_dirs, srcs_lib_whitelist_pkgs, merge_annotations_dirs, and merge_inclusion_annotations_dirs. You can also use these properties for the stubs library:

  • 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.
    java_sdk_library {
              name: "android.test.mock",
    
              srcs: ["src/**/*.java"],
    
              api_packages: [
                  "android.test.mock",
              ],
    
              srcs_lib: "framework",
              srcs_lib_whitelist_dirs: ["core/java"],
              srcs_lib_whitelist_pkgs: ["android"],
              compile_dex: true,
          }

Maintaining backward compatibility

The build system checks whether the APIs maintained backwards compatibility by comparing the latest API files with the generated API files at build time. This is accomplished with a new build rule called prebuilt_apis, which creates the prebuilt stubs library modules and API lists modules. 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 should be located at the same directory level with Android.bp.

prebuilt_apis {
        name: "sdk",
        api_dirs: [
            "1",
            "2",
              ....
            "28",
            "current",
        ],
    }

Configure the directories with the version/scope/api/ structure under the prebuilts directory. version corresponds to the API level and scope determines whether the directory is public, system, or test.

  • version/scope contains Java libraries.
  • version/scope/api contains API .txt files. Create empty text files named module_name.txt and module_name-removed.txt here.
    ├── 28
          │   ├── public
          │   │   ├── api
          │   │   │   ├── android.test.base-removed.txt
          │   │   │   └── android.test.base.txt
          │   │   └── android.test.base.jar
          │   ├── system
          │   │   ├── api
          │   │   │   ├── android.test.base-removed.txt
          │   │   │   └── android.test.base.txt
          │   │   └── android.test.base.jar
          │   └── test
          │       ├── api
          │       │   ├── android.test.base-removed.txt
          │       │   └── android.test.base.txt
          │       └── android.test.base.jar
          └── Android.bp