diff --git a/site/docs/user-manual.html b/site/docs/user-manual.html
index 20933c49f72d45..d98598de0fb425 100644
--- a/site/docs/user-manual.html
+++ b/site/docs/user-manual.html
@@ -2835,6 +2835,14 @@
--host_jvm_debug
subprocesses of Bazel: applications, tests, tools, etc.)
+--autodetect_server_javabase
+
+ This option causes Bazel to automatically search for an installed JDK on startup,
+ and to fall back to the installed JRE if the embedded JRE isn't available.
+ --explicit_server_javabase
can be used to pick an explicit JRE to
+ run bazel with.
+
+
--batch
diff --git a/src/main/cpp/blaze.cc b/src/main/cpp/blaze.cc
index f42a4f887aaf7a..a3fd334f24248d 100644
--- a/src/main/cpp/blaze.cc
+++ b/src/main/cpp/blaze.cc
@@ -457,7 +457,9 @@ static vector GetServerExeArgs(const blaze_util::Path &jvm_path,
startup_options.output_base.AsCommandLineArgument());
result.push_back("--workspace_directory=" +
blaze_util::ConvertPath(workspace));
- result.push_back("--default_system_javabase=" + GetSystemJavabase());
+ if (startup_options.autodetect_server_javabase) {
+ result.push_back("--default_system_javabase=" + GetSystemJavabase());
+ }
if (!startup_options.server_jvm_out.IsEmpty()) {
result.push_back("--server_jvm_out=" +
diff --git a/src/main/cpp/startup_options.cc b/src/main/cpp/startup_options.cc
index 5ee43bac80a98a..0190dccef33ea3 100644
--- a/src/main/cpp/startup_options.cc
+++ b/src/main/cpp/startup_options.cc
@@ -71,6 +71,7 @@ StartupOptions::StartupOptions(const string &product_name,
ignore_all_rc_files(false),
block_for_lock(true),
host_jvm_debug(false),
+ autodetect_server_javabase(true),
batch(false),
batch_cpu_scheduling(false),
io_nice_level(-1),
@@ -135,6 +136,8 @@ StartupOptions::StartupOptions(const string &product_name,
RegisterNullaryStartupFlag("fatal_event_bus_exceptions",
&fatal_event_bus_exceptions);
RegisterNullaryStartupFlag("host_jvm_debug", &host_jvm_debug);
+ RegisterNullaryStartupFlag("autodetect_server_javabase",
+ &autodetect_server_javabase);
RegisterNullaryStartupFlag("idle_server_tasks", &idle_server_tasks);
RegisterNullaryStartupFlag("incompatible_enable_execution_transition",
&incompatible_enable_execution_transition);
@@ -481,6 +484,10 @@ StartupOptions::GetServerJavabaseAndType() const {
// 2) Use a bundled JVM if we have one.
default_server_javabase_ = std::pair(
bundled_jre_path, JavabaseType::EMBEDDED);
+ } else if (!autodetect_server_javabase) {
+ BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
+ << "Could not find embedded or explicit server javabase, and "
+ "--noautodetect_server_javabase is set.";
} else {
// 3) Otherwise fall back to using the default system JVM.
blaze_util::Path system_javabase = GetSystemJavabase();
diff --git a/src/main/cpp/startup_options.h b/src/main/cpp/startup_options.h
index 41aac66a687093..dc78702ec0e7b4 100644
--- a/src/main/cpp/startup_options.h
+++ b/src/main/cpp/startup_options.h
@@ -165,6 +165,8 @@ class StartupOptions {
bool host_jvm_debug;
+ bool autodetect_server_javabase;
+
std::string host_jvm_profile;
std::vector host_jvm_args;
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BlazeServerStartupOptions.java b/src/main/java/com/google/devtools/build/lib/runtime/BlazeServerStartupOptions.java
index a9f976e6592052..390de3858e096c 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/BlazeServerStartupOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/BlazeServerStartupOptions.java
@@ -493,4 +493,14 @@ public String getTypeDescription() {
+ "extended attribute is checked on all source files and output files, meaning "
+ "that it causes a significant number of invocations of the getxattr() system call.")
public String unixDigestHashAttributeName;
+
+ @Option(
+ name = "autodetect_server_javabase",
+ defaultValue = "true", // NOTE: only for documentation, value never passed to the server.
+ documentationCategory = OptionDocumentationCategory.BAZEL_CLIENT_OPTIONS,
+ effectTags = {OptionEffectTag.AFFECTS_OUTPUTS, OptionEffectTag.LOSES_INCREMENTAL_STATE},
+ help =
+ "When --noautodetect_server_javabase is passed, Bazel does not fall back to the local "
+ + "JDK for running the bazel server and instead exits.")
+ public boolean autodetectServerJavabase;
}
diff --git a/src/test/cpp/bazel_startup_options_test.cc b/src/test/cpp/bazel_startup_options_test.cc
index 91f1c14a8a9ec1..742ddba87d1ae1 100644
--- a/src/test/cpp/bazel_startup_options_test.cc
+++ b/src/test/cpp/bazel_startup_options_test.cc
@@ -100,6 +100,7 @@ TEST_F(BazelStartupOptionsTest, ValidStartupFlags) {
ExpectValidNullaryOption(options, "fatal_event_bus_exceptions");
ExpectValidNullaryOption(options, "home_rc");
ExpectValidNullaryOption(options, "host_jvm_debug");
+ ExpectValidNullaryOption(options, "autodetect_server_javabase");
ExpectValidNullaryOption(options, "ignore_all_rc_files");
ExpectValidNullaryOption(options, "incompatible_enable_execution_transition");
ExpectValidNullaryOption(options, "master_bazelrc");
diff --git a/src/test/shell/BUILD b/src/test/shell/BUILD
index 5f6735ba01b863..c6b2693d4d0939 100644
--- a/src/test/shell/BUILD
+++ b/src/test/shell/BUILD
@@ -5,6 +5,7 @@ package(default_visibility = ["//visibility:private"])
exports_files([
"bin/bazel",
"bin/bazel_jdk_minimal",
+ "bin/bazel_nojdk",
"testenv.sh",
"integration_test_setup.sh",
"sandboxing_test_utils.sh",
diff --git a/src/test/shell/bin/bazel_nojdk b/src/test/shell/bin/bazel_nojdk
new file mode 100755
index 00000000000000..6db26634d57b3b
--- /dev/null
+++ b/src/test/shell/bin/bazel_nojdk
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# Copyright 2018 The Bazel Authors. All rights reserved.
+#
+# 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.
+#
+# Wrapper script to run bazel in the tests. Any change to this file will
+# affect all our integration tests.
+#
+exec $(rlocation io_bazel/src/bazel_nojdk) \
+ --bazelrc=$TEST_TMPDIR/bazelrc "$@"
diff --git a/src/test/shell/integration/BUILD b/src/test/shell/integration/BUILD
index 5bb5dbdf6729cf..7aea04a20340f6 100644
--- a/src/test/shell/integration/BUILD
+++ b/src/test/shell/integration/BUILD
@@ -26,6 +26,16 @@ filegroup(
],
)
+filegroup(
+ name = "test-deps-nojdk",
+ testonly = 1,
+ srcs = [
+ "//src:bazel-bin_nojdk",
+ "//src/test/shell:bin/bazel_nojdk",
+ "//src/test/shell/bazel:test-deps-wo-bazel",
+ ],
+)
+
sh_test(
name = "progress_reporting_test",
size = "large",
@@ -185,6 +195,18 @@ sh_test(
],
)
+sh_test(
+ name = "nojdk_startup_options_test",
+ size = "medium",
+ srcs = ["nojdk_startup_options_test.sh"],
+ data = [
+ ":test-deps-nojdk",
+ "@bazel_tools//tools/bash/runfiles",
+ ],
+ # Windows doesn't support sandboxing, which BAZEL_SUFFIX needs.
+ tags = ["no_windows"],
+)
+
sh_test(
name = "run_test",
size = "medium",
diff --git a/src/test/shell/integration/nojdk_startup_options_test.sh b/src/test/shell/integration/nojdk_startup_options_test.sh
new file mode 100755
index 00000000000000..3332d85865199f
--- /dev/null
+++ b/src/test/shell/integration/nojdk_startup_options_test.sh
@@ -0,0 +1,74 @@
+#!/bin/bash
+#
+# Copyright 2020 The Bazel Authors. All rights reserved.
+#
+# 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.
+#
+# Test of Bazel's startup option handling cof the nojdk version.
+
+# --- begin runfiles.bash initialization ---
+set -euo pipefail
+if [[ ! -d "${RUNFILES_DIR:-/dev/null}" && ! -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
+ if [[ -f "$0.runfiles_manifest" ]]; then
+ export RUNFILES_MANIFEST_FILE="$0.runfiles_manifest"
+ elif [[ -f "$0.runfiles/MANIFEST" ]]; then
+ export RUNFILES_MANIFEST_FILE="$0.runfiles/MANIFEST"
+ elif [[ -f "$0.runfiles/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
+ export RUNFILES_DIR="$0.runfiles"
+ fi
+fi
+if [[ -f "${RUNFILES_DIR:-/dev/null}/bazel_tools/tools/bash/runfiles/runfiles.bash" ]]; then
+ source "${RUNFILES_DIR}/bazel_tools/tools/bash/runfiles/runfiles.bash"
+elif [[ -f "${RUNFILES_MANIFEST_FILE:-/dev/null}" ]]; then
+ source "$(grep -m1 "^bazel_tools/tools/bash/runfiles/runfiles.bash " \
+ "$RUNFILES_MANIFEST_FILE" | cut -d ' ' -f 2-)"
+else
+ echo >&2 "ERROR: cannot find @bazel_tools//tools/bash/runfiles:runfiles.bash"
+ exit 1
+fi
+# --- end runfiles.bash initialization ---
+
+# We don't want to use the cached, extracted bazel. It will have a different
+# sha1 and fail the test. The 2 version commands below are cheap.
+unset TEST_INSTALL_BASE
+
+export BAZEL_SUFFIX="_nojdk"
+source "$(rlocation "io_bazel/src/test/shell/integration_test_setup.sh")" \
+ || { echo "integration_test_setup.sh not found!" >&2; exit 1; }
+
+case "$(uname -s | tr [:upper:] [:lower:])" in
+msys*|mingw*|cygwin*)
+ declare -r is_windows=true
+ ;;
+*)
+ declare -r is_windows=false
+ ;;
+esac
+
+if "$is_windows"; then
+ export MSYS_NO_PATHCONV=1
+ export MSYS2_ARG_CONV_EXCL="*"
+fi
+
+# Test that nojdk bazel works with --autodetect_server_javabase
+function test_autodetect_server_javabase() {
+ bazel --autodetect_server_javabase version &> $TEST_log || fail "Should pass"
+}
+
+# Test that nojdk bazel fails with --noautodetect_server_javabase
+function test_noautodetect_server_javabase() {
+ bazel --noautodetect_server_javabase version &> $TEST_log && fail "Should fail"
+ expect_log "FATAL: Could not find embedded or explicit server javabase, and --noautodetect_server_javabase is set."
+}
+
+run_suite "${PRODUCT_NAME} startup options test"
diff --git a/src/test/shell/integration/startup_options_test.sh b/src/test/shell/integration/startup_options_test.sh
index 71dd2fd7a3f500..63f1624866d41d 100755
--- a/src/test/shell/integration/startup_options_test.sh
+++ b/src/test/shell/integration/startup_options_test.sh
@@ -75,4 +75,11 @@ function test_command_args_are_not_parsed_as_startup_args() {
expect_not_log "Error: Unable to read .bazelrc file"
}
+# Test that normal bazel works with and without --autodetect_server_javabase
+# because it has an embedded JRE.
+function test_autodetect_server_javabase() {
+ bazel --autodetect_server_javabase version &> $TEST_log || fail "Should pass"
+ bazel --noautodetect_server_javabase version &> $TEST_log || fail "Should pass"
+}
+
run_suite "${PRODUCT_NAME} startup options test"