Attach Java runtime to Java toolchains
Defining a new rule "java_runtime_version_alias", which uses a custom configuration flag transition to select a specific version of remote JDK.
Added a weird "selected_java_runtime" attribute, which needs to exist until the incompatible_use_java_toolchain_resolution is flipped.
Added the test for the attached runtime and fixing the test for host_javabase (now it is only modified for targets in exec configuration).
Bootstrap_toolchain had to be moved to another file, because of java_runtime attribute, which is not yet released.
Related to https://github.com/bazelbuild/bazel/issues/4592
Closes #12677.
PiperOrigin-RevId: 346825514
diff --git a/scripts/bootstrap/BUILD.bootstrap b/scripts/bootstrap/BUILD.bootstrap
new file mode 100644
index 0000000..b5991f6
--- /dev/null
+++ b/scripts/bootstrap/BUILD.bootstrap
@@ -0,0 +1,23 @@
+load("@bazel_tools//tools/jdk:default_java_toolchain.bzl", "default_java_toolchain")
+
+# This toolchain is used to bootstrap Bazel.
+default_java_toolchain(
+ name = "bootstrap_toolchain",
+ bootclasspath = ["@bazel_tools//tools/jdk:platformclasspath.jar"],
+ genclass = ["//src/java_tools/buildjar:bootstrap_genclass_deploy.jar"],
+ ijar = ["//third_party/ijar"],
+ java_runtime = "@local_jdk//:jdk",
+ javabuilder = ["//src/java_tools/buildjar:bootstrap_VanillaJavaBuilder_deploy.jar"],
+ jvm_opts = [
+ # Prevent "Could not reserve enough space for object heap" errors on Windows.
+ "-Xmx512m",
+ # Using tiered compilation improves performance of Javac when not using the worker mode.
+ "-XX:+TieredCompilation",
+ "-XX:TieredStopAtLevel=1",
+ ],
+ singlejar = ["//src/java_tools/singlejar:bootstrap_deploy.jar"],
+ source_version = "8",
+ tags = ["manual"],
+ target_version = "8",
+ visibility = ["//visibility:public"],
+)
diff --git a/scripts/bootstrap/bootstrap.sh b/scripts/bootstrap/bootstrap.sh
index a42c861..597379b 100755
--- a/scripts/bootstrap/bootstrap.sh
+++ b/scripts/bootstrap/bootstrap.sh
@@ -36,12 +36,15 @@
--strategy=Javac=worker --worker_quit_after_build --ignore_unsupported_sandboxing \
--compilation_mode=opt \
--distdir=derived/distdir \
- --java_toolchain=//src/java_tools/buildjar:bootstrap_toolchain \
- --host_java_toolchain=//src/java_tools/buildjar:bootstrap_toolchain \
- --extra_toolchains=//src/java_tools/buildjar:bootstrap_toolchain_definition \
+ --java_toolchain=//scripts/bootstrap:bootstrap_toolchain \
+ --host_java_toolchain=//scripts/bootstrap:bootstrap_toolchain \
+ --incompatible_use_toolchain_resolution_for_java_rules \
+ --extra_toolchains=//scripts/bootstrap:bootstrap_toolchain_definition \
${DIST_BOOTSTRAP_ARGS:-} \
${EXTRA_BAZEL_ARGS:-}"
+cp scripts/bootstrap/BUILD.bootstrap scripts/bootstrap/BUILD
+
if [ -z "${BAZEL-}" ]; then
function _run_bootstrapping_bazel() {
local command=$1
diff --git a/src/java_tools/buildjar/BUILD b/src/java_tools/buildjar/BUILD
index 6edcb24..cf24d76 100644
--- a/src/java_tools/buildjar/BUILD
+++ b/src/java_tools/buildjar/BUILD
@@ -1,5 +1,4 @@
load("@rules_java//java:defs.bzl", "java_binary")
-load("@bazel_tools//tools/jdk:default_java_toolchain.bzl", "default_java_toolchain")
# Description:
# JavaBuilder and java tools used by Bazel
@@ -54,24 +53,3 @@
tags = ["manual"],
visibility = ["//visibility:public"],
)
-
-# This toolchain is used to bootstrap Bazel.
-default_java_toolchain(
- name = "bootstrap_toolchain",
- bootclasspath = ["@bazel_tools//tools/jdk:platformclasspath.jar"],
- genclass = ["bootstrap_genclass_deploy.jar"],
- ijar = ["//third_party/ijar"],
- javabuilder = ["bootstrap_VanillaJavaBuilder_deploy.jar"],
- jvm_opts = [
- # Prevent "Could not reserve enough space for object heap" errors on Windows.
- "-Xmx512m",
- # Using tiered compilation improves performance of Javac when not using the worker mode.
- "-XX:+TieredCompilation",
- "-XX:TieredStopAtLevel=1",
- ],
- singlejar = ["//src/java_tools/singlejar:bootstrap_deploy.jar"],
- source_version = "8",
- tags = ["manual"],
- target_version = "8",
- visibility = ["//visibility:public"],
-)
diff --git a/src/java_tools/singlejar/BUILD b/src/java_tools/singlejar/BUILD
index 2de4688..4eeae88 100644
--- a/src/java_tools/singlejar/BUILD
+++ b/src/java_tools/singlejar/BUILD
@@ -1,7 +1,10 @@
# Description:
# SingleJar combines multiple zip files and additional files
# into a single zip file.
-package(default_visibility = ["//src/java_tools:__subpackages__"])
+package(default_visibility = [
+ "//scripts/bootstrap:__subpackages__",
+ "//src/java_tools:__subpackages__",
+])
filegroup(
name = "srcs",
diff --git a/src/test/shell/bazel/bazel_java14_test.sh b/src/test/shell/bazel/bazel_java14_test.sh
index 51882b8..b9db489 100755
--- a/src/test/shell/bazel/bazel_java14_test.sh
+++ b/src/test/shell/bazel/bazel_java14_test.sh
@@ -125,8 +125,7 @@
}
}
EOF
- # TODO(ilist): remove tool_java_runtime_version after java_runtime is attached to the toolchain
- bazel run java/main:Javac14Example --java_language_version=14 --java_runtime_version=14 --tool_java_runtime_version=14 --test_output=all --verbose_failures &>"${TEST_log}"
+ bazel run java/main:Javac14Example --java_language_version=14 --java_runtime_version=14 --test_output=all --verbose_failures &>"${TEST_log}"
expect_log "0"
}
diff --git a/src/test/shell/bazel/bazel_java15_test.sh b/src/test/shell/bazel/bazel_java15_test.sh
index ffe866e..118efac 100755
--- a/src/test/shell/bazel/bazel_java15_test.sh
+++ b/src/test/shell/bazel/bazel_java15_test.sh
@@ -125,8 +125,7 @@
}
}
EOF
- # TODO(ilist): remove tool_java_runtime_version after java_runtime is attached to the toolchain
- bazel run java/main:Javac15Example --java_language_version=15 --java_runtime_version=15 --tool_java_runtime_version=15 --test_output=all --verbose_failures &>"${TEST_log}"
+ bazel run java/main:Javac15Example --java_language_version=15 --java_runtime_version=15 --test_output=all --verbose_failures &>"${TEST_log}"
expect_log "^Hello,\$"
expect_log "^World\$"
}
diff --git a/src/test/shell/bazel/bazel_java_test_defaults.sh b/src/test/shell/bazel/bazel_java_test_defaults.sh
index a6bce31..22e18c9 100755
--- a/src/test/shell/bazel/bazel_java_test_defaults.sh
+++ b/src/test/shell/bazel/bazel_java_test_defaults.sh
@@ -155,6 +155,7 @@
bazel coverage java/main:JavaBinary \
--java_toolchain=//java/main:default_toolchain \
--javabase=@bazel_tools//tools/jdk:remote_jdk11 \
+ --extra_toolchains=//java/main:default_toolchain_definition \
--verbose_failures -s &>"${TEST_log}" \
&& fail "Coverage succeeded even when jacocorunner not set"
expect_log "jacocorunner not set in java_toolchain:"
diff --git a/src/test/shell/integration/bazel_java_test.sh b/src/test/shell/integration/bazel_java_test.sh
index 524f446..662a04a 100755
--- a/src/test/shell/integration/bazel_java_test.sh
+++ b/src/test/shell/integration/bazel_java_test.sh
@@ -44,7 +44,7 @@
expect_log "java-home: .*/embedded_tools/jdk"
}
-function test_host_javabase() {
+function test_toolchain_javabase() {
cat << EOF >> WORKSPACE
load("@bazel_tools//tools/jdk:local_java_repository.bzl", "local_java_repository")
local_java_repository(
@@ -66,27 +66,98 @@
mkdir -p foobar/bin
touch foobar/bin/java
- # We expect the given host_javabase to appear in the command line of
+ # We expect the given host_javabase does not appear in the command line of
# java_library actions.
bazel aquery --output=text --host_javabase=@host_javabase//:jdk --tool_java_runtime_version='host_javabase' //java:javalib >& $TEST_log
- expect_log "exec external/host_javabase/bin/java"
+ expect_log "exec external/remotejdk11_.*/bin/java"
+ expect_not_log "exec external/host_javabase/bin/java"
- # If we don't specify anything, we expect the embedded JDK to be used.
- # Note that this will change in the future but is the current state.
+ # If we don't specify anything, we expect the remote JDK to be used.
bazel aquery --output=text //java:javalib >& $TEST_log
expect_not_log "exec external/embedded_jdk/bin/java"
expect_log "exec external/remotejdk11_.*/bin/java"
bazel aquery --output=text --host_javabase=@host_javabase//:jdk --tool_java_runtime_version='host_javabase' \
//java:javalib >& $TEST_log
- expect_log "exec external/host_javabase/bin/java"
- expect_not_log "exec external/remotejdk_.*/bin/java"
+ expect_log "exec external/remotejdk11_.*/bin/java"
+ expect_not_log "exec external/host_javabase/bin/java"
bazel aquery --output=text \
//java:javalib >& $TEST_log
expect_log "exec external/remotejdk11_.*/bin/java"
+
+ # If we change language version to 15, we expect runtime to change
+ bazel aquery --incompatible_use_toolchain_resolution_for_java_rules --output=text --host_javabase=@host_javabase//:jdk \
+ --tool_java_runtime_version='host_javabase' --java_language_version=15 \
+ //java:javalib >& $TEST_log
+ expect_not_log "exec external/remotejdk11_.*/bin/java"
+ expect_log "exec external/remotejdk15_.*/bin/java"
}
+function test_host_javabase() {
+ cat << EOF >> WORKSPACE
+load("@bazel_tools//tools/jdk:local_java_repository.bzl", "local_java_repository")
+local_java_repository(
+ name = "host_javabase",
+ java_home = "$PWD/foobar",
+ version = "11",
+)
+EOF
+ mkdir -p java
+ cat >> java/rule.bzl <<EOF
+def _sample_rule_impl(ctx):
+ return []
+
+sample_rule = rule(
+ implementation = _sample_rule_impl,
+ attrs = {
+ "dep": attr.label(cfg = 'exec'),
+ },
+)
+EOF
+
+ cat << EOF > java/BUILD
+load(":rule.bzl", "sample_rule")
+
+java_library(
+ name = "javalib",
+ srcs = ["HelloWorld.java"],
+)
+sample_rule(
+ name = 'sample',
+ dep = ':javalib',
+)
+EOF
+ touch java/HelloWorld.java
+
+ mkdir -p foobar/bin
+ touch foobar/bin/java
+
+ # We expect the given host_javabase does not appear in the command line of
+ # java_library actions.
+ bazel aquery --output=text --host_javabase=@host_javabase//:jdk --tool_java_runtime_version='host_javabase' 'deps(//java:sample,1)' >& $TEST_log
+ expect_log "exec external/remotejdk11_.*/bin/java"
+ expect_not_log "exec external/host_javabase/bin/java"
+
+ # If we don't specify anything, we expect the embedded JDK to be used.
+ # Note that this will change in the future but is the current state.
+ bazel aquery --output=text 'deps(//java:sample,1)' >& $TEST_log
+ expect_not_log "exec external/embedded_jdk/bin/java"
+ expect_log "exec external/remotejdk11_.*/bin/java"
+
+ bazel aquery --output=text --host_javabase=@host_javabase//:jdk --tool_java_runtime_version='host_javabase' \
+ 'deps(//java:sample,1)' >& $TEST_log
+ expect_log "exec external/remotejdk11_.*/bin/java"
+ expect_not_log "exec external/host_javabase/bin/java"
+
+
+ bazel aquery --output=text \
+ 'deps(//java:sample,1)' >& $TEST_log
+ expect_log "exec external/remotejdk11_.*/bin/java"
+}
+
+
+
function test_javabase() {
cat << EOF >> WORKSPACE
load("@bazel_tools//tools/jdk:local_java_repository.bzl", "local_java_repository")
diff --git a/tools/jdk/BUILD.tools b/tools/jdk/BUILD.tools
index e0ccf4f..b1fc627 100644
--- a/tools/jdk/BUILD.tools
+++ b/tools/jdk/BUILD.tools
@@ -13,6 +13,7 @@
"//tools/jdk:java_toolchain_alias.bzl",
"java_host_runtime_alias",
"java_runtime_alias",
+ "java_runtime_version_alias",
"java_toolchain_alias",
"legacy_java_runtime_alias",
"legacy_java_toolchain_alias",
@@ -377,6 +378,7 @@
default_java_toolchain(
name = "toolchain_jdk_14",
configuration = dict(),
+ java_runtime = "@bazel_tools//tools/jdk:remotejdk_14",
source_version = "14",
target_version = "14",
)
@@ -385,6 +387,7 @@
default_java_toolchain(
name = "toolchain_jdk_15",
configuration = dict(),
+ java_runtime = "@bazel_tools//tools/jdk:remotejdk_15",
source_version = "15",
target_version = "15",
)
@@ -420,9 +423,10 @@
)
# A JDK 11 for use as a --host_javabase.
-alias(
+java_runtime_version_alias(
name = "remote_jdk11",
- actual = select(
+ runtime_version = "remotejdk_11",
+ selected_java_runtime = select(
{
"//src/conditions:darwin": "@remotejdk11_macos//:jdk",
"//src/conditions:windows": "@remotejdk11_win//:jdk",
@@ -436,3 +440,33 @@
),
visibility = ["//visibility:public"],
)
+
+java_runtime_version_alias(
+ name = "remotejdk_14",
+ runtime_version = "remotejdk_14",
+ selected_java_runtime = select(
+ {
+ "//src/conditions:darwin": "@remotejdk14_macos//:jdk",
+ "//src/conditions:windows": "@remotejdk14_win//:jdk",
+ "//src/conditions:linux_x86_64": "@remotejdk14_linux//:jdk",
+ },
+ no_match_error = "Could not find a JDK for host execution environment, please explicitly" +
+ " provide one using `--host_javabase.`",
+ ),
+ visibility = ["//visibility:public"],
+)
+
+java_runtime_version_alias(
+ name = "remotejdk_15",
+ runtime_version = "remotejdk_15",
+ selected_java_runtime = select(
+ {
+ "//src/conditions:darwin": "@remotejdk15_macos//:jdk",
+ "//src/conditions:windows": "@remotejdk15_win//:jdk",
+ "//src/conditions:linux_x86_64": "@remotejdk15_linux//:jdk",
+ },
+ no_match_error = "Could not find a JDK for host execution environment, please explicitly" +
+ " provide one using `--host_javabase.`",
+ ),
+ visibility = ["//visibility:public"],
+)
diff --git a/tools/jdk/default_java_toolchain.bzl b/tools/jdk/default_java_toolchain.bzl
index f98adef..f71f794 100644
--- a/tools/jdk/default_java_toolchain.bzl
+++ b/tools/jdk/default_java_toolchain.bzl
@@ -71,6 +71,7 @@
bootclasspath = ["@bazel_tools//tools/jdk:platformclasspath"],
source_version = "8",
target_version = "8",
+ java_runtime = "@bazel_tools//tools/jdk:remote_jdk11",
)
JVM8_TOOLCHAIN_CONFIGURATION = dict(
diff --git a/tools/jdk/java_toolchain_alias.bzl b/tools/jdk/java_toolchain_alias.bzl
index 4647666..b7a6126 100644
--- a/tools/jdk/java_toolchain_alias.bzl
+++ b/tools/jdk/java_toolchain_alias.bzl
@@ -72,6 +72,48 @@
},
)
+def _java_runtime_version_alias(ctx):
+ """An alias fixing a specific version of java_runtime."""
+ if java_common.is_java_toolchain_resolution_enabled_do_not_use(ctx = ctx):
+ toolchain = ctx.toolchains["@bazel_tools//tools/jdk:runtime_toolchain_type"]
+ else:
+ toolchain = ctx.attr.selected_java_runtime[java_common.JavaRuntimeInfo]
+ return [
+ toolchain,
+ platform_common.TemplateVariableInfo({
+ "JAVA": str(toolchain.java_executable_exec_path),
+ "JAVABASE": str(toolchain.java_home),
+ }),
+ # See b/65239471 for related discussion of handling toolchain runfiles/data.
+ DefaultInfo(
+ runfiles = ctx.runfiles(transitive_files = toolchain.files),
+ files = toolchain.files,
+ ),
+ ]
+
+def _java_runtime_transition_impl(settings, attr):
+ return {"//command_line_option:java_runtime_version": attr.runtime_version}
+
+_java_runtime_transition = transition(
+ implementation = _java_runtime_transition_impl,
+ inputs = [],
+ outputs = ["//command_line_option:java_runtime_version"],
+)
+
+java_runtime_version_alias = rule(
+ implementation = _java_runtime_version_alias,
+ toolchains = ["@bazel_tools//tools/jdk:runtime_toolchain_type"],
+ attrs = {
+ "runtime_version": attr.string(mandatory = True),
+ # TODO(ilist): remove after java toolchain resolution flag is flipped
+ "selected_java_runtime": attr.label(mandatory = True),
+ "_allowlist_function_transition": attr.label(
+ default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
+ ),
+ },
+ cfg = _java_runtime_transition,
+)
+
def _java_toolchain_alias(ctx):
"""An experimental implementation of java_toolchain_alias using toolchain resolution."""
if java_common.is_java_toolchain_resolution_enabled_do_not_use(ctx = ctx):