aboutsummaryrefslogtreecommitdiff
path: root/rules/java
diff options
context:
space:
mode:
Diffstat (limited to 'rules/java')
-rw-r--r--rules/java/BUILD112
-rw-r--r--rules/java/bootclasspath.bzl49
-rw-r--r--rules/java/bootclasspath_test.bzl67
-rw-r--r--rules/java/event_log_tags.bzl49
-rw-r--r--rules/java/host_for_device.bzl40
-rw-r--r--rules/java/host_for_device_test.bzl78
-rw-r--r--rules/java/import.bzl67
-rw-r--r--rules/java/java_aidl_library.bzl91
-rw-r--r--rules/java/java_system_modules.bzl177
-rw-r--r--rules/java/java_system_modules_test.bzl59
-rw-r--r--rules/java/library.bzl80
-rw-r--r--rules/java/merged_txts.bzl84
-rw-r--r--rules/java/merged_txts_test.bzl156
-rw-r--r--rules/java/proto.bzl97
-rw-r--r--rules/java/rules.bzl30
-rw-r--r--rules/java/sdk/BUILD.bazel112
-rw-r--r--rules/java/sdk/config_setting_names.bzl35
-rw-r--r--rules/java/sdk_library.bzl61
-rw-r--r--rules/java/sdk_library_test.bzl115
-rw-r--r--rules/java/sdk_transition.bzl68
-rw-r--r--rules/java/sdk_transition_test.bzl173
-rw-r--r--rules/java/stub_local_jdk/BUILD.bazel8
-rw-r--r--rules/java/stub_local_jdk/WORKSPACE0
-rw-r--r--rules/java/versions.bzl104
-rw-r--r--rules/java/versions_test.bzl44
-rw-r--r--rules/java/wrapper_test.sh38
26 files changed, 1938 insertions, 56 deletions
diff --git a/rules/java/BUILD b/rules/java/BUILD
index e69de29b..763713c9 100644
--- a/rules/java/BUILD
+++ b/rules/java/BUILD
@@ -0,0 +1,112 @@
+"""
+Copyright (C) 2023 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+load(":merged_txts_test.bzl", "merged_txts_test_suite")
+load(":sdk_library_test.bzl", "java_sdk_library_test_suite")
+load(":java_system_modules_test.bzl", "java_system_modules_test_suite")
+load(":bootclasspath_test.bzl", "bootclasspath_test_suite")
+load(":versions_test.bzl", "versions_test_suite")
+load(":versions.bzl", "java_versions")
+load(":sdk_transition_test.bzl", "sdk_transition_test_suite")
+load(":host_for_device_test.bzl", "host_for_device_test_suite")
+load("@bazel_skylib//rules:common_settings.bzl", "string_setting")
+load("@bazel_tools//tools/jdk:default_java_toolchain.bzl", "DEFAULT_JAVACOPTS", "default_java_toolchain")
+load("@soong_injection//java_toolchain:constants.bzl", "constants")
+
+package(
+ default_visibility = ["//visibility:public"],
+)
+
+java_sdk_library_test_suite(name = "java_sdk_library_tests")
+
+merged_txts_test_suite(name = "merged_txts_tests")
+
+java_system_modules_test_suite(name = "java_system_modules_tests")
+
+bootclasspath_test_suite(name = "bootclasspath_tests")
+
+versions_test_suite(name = "versions_tests")
+
+sdk_transition_test_suite(name = "sdk_transition_tests")
+
+host_for_device_test_suite(name = "host_for_device_test_suite")
+
+string_setting(
+ name = "version",
+ build_setting_default = str(java_versions.get_version()),
+ values = [str(v) for v in java_versions.ALL_VERSIONS],
+)
+
+[
+ config_setting(
+ name = setting,
+ flag_values = {
+ "//build/bazel/rules/java:version": str(java_version),
+ },
+ )
+ for java_version, setting in java_versions.VERSION_TO_CONFIG_SETTING.items()
+]
+
+# There is no need for both host and device java version build settings in a
+# world where every java_*/android_*/kt_* target uses the AOSP-specific
+# wrappers. However, there are targets defined by BUILD.tools files within the
+# Bazel binary that do not use the wrapper. These would inherit their java
+# version from their reverse dependency, which can cause build failures (e.g. an
+# android_library_import with java_version=7 has a tools dependency on a
+# non-wrapped Bazel java_library that uses lambdas). By using a separate host
+# version, we can reset it to its default when in the device configuration, so
+# that a subsequent exec transition will use the default java version.
+string_setting(
+ name = "host_version",
+ build_setting_default = str(java_versions.get_version()),
+ values = [str(v) for v in java_versions.ALL_VERSIONS],
+)
+
+[
+ config_setting(
+ name = "host_" + setting,
+ flag_values = {
+ "//build/bazel/rules/java:host_version": str(java_version),
+ },
+ )
+ for java_version, setting in java_versions.VERSION_TO_CONFIG_SETTING.items()
+]
+
+java_version_select_dict = {
+ "host_" + setting: str(version)
+ for version, setting in java_versions.VERSION_TO_CONFIG_SETTING.items()
+} | {
+ "//conditions:default": str(java_versions.get_version()),
+}
+
+default_java_toolchain(
+ name = "jdk17_host_toolchain_java",
+ # TODO(b/218720643): Support switching between multiple JDKs.
+ java_runtime = "//prebuilts/jdk/jdk17:jdk17_runtime",
+ misc = DEFAULT_JAVACOPTS + constants.CommonJdkFlags,
+ source_version = select(java_version_select_dict),
+ target_version = select(java_version_select_dict),
+ toolchain_definition = False,
+)
+
+toolchain(
+ name = "jdk17_host_toolchain_java_definition",
+ exec_compatible_with = ["//build/bazel/platforms/os:linux"],
+ target_compatible_with = ["//build/bazel/platforms/os:linux"],
+ target_settings = [],
+ toolchain = ":jdk17_host_toolchain_java",
+ toolchain_type = "@bazel_tools//tools/jdk:toolchain_type",
+)
diff --git a/rules/java/bootclasspath.bzl b/rules/java/bootclasspath.bzl
new file mode 100644
index 00000000..78fddcfb
--- /dev/null
+++ b/rules/java/bootclasspath.bzl
@@ -0,0 +1,49 @@
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+load(":java_system_modules.bzl", "SystemInfo")
+
+def _bootclasspath_impl(ctx):
+ compile_jars = lambda b: b[JavaInfo].compile_jars.to_list()
+ return java_common.BootClassPathInfo(
+ bootclasspath = [jar for b in ctx.attr.bootclasspath for jar in compile_jars(b)],
+ system = ctx.attr.system[SystemInfo].system if ctx.attr.system else None,
+ auxiliary = [jar for b in ctx.attr.auxiliary for jar in compile_jars(b)],
+ )
+
+bootclasspath = rule(
+ implementation = _bootclasspath_impl,
+ attrs = {
+ "bootclasspath": attr.label_list(
+ providers = [JavaInfo],
+ doc = "The list of libraries to use as javac's --bootclasspath argument.",
+ ),
+ "system": attr.label(
+ providers = [SystemInfo],
+ doc = "The java_system_modules target to use as javac's --system argument.",
+ ),
+ "auxiliary": attr.label_list(
+ providers = [JavaInfo],
+ doc = "The list of libraries to include first in javac's --classpath.",
+ ),
+ },
+ provides = [java_common.BootClassPathInfo],
+ doc = """Provides BootClassPathInfo to a Java toolchain.
+
+the java_common.BootClassPathInfo provider is used by a Java toolchain to
+set javac's --bootclasspath and --system arguments. It can also optionally add
+to the classpath before anything else gets added to it. This rule generates this
+provider from a list of JavaInfo-providing targets for --bootclasspath and
+--classpath, and from a single SystemInfo-providing target for --system.
+""",
+)
diff --git a/rules/java/bootclasspath_test.bzl b/rules/java/bootclasspath_test.bzl
new file mode 100644
index 00000000..652acf2a
--- /dev/null
+++ b/rules/java/bootclasspath_test.bzl
@@ -0,0 +1,67 @@
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
+load(":bootclasspath.bzl", "bootclasspath")
+load(":rules.bzl", "java_import")
+load(":java_system_modules.bzl", "java_system_modules")
+
+def _bootclasspath_test_impl(ctx):
+ env = analysistest.begin(ctx)
+ bootclasspath_target = analysistest.target_under_test(env)
+
+ asserts.true(
+ env,
+ java_common.BootClassPathInfo in bootclasspath_target,
+ "Expected BootClassPathInfo in bootclasspath providers.",
+ )
+ return analysistest.end(env)
+
+bootclasspath_test = analysistest.make(
+ _bootclasspath_test_impl,
+)
+
+def test_bootclasspath_provider():
+ name = "test_bootclasspath_provider"
+ import_target = ":" + name + "_import"
+ system_target = ":" + name + "_jsm"
+ bootclasspath(
+ name = name + "_target",
+ bootclasspath = [import_target],
+ system = system_target,
+ auxiliary = [import_target],
+ tags = ["manual"],
+ )
+ bootclasspath_test(
+ name = name,
+ target_under_test = name + "_target",
+ )
+ java_system_modules(
+ name = name + "_jsm",
+ deps = [import_target],
+ tags = ["manual"],
+ )
+ java_import(
+ name = import_target[1:],
+ jars = ["some_jar.jar"],
+ tags = ["manual"],
+ )
+ return name
+
+def bootclasspath_test_suite(name):
+ native.test_suite(
+ name = name,
+ tests = [
+ test_bootclasspath_provider(),
+ ],
+ )
diff --git a/rules/java/event_log_tags.bzl b/rules/java/event_log_tags.bzl
new file mode 100644
index 00000000..b802258b
--- /dev/null
+++ b/rules/java/event_log_tags.bzl
@@ -0,0 +1,49 @@
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Event log tags generation rule"""
+
+load("@bazel_skylib//lib:paths.bzl", "paths")
+
+def _event_log_tags_impl(ctx):
+ out_files = []
+ for logtag_file in ctx.files.srcs:
+ out_filename = paths.replace_extension(logtag_file.basename, ".java")
+ out_file = ctx.actions.declare_file(out_filename)
+ out_files.append(out_file)
+ ctx.actions.run(
+ inputs = [logtag_file],
+ outputs = [out_file],
+ arguments = [
+ "-o",
+ out_file.path,
+ logtag_file.path,
+ ],
+ progress_message = "Generating Java logtag file from %s" % logtag_file.short_path,
+ executable = ctx.executable._logtag_to_java_tool,
+ )
+ return [DefaultInfo(files = depset(out_files))]
+
+event_log_tags = rule(
+ implementation = _event_log_tags_impl,
+ attrs = {
+ "srcs": attr.label_list(allow_files = [".logtags"], mandatory = True),
+ "_logtag_to_java_tool": attr.label(
+ executable = True,
+ cfg = "exec",
+ allow_files = True,
+ default = Label("//build/make/tools:java-event-log-tags"),
+ ),
+ },
+)
diff --git a/rules/java/host_for_device.bzl b/rules/java/host_for_device.bzl
new file mode 100644
index 00000000..9d7990a1
--- /dev/null
+++ b/rules/java/host_for_device.bzl
@@ -0,0 +1,40 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+visibility([
+ "//external/guava/...",
+ "//external/kotlinx.coroutines/...",
+ "//external/robolectric-shadows/...",
+ "//external/robolectric/...",
+])
+
+def _host_for_device_impl(ctx):
+ return [java_common.merge([d[JavaInfo] for d in ctx.attr.exports])]
+
+java_host_for_device = rule(
+ doc = """Rule to provide java libraries built with a host classpath in a device configuration.
+This is rarely necessary and restricted to a few allowed projects.
+""",
+ implementation = _host_for_device_impl,
+ attrs = {
+ # This attribute must have a specific name to let the DexArchiveAspect propagate
+ # through it.
+ "exports": attr.label_list(
+ cfg = "exec",
+ providers = [JavaInfo],
+ doc = "List of targets whose contents will be visible to targets that depend on this target.",
+ ),
+ },
+ provides = [JavaInfo],
+)
diff --git a/rules/java/host_for_device_test.bzl b/rules/java/host_for_device_test.bzl
new file mode 100644
index 00000000..5585bad9
--- /dev/null
+++ b/rules/java/host_for_device_test.bzl
@@ -0,0 +1,78 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+load(":host_for_device.bzl", "java_host_for_device")
+load(":rules.bzl", "java_import")
+load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
+load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo")
+
+Platform = provider(
+ "Platform of the leaf dependency in a linear dependency chain",
+ fields = {
+ "platform": "the target platform",
+ "host_platform": "the host platform",
+ },
+)
+
+def _host_for_device_tester_aspect_impl(target, ctx):
+ if ctx.rule.attr.exports and len(ctx.rule.attr.exports) > 0 and Platform in ctx.rule.attr.exports[0]:
+ return ctx.rule.attr.exports[0][Platform]
+ return Platform(
+ platform = ctx.fragments.platform.platform,
+ host_platform = ctx.fragments.platform.host_platform,
+ )
+
+host_for_device_tester_aspect = aspect(
+ implementation = _host_for_device_tester_aspect_impl,
+ attr_aspects = ["exports"],
+ fragments = ["platform"],
+ provides = [Platform],
+)
+
+def _host_for_device_dep_runs_in_exec_config_test_impl(ctx):
+ env = analysistest.begin(ctx)
+ target_under_test = analysistest.target_under_test(env)
+ actual_platform = target_under_test[Platform].platform
+ expected_platform = target_under_test[Platform].host_platform
+ asserts.equals(env, expected_platform, actual_platform)
+ asserts.true(env, JavaInfo in target_under_test, "Expected host_for_device to provide JavaInfo")
+ return analysistest.end(env)
+
+host_for_device_dep_runs_in_exec_config_test = analysistest.make(
+ _host_for_device_dep_runs_in_exec_config_test_impl,
+ extra_target_under_test_aspects = [host_for_device_tester_aspect],
+)
+
+def test_host_for_device(name):
+ java_host_for_device(
+ name = name + "_parent",
+ exports = [name + "_child"],
+ tags = ["manual"],
+ )
+ java_import(
+ name = name + "_child",
+ jars = ["blah.jar"],
+ tags = ["manual"],
+ )
+ host_for_device_dep_runs_in_exec_config_test(
+ name = name,
+ target_under_test = name + "_parent",
+ )
+ return name
+
+def host_for_device_test_suite(name):
+ native.test_suite(
+ name = name,
+ tests = [test_host_for_device("test_host_for_device")],
+ )
diff --git a/rules/java/import.bzl b/rules/java/import.bzl
new file mode 100644
index 00000000..6770c5f0
--- /dev/null
+++ b/rules/java/import.bzl
@@ -0,0 +1,67 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Macro wrapping the java_import for bp2build. """
+
+load("@rules_java//java:defs.bzl", _java_import = "java_import")
+load("//build/bazel/rules/java:sdk_transition.bzl", "sdk_transition", "sdk_transition_attrs")
+
+# TODO(b/277801336): document these attributes.
+def java_import(
+ name = "",
+ jars = [],
+ deps = [],
+ tags = [],
+ target_compatible_with = [],
+ visibility = None,
+ **kwargs):
+ lib_name = name + "_private"
+ _java_import(
+ name = lib_name,
+ jars = jars,
+ deps = deps,
+ tags = tags + ["manual"],
+ target_compatible_with = target_compatible_with,
+ visibility = ["//visibility:private"],
+ **kwargs
+ )
+
+ java_import_sdk_transition(
+ name = name,
+ sdk_version = "none",
+ java_version = None,
+ exports = lib_name,
+ tags = tags,
+ target_compatible_with = target_compatible_with,
+ visibility = visibility,
+ )
+
+# The list of providers to forward was determined using cquery on one
+# of the example targets listed under EXAMPLE_WRAPPER_TARGETS at
+# //build/bazel/ci/target_lists.sh. It may not be exhaustive. A unit
+# test ensures that the wrapper's providers and the wrapped rule's do
+# match.
+def _java_import_sdk_transition_impl(ctx):
+ return [
+ ctx.attr.exports[0][JavaInfo],
+ ctx.attr.exports[0][ProguardSpecProvider],
+ ctx.attr.exports[0][OutputGroupInfo],
+ ctx.attr.exports[0][DefaultInfo],
+ ]
+
+java_import_sdk_transition = rule(
+ implementation = _java_import_sdk_transition_impl,
+ attrs = sdk_transition_attrs,
+ provides = [JavaInfo],
+)
diff --git a/rules/java/java_aidl_library.bzl b/rules/java/java_aidl_library.bzl
new file mode 100644
index 00000000..94fd8c5c
--- /dev/null
+++ b/rules/java/java_aidl_library.bzl
@@ -0,0 +1,91 @@
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+load("//build/bazel/rules/aidl:aidl_library.bzl", "AidlGenInfo", "aidl_file_utils")
+load("//build/bazel/rules/java:sdk_transition.bzl", "sdk_transition")
+
+JavaAidlAspectInfo = provider("JavaAidlAspectInfo", fields = ["jars"])
+
+def _java_aidl_gen_aspect_impl(target, ctx):
+ aidl_gen_java_files = aidl_file_utils.generate_aidl_bindings(ctx, "java", target[AidlGenInfo])
+ java_deps = [
+ d[JavaInfo]
+ for d in ctx.rule.attr.deps
+ ]
+ out_jar = ctx.actions.declare_file(target.label.name + "-aidl-gen.jar")
+ java_info = java_common.compile(
+ ctx,
+ source_files = aidl_gen_java_files,
+ deps = java_deps,
+ output = out_jar,
+ java_toolchain = ctx.toolchains["@bazel_tools//tools/jdk:toolchain_type"].java,
+ )
+
+ return [
+ java_info,
+ JavaAidlAspectInfo(
+ jars = depset([out_jar]),
+ ),
+ ]
+
+_java_aidl_gen_aspect = aspect(
+ implementation = _java_aidl_gen_aspect_impl,
+ attr_aspects = ["deps"],
+ attrs = {
+ "_aidl_tool": attr.label(
+ allow_files = True,
+ executable = True,
+ cfg = "exec",
+ default = Label("//prebuilts/build-tools:linux-x86/bin/aidl"),
+ ),
+ },
+ toolchains = ["@bazel_tools//tools/jdk:toolchain_type"],
+ fragments = ["java"],
+ provides = [JavaInfo, JavaAidlAspectInfo],
+)
+
+def _java_aidl_library_rule_impl(ctx):
+ java_info = java_common.merge([d[JavaInfo] for d in ctx.attr.deps])
+ runtime_jars = depset(transitive = [dep[JavaAidlAspectInfo].jars for dep in ctx.attr.deps])
+ transitive_runtime_jars = depset(transitive = [java_info.transitive_runtime_jars])
+
+ return [
+ java_info,
+ DefaultInfo(
+ files = runtime_jars,
+ runfiles = ctx.runfiles(transitive_files = transitive_runtime_jars),
+ ),
+ OutputGroupInfo(default = depset()),
+ ]
+
+java_aidl_library = rule(
+ implementation = _java_aidl_library_rule_impl,
+ attrs = {
+ # This attribute's name lets the DexArchiveAspect propagate
+ # through it. It should be changed carefully.
+ "deps": attr.label_list(
+ providers = [AidlGenInfo],
+ aspects = [_java_aidl_gen_aspect],
+ cfg = sdk_transition,
+ ),
+ "java_version": attr.string(),
+ "sdk_version": attr.string(
+ default = "system_current",
+ ),
+ "_allowlist_function_transition": attr.label(
+ default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
+ ),
+ },
+ provides = [JavaInfo],
+)
diff --git a/rules/java/java_system_modules.bzl b/rules/java/java_system_modules.bzl
new file mode 100644
index 00000000..41e76a83
--- /dev/null
+++ b/rules/java/java_system_modules.bzl
@@ -0,0 +1,177 @@
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+load("@bazel_skylib//lib:paths.bzl", "paths")
+
+SystemInfo = provider(fields = ["system"])
+
+def _gen_module_info_java(ctx, jars_to_module_info, jars, module_info):
+ ctx.actions.run_shell(
+ inputs = jars,
+ outputs = [module_info],
+ command = "{} java.base {} > {}".format(
+ jars_to_module_info.path,
+ " ".join([jar.path for jar in jars]),
+ module_info.path,
+ ),
+ tools = [jars_to_module_info],
+ )
+
+def _gen_module_info_class(ctx, java_runtime, module_info, java_base_patch_jars, module_info_class):
+ ctx.actions.run_shell(
+ inputs = depset([module_info], transitive = [java_base_patch_jars]),
+ outputs = [module_info_class],
+ tools = java_runtime.files,
+ command = "{} -d {} --system=none --patch-module=java.base={} {}".format(
+ paths.join(java_runtime.java_home, "bin", "javac"),
+ module_info_class.dirname,
+ ":".join([jar.path for jar in java_base_patch_jars.to_list()]),
+ module_info.path,
+ ),
+ )
+
+def _gen_module_info_jar(ctx, soong_zip, module_info_class, module_info_jar):
+ args = ctx.actions.args()
+ args.add("-jar")
+ args.add("--symlinks=false")
+ args.add("-o", module_info_jar)
+ args.add("-C", module_info_class.dirname)
+ args.add("-f", module_info_class)
+ ctx.actions.run(
+ inputs = [module_info_class],
+ outputs = [module_info_jar],
+ arguments = [args],
+ executable = soong_zip,
+ )
+
+def _gen_merged_module_jar(ctx, merge_zips, module_info_jar, jars, merged_module_jar):
+ args = ctx.actions.args()
+ args.add("-j", merged_module_jar)
+ args.add_all(depset([module_info_jar], transitive = [jars]))
+ ctx.actions.run(
+ inputs = depset([module_info_jar], transitive = [jars]),
+ outputs = [merged_module_jar],
+ arguments = [args],
+ executable = merge_zips,
+ )
+
+def _gen_jmod(ctx, java_runtime, merged_module_jar, jmod):
+ ctx.actions.run_shell(
+ inputs = [merged_module_jar],
+ outputs = [jmod],
+ tools = java_runtime.files,
+ command = (
+ "{} create --module-version $({} --version) " +
+ "--target-platform android --class-path {} {}"
+ ).format(
+ paths.join(java_runtime.java_home, "bin", "jmod"),
+ paths.join(java_runtime.java_home, "bin", "jlink"),
+ merged_module_jar.path,
+ jmod.path,
+ ),
+ )
+
+def _gen_system(ctx, java_runtime, jmod, system):
+ ctx.actions.run_shell(
+ inputs = depset([jmod], transitive = [java_runtime.files]),
+ outputs = [system],
+ tools = java_runtime.files,
+ command = (
+ "rm -rf {} && " +
+ "{} --module-path {} --add-modules java.base --output {} " +
+ "--disable-plugin system-modules && " +
+ "cp {} {}/lib/"
+ ).format(
+ system.path,
+ paths.join(java_runtime.java_home, "bin", "jlink"),
+ jmod.dirname,
+ system.path,
+ paths.join(java_runtime.java_home, "lib", "jrt-fs.jar"),
+ system.path,
+ ),
+ )
+
+def _java_system_modules_impl(ctx):
+ java_info = java_common.merge([d[JavaInfo] for d in ctx.attr.deps])
+ module_info = ctx.actions.declare_file("%s/src/module-info.java" % ctx.label.name)
+ _gen_module_info_java(ctx, ctx.executable._jars_to_module_info, java_info.compile_jars.to_list(), module_info)
+
+ java_runtime = ctx.attr._runtime[java_common.JavaRuntimeInfo]
+ module_info_class = ctx.actions.declare_file("%s/class/module-info.class" % ctx.label.name)
+ _gen_module_info_class(ctx, java_runtime, module_info, java_info.compile_jars, module_info_class)
+
+ module_info_jar = ctx.actions.declare_file("%s/jar/classes.jar" % ctx.label.name)
+ _gen_module_info_jar(ctx, ctx.executable._soong_zip, module_info_class, module_info_jar)
+
+ merged_module_jar = ctx.actions.declare_file("%s/merged/module.jar" % ctx.label.name)
+ _gen_merged_module_jar(
+ ctx,
+ ctx.executable._merge_zips,
+ module_info_jar,
+ java_info.full_compile_jars,
+ merged_module_jar,
+ )
+
+ jmod = ctx.actions.declare_file("%s/jmod/java.base.jmod" % ctx.label.name)
+ _gen_jmod(ctx, java_runtime, merged_module_jar, jmod)
+
+ system = ctx.actions.declare_directory("%s/system" % ctx.label.name)
+ _gen_system(ctx, java_runtime, jmod, system)
+
+ return [
+ SystemInfo(
+ system = system,
+ ),
+ DefaultInfo(files = depset([system])),
+ ]
+
+java_system_modules = rule(
+ implementation = _java_system_modules_impl,
+ attrs = {
+ "_jars_to_module_info": attr.label(
+ allow_files = True,
+ executable = True,
+ cfg = "exec",
+ default = "//build/soong/scripts:jars-to-module-info-java",
+ ),
+ "_soong_zip": attr.label(
+ cfg = "exec",
+ allow_single_file = True,
+ doc = "The tool soong_zip",
+ default = "//build/soong/zip/cmd:soong_zip",
+ executable = True,
+ ),
+ "_merge_zips": attr.label(
+ cfg = "exec",
+ allow_single_file = True,
+ doc = "The tool merge_zips.",
+ default = "//prebuilts/build-tools:linux-x86/bin/merge_zips",
+ executable = True,
+ ),
+ "_runtime": attr.label(
+ default = Label("@bazel_tools//tools/jdk:current_java_runtime"),
+ cfg = "exec",
+ providers = [java_common.JavaRuntimeInfo],
+ ),
+ "deps": attr.label_list(
+ providers = [JavaInfo],
+ doc = "Libraries to be converted into a system module directory structure.",
+ ),
+ },
+ doc = """Generates a system module directory from Java libraries.
+
+Starting from version 1.9, Java requires a subset of java.* classes to be
+provided via system modules. This rule encapsulates the set of steps necessary
+to convert a jar file into the directory structure of system modules.
+""",
+)
diff --git a/rules/java/java_system_modules_test.bzl b/rules/java/java_system_modules_test.bzl
new file mode 100644
index 00000000..3b76f4c8
--- /dev/null
+++ b/rules/java/java_system_modules_test.bzl
@@ -0,0 +1,59 @@
+# Copyright (C) 2022 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
+load(":java_system_modules.bzl", "SystemInfo", "java_system_modules")
+load(":rules.bzl", "java_import")
+
+def _java_system_modules_test_impl(ctx):
+ env = analysistest.begin(ctx)
+ java_system_modules_target = analysistest.target_under_test(env)
+
+ asserts.true(
+ env,
+ java_system_modules_target[SystemInfo].system.is_directory,
+ "java_system_modules output should be a directory.",
+ )
+ return analysistest.end(env)
+
+java_system_modules_test = analysistest.make(
+ _java_system_modules_test_impl,
+)
+
+def test_java_system_modules_provider():
+ name = "test_java_system_modules_provider"
+ import_target = ":" + name + "_import"
+ java_system_modules(
+ name = name + "_target",
+ deps = [import_target],
+ tags = ["manual"],
+ )
+ java_system_modules_test(
+ name = name,
+ target_under_test = name + "_target",
+ )
+
+ java_import(
+ name = import_target[1:],
+ jars = ["some_jar.jar"],
+ tags = ["manual"],
+ )
+ return name
+
+def java_system_modules_test_suite(name):
+ native.test_suite(
+ name = name,
+ tests = [
+ test_java_system_modules_provider(),
+ ],
+ )
diff --git a/rules/java/library.bzl b/rules/java/library.bzl
index f45cd51b..f381b1c2 100644
--- a/rules/java/library.bzl
+++ b/rules/java/library.bzl
@@ -1,8 +1,80 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http:#www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
"""Macro wrapping the java_library for bp2build. """
-def java_library(name = "", srcs = [], deps = [], javacopts = [], **kwargs):
- # Disable the error prone check of HashtableContains by default. See https://errorprone.info/bugpattern/HashtableContains
- # HashtableContains error is reported when compiling //external/bouncycastle:bouncycastle-bcpkix-unbundled
+load(
+ "@rules_java//java:defs.bzl",
+ _java_library = "java_library",
+)
+load("//build/bazel/rules/java:sdk_transition.bzl", "sdk_transition", "sdk_transition_attrs")
+
+# TODO(b/277801336): document these attributes.
+def java_library(
+ name = "",
+ srcs = [],
+ deps = [],
+ javacopts = [],
+ sdk_version = None,
+ java_version = None,
+ tags = [],
+ target_compatible_with = [],
+ visibility = None,
+ **kwargs):
+ lib_name = name + "_private"
+
+ # Disable the error prone check of HashtableContains by default. See https://errorprone.info/bugpattern/HashtableContains
+ # HashtableContains error is reported when compiling //external/bouncycastle:bouncycastle-bcpkix-unbundled
opts = ["-Xep:HashtableContains:OFF"] + javacopts
- native.java_library(name, srcs = srcs, deps = deps, javacopts = opts, **kwargs)
+ _java_library(
+ name = lib_name,
+ srcs = srcs,
+ deps = deps,
+ javacopts = opts,
+ tags = tags + ["manual"],
+ target_compatible_with = target_compatible_with,
+ visibility = ["//visibility:private"],
+ **kwargs
+ )
+
+ java_library_sdk_transition(
+ name = name,
+ sdk_version = sdk_version,
+ java_version = java_version,
+ exports = lib_name,
+ tags = tags,
+ target_compatible_with = target_compatible_with,
+ visibility = ["//visibility:public"],
+ )
+
+# The list of providers to forward was determined using cquery on one
+# of the example targets listed under EXAMPLE_WRAPPER_TARGETS at
+# //build/bazel/ci/target_lists.sh. It may not be exhaustive. A unit
+# test ensures that the wrapper's providers and the wrapped rule's do
+# match.
+def _java_library_sdk_transition_impl(ctx):
+ return [
+ ctx.attr.exports[0][JavaInfo],
+ ctx.attr.exports[0][InstrumentedFilesInfo],
+ ctx.attr.exports[0][ProguardSpecProvider],
+ ctx.attr.exports[0][OutputGroupInfo],
+ ctx.attr.exports[0][DefaultInfo],
+ ]
+
+java_library_sdk_transition = rule(
+ implementation = _java_library_sdk_transition_impl,
+ attrs = sdk_transition_attrs,
+ provides = [JavaInfo],
+)
diff --git a/rules/java/merged_txts.bzl b/rules/java/merged_txts.bzl
new file mode 100644
index 00000000..069903f8
--- /dev/null
+++ b/rules/java/merged_txts.bzl
@@ -0,0 +1,84 @@
+"""
+Copyright (C) 2023 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+load("//build/bazel/rules/java:sdk_library.bzl", "JavaSdkLibraryInfo")
+
+METALAVA_ARGS = [
+ "-J--add-opens=java.base/java.util=ALL-UNNAMED",
+ "--quiet",
+ "--no-banner",
+ "--format=v2",
+]
+
+def _get_inputs(ctx):
+ inputs = []
+ inputs.extend(ctx.files.base)
+ from_deps = []
+ if ctx.attr.scope == "public":
+ from_deps = [d[JavaSdkLibraryInfo].public for d in ctx.attr.deps]
+ elif ctx.attr.scope == "system":
+ from_deps = [d[JavaSdkLibraryInfo].system for d in ctx.attr.deps]
+ elif ctx.attr.scope == "module-lib":
+ from_deps = [d[JavaSdkLibraryInfo].module_lib for d in ctx.attr.deps]
+ elif ctx.attr.scope == "system-server":
+ from_deps = [d[JavaSdkLibraryInfo].system_server for d in ctx.attr.deps]
+ inputs.extend(from_deps)
+ return depset(inputs)
+
+def _get_output_name(ctx):
+ output_name = "current.txt"
+ if ctx.attr.scope != "public":
+ output_name = ctx.attr.scope + "-" + output_name
+ return output_name
+
+def _merged_txts_impl(ctx):
+ output = ctx.actions.declare_file(_get_output_name(ctx))
+ inputs = _get_inputs(ctx)
+ args = ctx.actions.args()
+ args.add_all(METALAVA_ARGS)
+ args.add_all(inputs)
+ args.add("--api", output)
+ ctx.actions.run(
+ outputs = [output],
+ inputs = inputs,
+ executable = ctx.executable._metalava,
+ arguments = [args],
+ )
+ return [DefaultInfo(files = depset([output]))]
+
+merged_txts = rule(
+ implementation = _merged_txts_impl,
+ attrs = {
+ "scope": attr.string(
+ doc = "api scope",
+ ),
+ "base": attr.label(
+ mandatory = True,
+ allow_single_file = True,
+ doc = "the target used to get the checked-in base current.txt",
+ ),
+ "deps": attr.label_list(
+ mandatory = True,
+ allow_empty = False,
+ providers = [JavaSdkLibraryInfo],
+ ),
+ "_metalava": attr.label(
+ default = "//tools/metalava:metalava",
+ executable = True,
+ cfg = "exec",
+ ),
+ },
+)
diff --git a/rules/java/merged_txts_test.bzl b/rules/java/merged_txts_test.bzl
new file mode 100644
index 00000000..6dcf3331
--- /dev/null
+++ b/rules/java/merged_txts_test.bzl
@@ -0,0 +1,156 @@
+"""
+Copyright (C) 2023 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+"""
+
+load("@bazel_skylib//lib:paths.bzl", "paths")
+load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
+load(":merged_txts.bzl", "merged_txts")
+load(":sdk_library.bzl", "java_sdk_library")
+
+SCOPE_TO_JAVA_SDK_LIBRARY_FILE = {
+ "public": "sdk_public.txt",
+ "system": "sdk_system.txt",
+ "module-lib": "sdk_module_lib.txt",
+ "system-server": "sdk_system_server.txt",
+}
+
+def _basic_merged_txts_test_impl(ctx):
+ env = analysistest.begin(ctx)
+ actions = analysistest.target_actions(env)
+
+ base_file = paths.join(paths.dirname(ctx.build_file_path), ctx.attr.base)
+ asserts.true(
+ env,
+ base_file in actions[0].argv,
+ "Base file {} of scope {} is not in args list".format(base_file, ctx.attr.scope),
+ )
+
+ java_sdk_library_file = paths.join(
+ paths.dirname(ctx.build_file_path),
+ SCOPE_TO_JAVA_SDK_LIBRARY_FILE[ctx.attr.scope],
+ )
+ asserts.true(
+ env,
+ java_sdk_library_file in actions[0].argv,
+ "java_sdk_library file {} of scope {} is not in args list".format(java_sdk_library_file, ctx.attr.scope),
+ )
+
+ return analysistest.end(env)
+
+basic_merged_txts_test = analysistest.make(
+ _basic_merged_txts_test_impl,
+ attrs = {
+ "scope": attr.string(),
+ "base": attr.string(),
+ },
+)
+
+def test_generated_current_txt():
+ name = "generated_current_txt_test"
+ target_name = name + "_target"
+ scope = "public"
+ base = "non-updatable-current.txt"
+ merged_txts(
+ name = target_name,
+ scope = scope,
+ base = base,
+ deps = ["dep"],
+ tags = ["manual"],
+ )
+ java_sdk_library(
+ name = "dep",
+ public = SCOPE_TO_JAVA_SDK_LIBRARY_FILE["public"],
+ system = SCOPE_TO_JAVA_SDK_LIBRARY_FILE["system"],
+ module_lib = SCOPE_TO_JAVA_SDK_LIBRARY_FILE["module-lib"],
+ system_server = SCOPE_TO_JAVA_SDK_LIBRARY_FILE["system-server"],
+ )
+ basic_merged_txts_test(
+ name = name,
+ target_under_test = target_name,
+ scope = scope,
+ base = base,
+ )
+ return name
+
+def test_generated_system_current_txt():
+ name = "generated_system_current_txt_test"
+ target_name = name + "_target"
+ scope = "system"
+ base = "non-updatable-system-current.txt"
+ merged_txts(
+ name = target_name,
+ scope = scope,
+ base = base,
+ deps = ["dep"],
+ tags = ["manual"],
+ )
+ basic_merged_txts_test(
+ name = name,
+ target_under_test = target_name,
+ scope = scope,
+ base = base,
+ )
+ return name
+
+def test_generated_module_lib_current_txt():
+ name = "generated_module_lib_current_txt_test"
+ target_name = name + "_target"
+ scope = "module-lib"
+ base = "non-updatable-module-lib_current.txt"
+ merged_txts(
+ name = target_name,
+ scope = scope,
+ base = base,
+ deps = ["dep"],
+ tags = ["manual"],
+ )
+ basic_merged_txts_test(
+ name = name,
+ target_under_test = target_name,
+ scope = scope,
+ base = base,
+ )
+ return name
+
+def test_generated_system_server_current_txt():
+ name = "generated_system_server_current_txt_test"
+ target_name = name + "_target"
+ scope = "system-server"
+ base = "non-updatable-system-server-current.txt"
+ merged_txts(
+ name = target_name,
+ scope = scope,
+ base = base,
+ deps = ["dep"],
+ tags = ["manual"],
+ )
+ basic_merged_txts_test(
+ name = name,
+ target_under_test = target_name,
+ scope = scope,
+ base = base,
+ )
+ return name
+
+def merged_txts_test_suite(name):
+ native.test_suite(
+ name = name,
+ tests = [
+ test_generated_current_txt(),
+ test_generated_system_current_txt(),
+ test_generated_module_lib_current_txt(),
+ test_generated_system_server_current_txt(),
+ ],
+ )
diff --git a/rules/java/proto.bzl b/rules/java/proto.bzl
index fa2d5675..68533d20 100644
--- a/rules/java/proto.bzl
+++ b/rules/java/proto.bzl
@@ -1,22 +1,19 @@
-"""
-Copyright (C) 2021 The Android Open Source Project
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-"""
+# Copyright (C) 2021 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
load("//build/bazel/rules:proto_file_utils.bzl", "proto_file_utils")
-load("@bazel_skylib//lib:paths.bzl", "paths")
-load(":library.bzl", "java_library")
+load(":rules.bzl", "java_library")
def _java_proto_sources_gen_rule_impl(ctx):
out_flags = []
@@ -30,17 +27,20 @@ def _java_proto_sources_gen_rule_impl(ctx):
out_flags.append(ctx.attr.out_format)
srcs = []
+ proto_infos = []
+
for dep in ctx.attr.deps:
- proto_info = dep[ProtoInfo]
- out_jar = _generate_java_proto_action(
- proto_info = proto_info,
- protoc = ctx.executable._protoc,
- ctx = ctx,
- out_flags = out_flags,
- plugin_executable = plugin_executable,
- out_arg = out_arg,
- )
- srcs.append(out_jar)
+ proto_infos.append(dep[ProtoInfo])
+
+ out_jar = _generate_java_proto_action(
+ proto_infos = proto_infos,
+ protoc = ctx.executable._protoc,
+ ctx = ctx,
+ out_flags = out_flags,
+ plugin_executable = plugin_executable,
+ out_arg = out_arg,
+ )
+ srcs.append(out_jar)
return [
DefaultInfo(files = depset(direct = srcs)),
@@ -76,14 +76,14 @@ If not provided, defaults to full protos.
)
def _generate_java_proto_action(
- proto_info,
+ proto_infos,
protoc,
ctx,
plugin_executable,
out_arg,
out_flags):
return proto_file_utils.generate_jar_proto_action(
- proto_info,
+ proto_infos,
protoc,
ctx,
out_flags,
@@ -96,9 +96,10 @@ def _java_proto_library(
name,
deps = [],
plugin = None,
- target_compatible_with = [],
out_format = None,
- proto_dep = None):
+ proto_dep = None,
+ sdk_version = "core_current",
+ **kwargs):
proto_sources_name = name + "_proto_gen"
_java_proto_sources_gen(
@@ -106,6 +107,7 @@ def _java_proto_library(
deps = deps,
plugin = plugin,
out_format = out_format,
+ tags = ["manual"],
)
if proto_dep:
@@ -117,70 +119,61 @@ def _java_proto_library(
name = name,
srcs = [proto_sources_name],
deps = deps,
- target_compatible_with = target_compatible_with,
+ sdk_version = sdk_version,
+ **kwargs
)
def java_nano_proto_library(
name,
- deps = [],
plugin = "//external/protobuf:protoc-gen-javanano",
- target_compatible_with = []):
+ **kwargs):
_java_proto_library(
name,
- deps = deps,
plugin = plugin,
- target_compatible_with = target_compatible_with,
proto_dep = "//external/protobuf:libprotobuf-java-nano",
+ **kwargs
)
def java_micro_proto_library(
name,
- deps = [],
plugin = "//external/protobuf:protoc-gen-javamicro",
- target_compatible_with = []):
+ **kwargs):
_java_proto_library(
name,
- deps = deps,
plugin = plugin,
- target_compatible_with = target_compatible_with,
proto_dep = "//external/protobuf:libprotobuf-java-micro",
+ **kwargs
)
def java_lite_proto_library(
name,
- deps = [],
plugin = None,
- target_compatible_with = []):
+ **kwargs):
_java_proto_library(
name,
- deps = deps,
plugin = plugin,
- target_compatible_with = target_compatible_with,
out_format = "lite",
proto_dep = "//external/protobuf:libprotobuf-java-lite",
+ **kwargs
)
def java_stream_proto_library(
name,
- deps = [],
plugin = "//frameworks/base/tools/streaming_proto:protoc-gen-javastream",
- target_compatible_with = []):
+ **kwargs):
_java_proto_library(
name,
- deps = deps,
plugin = plugin,
- target_compatible_with = target_compatible_with,
+ **kwargs
)
def java_proto_library(
name,
- deps = [],
plugin = None,
- target_compatible_with = []):
+ **kwargs):
_java_proto_library(
name,
- deps = deps,
plugin = plugin,
- target_compatible_with = target_compatible_with,
proto_dep = "//external/protobuf:libprotobuf-java-full",
+ **kwargs
)
diff --git a/rules/java/rules.bzl b/rules/java/rules.bzl
new file mode 100644
index 00000000..575321b2
--- /dev/null
+++ b/rules/java/rules.bzl
@@ -0,0 +1,30 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http:#www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+load(
+ "@rules_java//java:defs.bzl",
+ _java_binary = "java_binary",
+)
+load(
+ "//build/bazel/rules/java:import.bzl",
+ _java_import = "java_import",
+)
+load(
+ "//build/bazel/rules/java:library.bzl",
+ _java_library = "java_library",
+)
+
+java_binary = _java_binary
+java_library = _java_library
+java_import = _java_import
diff --git a/rules/java/sdk/BUILD.bazel b/rules/java/sdk/BUILD.bazel
new file mode 100644
index 00000000..b00ba819
--- /dev/null
+++ b/rules/java/sdk/BUILD.bazel
@@ -0,0 +1,112 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+package(
+ default_visibility = ["//visibility:public"],
+)
+
+load("@bazel_skylib//rules:common_settings.bzl", "int_setting", "string_setting")
+load("//build/bazel/rules/common:sdk_version.bzl", "sdk_version")
+load("//build/bazel/rules/common:api.bzl", "api")
+load("//build/bazel/rules/java:versions.bzl", "java_versions")
+load(":config_setting_names.bzl", "config_setting_names")
+load("@bazel_skylib//lib:selects.bzl", "selects")
+load("//prebuilts/sdk:utils.bzl", "prebuilt_sdk_utils")
+
+string_setting(
+ name = "kind",
+ build_setting_default = sdk_version.KIND_PUBLIC,
+ values = sdk_version.ALL_KINDS,
+)
+
+int_setting(
+ name = "api_level",
+ build_setting_default = api.FUTURE_API_LEVEL,
+)
+
+# The settings below are used to properly define a device java and android toolchain.
+
+# The SDK_NONE config setting maps to sdk_version = "none". In this configuration the java toolchain
+# will provide nothing on the bootclasspath, not even the standard java.* libraries.
+# The android toolchain is undefined in this configuration.
+config_setting(
+ name = config_setting_names.SDK_NONE,
+ flag_values = {
+ "//build/bazel/rules/java/sdk:kind": sdk_version.KIND_NONE,
+ },
+)
+
+# Pre and Post Java 9 configs differ in how the bootclasspath is constructed and what arguments must
+# be passed to javac. Pre Java 9, the SDK is passed as a whole to the --bootclasspath argument of
+# javac. Post Java 9, the SDK is split between core libraries, passed using system modules and the
+# --system javac argument, and the rest, added at the beginning of the classpath.
+selects.config_setting_group(
+ name = config_setting_names.PRE_JAVA_9,
+ match_any = [
+ "//build/bazel/rules/java:" + java_versions.VERSION_TO_CONFIG_SETTING[version]
+ for version in java_versions.VERSION_TO_CONFIG_SETTING.keys()
+ if version < 9
+ ],
+)
+
+selects.config_setting_group(
+ name = config_setting_names.POST_JAVA_9,
+ match_any = [
+ "//build/bazel/rules/java:" + java_versions.VERSION_TO_CONFIG_SETTING[version]
+ for version in java_versions.VERSION_TO_CONFIG_SETTING.keys()
+ if version >= 9
+ ],
+)
+
+# Specific configuration at a given kind and api level will have the java and android toolchains
+# pointed to the proper android.jar and framework.aidl files.
+[
+ config_setting(
+ name = config_setting_names.kind_api(kind, api_level),
+ flag_values = {
+ "//build/bazel/rules/java/sdk:kind": kind,
+ "//build/bazel/rules/java/sdk:api_level": str(api_level),
+ },
+ )
+ for api_level in prebuilt_sdk_utils.API_LEVELS
+ for kind in prebuilt_sdk_utils.available_kinds_for_api_level(api_level)
+]
+
+# The bootclasspath is a function of sdk kind, api level, and whether building for pre or post java
+# 9 sources.
+[
+ selects.config_setting_group(
+ name = config_setting_names.kind_api_pre_java_9(kind, api_level),
+ match_all = [
+ config_setting_names.kind_api(kind, api_level),
+ config_setting_names.PRE_JAVA_9,
+ ],
+ )
+ for api_level in prebuilt_sdk_utils.API_LEVELS
+ for kind in prebuilt_sdk_utils.available_kinds_for_api_level(api_level)
+ if java_versions.supports_pre_java_9(api_level)
+]
+
+[
+ selects.config_setting_group(
+ name = config_setting_names.kind_api_post_java_9(kind, api_level),
+ match_all = [
+ config_setting_names.kind_api(kind, api_level),
+ config_setting_names.POST_JAVA_9,
+ ],
+ )
+ for api_level in prebuilt_sdk_utils.API_LEVELS
+ for kind in prebuilt_sdk_utils.available_kinds_for_api_level(api_level)
+ if java_versions.supports_post_java_9(api_level)
+]
diff --git a/rules/java/sdk/config_setting_names.bzl b/rules/java/sdk/config_setting_names.bzl
new file mode 100644
index 00000000..2150465f
--- /dev/null
+++ b/rules/java/sdk/config_setting_names.bzl
@@ -0,0 +1,35 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+def _kind_api(kind, api_level):
+ return "config_setting_android_%s_%s" % (kind, api_level)
+
+def _kind_api_pre_java_9(kind, api_level):
+ return _kind_api(kind, api_level) + "_pre_java_9"
+
+def _kind_api_post_java_9(kind, api_level):
+ return _kind_api(kind, api_level) + "_post_java_9"
+
+_CONFIG_SETTING_SDK_NONE = "config_setting_sdk_none"
+_CONFIG_SETTING_PRE_JAVA_9 = "config_setting_pre_java_9"
+_CONFIG_SETTING_POST_JAVA_9 = "config_setting_post_java_9"
+
+config_setting_names = struct(
+ SDK_NONE = _CONFIG_SETTING_SDK_NONE,
+ PRE_JAVA_9 = _CONFIG_SETTING_PRE_JAVA_9,
+ POST_JAVA_9 = _CONFIG_SETTING_POST_JAVA_9,
+ kind_api = _kind_api,
+ kind_api_pre_java_9 = _kind_api_pre_java_9,
+ kind_api_post_java_9 = _kind_api_post_java_9,
+)
diff --git a/rules/java/sdk_library.bzl b/rules/java/sdk_library.bzl
new file mode 100644
index 00000000..82f6eb3c
--- /dev/null
+++ b/rules/java/sdk_library.bzl
@@ -0,0 +1,61 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+JavaSdkLibraryInfo = provider(
+ "Checked in current.txt for Public, System, Module_lib and System_server",
+ fields = [
+ "public",
+ "system",
+ "test",
+ "module_lib",
+ "system_server",
+ ],
+)
+
+def _java_sdk_library_impl(ctx):
+ return [
+ JavaSdkLibraryInfo(
+ public = ctx.file.public,
+ system = ctx.file.system,
+ test = ctx.file.test,
+ module_lib = ctx.file.module_lib,
+ system_server = ctx.file.system_server,
+ ),
+ ]
+
+java_sdk_library = rule(
+ implementation = _java_sdk_library_impl,
+ attrs = {
+ "public": attr.label(
+ allow_single_file = True,
+ doc = "public api surface file",
+ ),
+ "system": attr.label(
+ allow_single_file = True,
+ doc = "system api surface file",
+ ),
+ "test": attr.label(
+ allow_single_file = True,
+ doc = "test api surface file",
+ ),
+ "module_lib": attr.label(
+ allow_single_file = True,
+ doc = "module_lib api surface file",
+ ),
+ "system_server": attr.label(
+ allow_single_file = True,
+ doc = "system_server api surface file",
+ ),
+ },
+)
diff --git a/rules/java/sdk_library_test.bzl b/rules/java/sdk_library_test.bzl
new file mode 100644
index 00000000..ca954766
--- /dev/null
+++ b/rules/java/sdk_library_test.bzl
@@ -0,0 +1,115 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
+load(":sdk_library.bzl", "JavaSdkLibraryInfo", "java_sdk_library")
+
+def _basic_java_sdk_library_test_impl(ctx):
+ env = analysistest.begin(ctx)
+ java_sdk_library_target = analysistest.target_under_test(env)
+
+ asserts.true(
+ env,
+ java_sdk_library_target[JavaSdkLibraryInfo].public.is_source,
+ "Public api surface file should be source, not generated",
+ )
+
+ asserts.equals(
+ env,
+ expected = "public.txt",
+ actual = java_sdk_library_target[JavaSdkLibraryInfo].public.basename,
+ msg = "Public api surface file not correct",
+ )
+
+ asserts.true(
+ env,
+ java_sdk_library_target[JavaSdkLibraryInfo].system.is_source,
+ "System api surface file should be source, not generated",
+ )
+
+ asserts.equals(
+ env,
+ expected = "system.txt",
+ actual = java_sdk_library_target[JavaSdkLibraryInfo].system.basename,
+ msg = "System api surface file not correct",
+ )
+
+ asserts.true(
+ env,
+ java_sdk_library_target[JavaSdkLibraryInfo].test.is_source,
+ "Test api surface file should be source, not generated",
+ )
+
+ asserts.equals(
+ env,
+ expected = "test.txt",
+ actual = java_sdk_library_target[JavaSdkLibraryInfo].test.basename,
+ msg = "Test api surface file not correct",
+ )
+
+ asserts.true(
+ env,
+ java_sdk_library_target[JavaSdkLibraryInfo].module_lib.is_source,
+ "Module_lib api surface file should be source, not generated",
+ )
+
+ asserts.equals(
+ env,
+ expected = "module_lib.txt",
+ actual = java_sdk_library_target[JavaSdkLibraryInfo].module_lib.basename,
+ msg = "Module_lib api surface file not correct",
+ )
+
+ asserts.true(
+ env,
+ java_sdk_library_target[JavaSdkLibraryInfo].system_server.is_source,
+ "System_server api surface file should be source, not generated",
+ )
+
+ asserts.equals(
+ env,
+ expected = "system_server.txt",
+ actual = java_sdk_library_target[JavaSdkLibraryInfo].system_server.basename,
+ msg = "System_server api surface file not correct",
+ )
+
+ return analysistest.end(env)
+
+basic_java_sdk_library_test = analysistest.make(
+ _basic_java_sdk_library_test_impl,
+)
+
+def test_checked_in_api_surface_files():
+ name = "checked_in_api_surface_files_test"
+ java_sdk_library(
+ name = name + "_target",
+ public = "public.txt",
+ system = "system.txt",
+ test = "test.txt",
+ module_lib = "module_lib.txt",
+ system_server = "system_server.txt",
+ )
+ basic_java_sdk_library_test(
+ name = name,
+ target_under_test = name + "_target",
+ )
+ return name
+
+def java_sdk_library_test_suite(name):
+ native.test_suite(
+ name = name,
+ tests = [
+ test_checked_in_api_surface_files(),
+ ],
+ )
diff --git a/rules/java/sdk_transition.bzl b/rules/java/sdk_transition.bzl
new file mode 100644
index 00000000..7f69d09d
--- /dev/null
+++ b/rules/java/sdk_transition.bzl
@@ -0,0 +1,68 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+load("//build/bazel/rules/java:versions.bzl", "java_versions")
+load("//build/bazel/rules/common:sdk_version.bzl", "sdk_version")
+load("//build/bazel/rules/common:api.bzl", "api")
+
+def _sdk_transition_impl(settings, attr):
+ host_platform = settings["//command_line_option:host_platform"]
+ default_java_version = str(java_versions.get_version())
+
+ # TODO: this condition should really be "platform is not a device".
+ # More details on why we're treating java version for non-device platforms differently at the
+ # definition of the //build/bazel/rules/java:host_version build setting.
+ if all([host_platform == platform for platform in settings["//command_line_option:platforms"]]):
+ return {
+ "//build/bazel/rules/java:version": default_java_version,
+ "//build/bazel/rules/java:host_version": str(java_versions.get_version(attr.java_version)),
+ "//build/bazel/rules/java/sdk:kind": sdk_version.KIND_NONE,
+ "//build/bazel/rules/java/sdk:api_level": api.NONE_API_LEVEL,
+ }
+ sdk_spec = sdk_version.sdk_spec_from(attr.sdk_version)
+ java_version = str(java_versions.get_version(attr.java_version, sdk_spec.api_level))
+
+ return {
+ "//build/bazel/rules/java:host_version": default_java_version,
+ "//build/bazel/rules/java:version": java_version,
+ "//build/bazel/rules/java/sdk:kind": sdk_spec.kind,
+ "//build/bazel/rules/java/sdk:api_level": sdk_spec.api_level,
+ }
+
+sdk_transition = transition(
+ implementation = _sdk_transition_impl,
+ inputs = [
+ "//command_line_option:host_platform",
+ "//command_line_option:platforms",
+ ],
+ outputs = [
+ "//build/bazel/rules/java:version",
+ "//build/bazel/rules/java:host_version",
+ "//build/bazel/rules/java/sdk:kind",
+ "//build/bazel/rules/java/sdk:api_level",
+ ],
+)
+
+sdk_transition_attrs = {
+ # This attribute must have a specific name to let the DexArchiveAspect propagate
+ # through it.
+ "exports": attr.label(
+ cfg = sdk_transition,
+ ),
+ "java_version": attr.string(),
+ "sdk_version": attr.string(),
+ "_allowlist_function_transition": attr.label(
+ default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
+ ),
+}
diff --git a/rules/java/sdk_transition_test.bzl b/rules/java/sdk_transition_test.bzl
new file mode 100644
index 00000000..6dd90441
--- /dev/null
+++ b/rules/java/sdk_transition_test.bzl
@@ -0,0 +1,173 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+load(":sdk_transition.bzl", "sdk_transition")
+load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
+load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo")
+
+SdkConfig = provider(
+ "Info about the config settings of the leaf dependency (in a linear dependency chain only)",
+ fields = {
+ "java_version": "the value of the //build/bazel/rules/java:version setting.",
+ "host_java_version": "the value of the //build/bazel/rules/java:host_version setting.",
+ "sdk_kind": "the value of the //build/bazel/rules/java/sdk:kind setting.",
+ "api_level": "the value of the //build/bazel/rules/java/sdk:api_level setting.",
+ },
+)
+
+def _sdk_transition_tester_impl(ctx):
+ if ctx.attr.exports and len(ctx.attr.exports) > 0 and SdkConfig in ctx.attr.exports[0]:
+ return ctx.attr.exports[0][SdkConfig]
+ return SdkConfig(
+ java_version = ctx.attr._java_version_config_setting[BuildSettingInfo].value,
+ host_java_version = ctx.attr._host_java_version_config_setting[BuildSettingInfo].value,
+ sdk_kind = ctx.attr._sdk_kind_config_setting[BuildSettingInfo].value,
+ api_level = ctx.attr._api_level_config_setting[BuildSettingInfo].value,
+ )
+
+sdk_transition_tester = rule(
+ implementation = _sdk_transition_tester_impl,
+ attrs = {
+ "exports": attr.label(
+ cfg = sdk_transition,
+ providers = [SdkConfig],
+ ),
+ "java_version": attr.string(),
+ "sdk_version": attr.string(),
+ "_java_version_config_setting": attr.label(
+ default = "//build/bazel/rules/java:version",
+ ),
+ "_host_java_version_config_setting": attr.label(
+ default = "//build/bazel/rules/java:host_version",
+ ),
+ "_sdk_kind_config_setting": attr.label(
+ default = "//build/bazel/rules/java/sdk:kind",
+ ),
+ "_api_level_config_setting": attr.label(
+ default = "//build/bazel/rules/java/sdk:api_level",
+ ),
+ "_allowlist_function_transition": attr.label(
+ default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
+ ),
+ },
+)
+
+def _sdk_transition_host_test_impl(ctx):
+ env = analysistest.begin(ctx)
+ actual_config = analysistest.target_under_test(env)[SdkConfig]
+ asserts.equals(
+ env,
+ ctx.attr.expected_host_java_version,
+ actual_config.host_java_version,
+ "mismatching host_java_version",
+ )
+ return analysistest.end(env)
+
+def _sdk_transition_device_test_impl(ctx):
+ env = analysistest.begin(ctx)
+ actual_config = analysistest.target_under_test(env)[SdkConfig]
+ asserts.equals(
+ env,
+ ctx.attr.expected_java_version,
+ actual_config.java_version,
+ "mismatching java_version",
+ )
+ asserts.equals(
+ env,
+ ctx.attr.expected_sdk_kind,
+ actual_config.sdk_kind,
+ "mismatching sdk_kind",
+ )
+ asserts.equals(
+ env,
+ ctx.attr.expected_api_level,
+ actual_config.api_level,
+ "mismatching api_level",
+ )
+ return analysistest.end(env)
+
+sdk_transition_host_test = analysistest.make(
+ impl = _sdk_transition_host_test_impl,
+ attrs = {
+ "expected_host_java_version": attr.string(),
+ },
+ config_settings = {
+ "//command_line_option:platforms": "@//build/bazel/tests/products:aosp_arm64_for_testing_linux_x86_64",
+ "//command_line_option:host_platform": "@//build/bazel/tests/products:aosp_arm64_for_testing_linux_x86_64",
+ },
+)
+
+sdk_transition_device_test = analysistest.make(
+ impl = _sdk_transition_device_test_impl,
+ attrs = {
+ "expected_java_version": attr.string(),
+ "expected_sdk_kind": attr.string(),
+ "expected_api_level": attr.int(),
+ },
+ config_settings = {
+ "//command_line_option:platforms": "@//build/bazel/tests/products:aosp_arm64_for_testing",
+ "//command_line_option:host_platform": "@//build/bazel/tests/products:aosp_arm64_for_testing_linux_x86_64",
+ },
+)
+
+def set_up_targets_under_test(name, java_version, sdk_version):
+ sdk_transition_tester(
+ name = name + "_parent",
+ java_version = java_version,
+ sdk_version = sdk_version,
+ exports = name + "_child",
+ tags = ["manual"],
+ )
+ sdk_transition_tester(
+ name = name + "_child",
+ tags = ["manual"],
+ )
+
+def test_host_sdk_transition(
+ name,
+ java_version,
+ expected_host_java_version):
+ set_up_targets_under_test(name, java_version, sdk_version = None)
+ sdk_transition_host_test(
+ name = name,
+ target_under_test = name + "_parent",
+ expected_host_java_version = expected_host_java_version,
+ )
+ return name
+
+def test_device_sdk_transition(
+ name,
+ java_version,
+ sdk_version,
+ expected_java_version,
+ expected_sdk_kind,
+ expected_api_level):
+ set_up_targets_under_test(name, java_version, sdk_version)
+ sdk_transition_device_test(
+ name = name,
+ target_under_test = name + "_parent",
+ expected_java_version = expected_java_version,
+ expected_sdk_kind = expected_sdk_kind,
+ expected_api_level = expected_api_level,
+ )
+ return name
+
+def sdk_transition_test_suite(name):
+ native.test_suite(
+ name = name,
+ tests = [
+ test_host_sdk_transition("test_host_sdk_transition", java_version = "8", expected_host_java_version = "8"),
+ test_device_sdk_transition("test_device_sdk_transition", java_version = "9", sdk_version = "32", expected_java_version = "9", expected_sdk_kind = "public", expected_api_level = 32),
+ ],
+ )
diff --git a/rules/java/stub_local_jdk/BUILD.bazel b/rules/java/stub_local_jdk/BUILD.bazel
new file mode 100644
index 00000000..0902d775
--- /dev/null
+++ b/rules/java/stub_local_jdk/BUILD.bazel
@@ -0,0 +1,8 @@
+package(default_visibility = ["//visibility:public"])
+
+#The Kotlin rules directly refer to @local_jdk//jar, this alias is defined to
+# keep this reference valid.
+alias(
+ name = "jar",
+ actual = "@//prebuilts/jdk/jdk17:jar",
+)
diff --git a/rules/java/stub_local_jdk/WORKSPACE b/rules/java/stub_local_jdk/WORKSPACE
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/rules/java/stub_local_jdk/WORKSPACE
diff --git a/rules/java/versions.bzl b/rules/java/versions.bzl
new file mode 100644
index 00000000..acee980e
--- /dev/null
+++ b/rules/java/versions.bzl
@@ -0,0 +1,104 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Constants and utility functions relating to Java versions and how they map to SDK versions.
+"""
+
+load("//build/bazel/rules/common:api.bzl", "api")
+
+# The default java version used absent any java_version or sdk_version specification.
+_DEFAULT_VERSION = 17
+
+# All available java versions
+_ALL_VERSIONS = [
+ 7,
+ 8,
+ 9,
+ 11,
+ 17,
+]
+
+_VERSION_TO_CONFIG_SETTING = {
+ java_version: "config_setting_java_%s" % java_version
+ for java_version in _ALL_VERSIONS
+}
+
+def _compatible_versions_for_api_level(api_level):
+ """Returns all possible java versions that can be used at the given api level."""
+ if api_level in (api.FUTURE_API_LEVEL, api.NONE_API_LEVEL):
+ return _ALL_VERSIONS
+ if api_level <= 23:
+ return [7]
+ if api_level <= 29:
+ return [
+ 7,
+ 8,
+ ]
+ if api_level <= 31:
+ return [
+ 7,
+ 8,
+ 9,
+ ]
+ if api_level <= 33:
+ return [
+ 7,
+ 8,
+ 9,
+ 11,
+ ]
+ return _ALL_VERSIONS
+
+def _supports_pre_java_9(api_level):
+ return any([
+ version < 9
+ for version in _compatible_versions_for_api_level(api_level)
+ ])
+
+def _supports_post_java_9(api_level):
+ return any([
+ version >= 9
+ for version in _compatible_versions_for_api_level(api_level)
+ ])
+
+_NORMALIZED_VERSIONS = {
+ "1.7": 7,
+ "7": 7,
+ "1.8": 8,
+ "8": 8,
+ "1.9": 9,
+ "9": 9,
+ "11": 11,
+ "17": 17,
+}
+
+def _default_version(api_level):
+ """Returns the default java version for the input api level."""
+ return max(_compatible_versions_for_api_level(api_level))
+
+def _get_version(java_version = None, api_level = None):
+ """Returns the java version to use for a given target based on the java_version set by this target and the api_level_string extracted from sdk_version."""
+ if java_version:
+ return _NORMALIZED_VERSIONS[java_version]
+ elif api_level:
+ return _default_version(api_level)
+ return _DEFAULT_VERSION
+
+java_versions = struct(
+ ALL_VERSIONS = _ALL_VERSIONS,
+ VERSION_TO_CONFIG_SETTING = _VERSION_TO_CONFIG_SETTING,
+ compatible_versions_for_api_level = _compatible_versions_for_api_level,
+ get_version = _get_version,
+ supports_pre_java_9 = _supports_pre_java_9,
+ supports_post_java_9 = _supports_post_java_9,
+)
diff --git a/rules/java/versions_test.bzl b/rules/java/versions_test.bzl
new file mode 100644
index 00000000..f06488b1
--- /dev/null
+++ b/rules/java/versions_test.bzl
@@ -0,0 +1,44 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+load("@bazel_skylib//lib:unittest.bzl", "asserts", "unittest")
+load("//build/bazel/rules/java:versions.bzl", "java_versions")
+load("//build/bazel/rules/common:api.bzl", "api")
+
+def _get_java_version_test_impl(ctx):
+ env = unittest.begin(ctx)
+
+ _VERSIONS_UNDER_TEST = {
+ (None, api.FUTURE_API_LEVEL): 17,
+ (None, 23): 7,
+ (None, 33): 11,
+ ("1.7", api.FUTURE_API_LEVEL): 7,
+ ("1.7", 23): 7,
+ ("1.8", 33): 8,
+ (None, None): 17,
+ }
+ for java_sdk_version, expected_java_version in _VERSIONS_UNDER_TEST.items():
+ java_version = java_sdk_version[0]
+ sdk_version = java_sdk_version[1]
+ asserts.equals(env, expected_java_version, java_versions.get_version(java_version, sdk_version), "unexpected java version for java_version %s and sdk_version %s" % (java_version, sdk_version))
+
+ return unittest.end(env)
+
+get_java_version_test = unittest.make(_get_java_version_test_impl)
+
+def versions_test_suite(name):
+ unittest.suite(
+ name,
+ get_java_version_test,
+ )
diff --git a/rules/java/wrapper_test.sh b/rules/java/wrapper_test.sh
new file mode 100644
index 00000000..abab4214
--- /dev/null
+++ b/rules/java/wrapper_test.sh
@@ -0,0 +1,38 @@
+#!/bin/bash -eux
+
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+if [[ ! -d "build/bazel/ci" ]]; then
+ echo "Please run this script from TOP".
+ exit 1
+fi
+
+source "build/bazel/ci/build_with_bazel.sh"
+source "build/bazel/ci/target_lists.sh"
+
+function test_wrapper_providers() {
+ for target in ${EXAMPLE_WRAPPER_TARGETS[@]}; do
+ private_providers="$(build/bazel/bin/bazel ${STARTUP_FLAGS[@]} \
+ cquery ${FLAGS[@]} --config=android "${target}_private" \
+ --starlark:expr="sorted(providers(target).keys())" --output=starlark|uniq)"
+ wrapper_providers="$(build/bazel/bin/bazel ${STARTUP_FLAGS[@]} \
+ cquery ${FLAGS[@]} --config=android "${target}" \
+ --starlark:expr="sorted(providers(target).keys())" --output=starlark|uniq)"
+ if [[ ! $(cmp -s <(echo "${private_providers}") <(echo "${wrapper_providers}")) ]]; then
+ echo "${target} and ${target}_private should have the same providers. Diff:"
+ diff <(echo "${private_providers}") <(echo "${wrapper_providers}")
+ fi
+ done
+}