Fix #7304: Validate that JAVA_HOME points to a JDK.
If JAVA_HOME is not valid, fallback to the detection by looking up the
`javac` binary.
This also fixes an issue where Bazel would try to look up the boot classpath
for JDK 8 in the wrong folder: By convention, OpenJDK 8 has a directory
structure, where the JRE is in a subdirectory of the JDK:
/usr/lib/jvm/java-8-openjdk-amd64 <- JDK
/usr/lib/jvm/java-8-openjdk-amd64/jre <- JRE
This changed with OpenJDK 9 and newer and there is no longer a `jre`
folder for these versions (and newer Java versions are not supplied as a
separate "JRE" version anymore, there is only a "JDK").
On some platforms (e.g. Debian) the JAVA_HOME of an installed OpenJDK 8
might point to the JRE instead of the JDK, which triggers a bug in the
boot classpath detection logic in Bazel's DumpPlatformClassPath tool:
The tool relies on the directory structure as mentioned above to
determine whether it is looking at a OpenJDK 8 or OpenJDK >= 9. If
certain well-known files (e.g. "jre/lib/rt.jar") of OpenJDK 8 don't
exist, it assumes that it's looking at an OpenJDK 9+ - unfortunately
this is also the case when you're looking at something that's not a JDK
at all or the `jre` subfolder of an OpenJDK 8.
This triggers an InvalidArgumentException in the Javac code.
By making sure that we only ever pass a valid JDK path to that tool, the
problem can no longer happen.
RELNOTES: Bazel now validates that JAVA_HOME points to a valid JDK and
falls back to auto-detection by looking up the path of `javac`.
Closes #7324.
PiperOrigin-RevId: 232197212
diff --git a/src/main/cpp/blaze_util_darwin.cc b/src/main/cpp/blaze_util_darwin.cc
index 456e851..d20169c 100644
--- a/src/main/cpp/blaze_util_darwin.cc
+++ b/src/main/cpp/blaze_util_darwin.cc
@@ -36,6 +36,7 @@
#include "src/main/cpp/util/exit_code.h"
#include "src/main/cpp/util/file.h"
#include "src/main/cpp/util/logging.h"
+#include "src/main/cpp/util/path.h"
#include "src/main/cpp/util/strings.h"
namespace blaze {
@@ -162,7 +163,12 @@
string GetSystemJavabase() {
string java_home = GetEnv("JAVA_HOME");
if (!java_home.empty()) {
- return java_home;
+ string javac = blaze_util::JoinPath(java_home, "bin/javac");
+ if (access(javac.c_str(), X_OK) == 0) {
+ return java_home;
+ }
+ BAZEL_LOG(WARNING)
+ << "Ignoring JAVA_HOME, because it must point to a JDK, not a JRE.";
}
// java_home will print a warning if no JDK could be found
diff --git a/src/main/cpp/blaze_util_freebsd.cc b/src/main/cpp/blaze_util_freebsd.cc
index ed7ec49..b972168 100644
--- a/src/main/cpp/blaze_util_freebsd.cc
+++ b/src/main/cpp/blaze_util_freebsd.cc
@@ -141,7 +141,17 @@
string GetSystemJavabase() {
// if JAVA_HOME is defined, then use it as default.
string javahome = GetEnv("JAVA_HOME");
- return !javahome.empty() ? javahome : "/usr/local/openjdk8";
+
+ if (!javahome.empty()) {
+ string javac = blaze_util::JoinPath(javahome, "bin/javac");
+ if (access(javac.c_str(), X_OK) == 0) {
+ return javahome;
+ }
+ BAZEL_LOG(WARNING)
+ << "Ignoring JAVA_HOME, because it must point to a JDK, not a JRE.";
+ }
+
+ return "/usr/local/openjdk8";
}
void WriteSystemSpecificProcessIdentifier(
diff --git a/src/main/cpp/blaze_util_linux.cc b/src/main/cpp/blaze_util_linux.cc
index cf1b0de..3801028 100644
--- a/src/main/cpp/blaze_util_linux.cc
+++ b/src/main/cpp/blaze_util_linux.cc
@@ -165,7 +165,12 @@
// if JAVA_HOME is defined, then use it as default.
string javahome = GetEnv("JAVA_HOME");
if (!javahome.empty()) {
- return javahome;
+ string javac = blaze_util::JoinPath(javahome, "bin/javac");
+ if (access(javac.c_str(), X_OK) == 0) {
+ return javahome;
+ }
+ BAZEL_LOG(WARNING)
+ << "Ignoring JAVA_HOME, because it must point to a JDK, not a JRE.";
}
// which javac
diff --git a/src/main/cpp/blaze_util_windows.cc b/src/main/cpp/blaze_util_windows.cc
index 038ad50..3d01b44 100644
--- a/src/main/cpp/blaze_util_windows.cc
+++ b/src/main/cpp/blaze_util_windows.cc
@@ -459,10 +459,16 @@
string GetSystemJavabase() {
string javahome(GetEnv("JAVA_HOME"));
- if (javahome.empty()) {
- return "";
+ if (!javahome.empty()) {
+ string javac = blaze_util::JoinPath(javahome, "bin/javac.exe");
+ if (blaze_util::PathExists(javac.c_str())) {
+ return javahome;
+ }
+ BAZEL_LOG(WARNING)
+ << "Ignoring JAVA_HOME, because it must point to a JDK, not a JRE.";
}
- return javahome;
+
+ return "";
}
namespace {