Allow per-target Java runtime selection for java_binary/java_test #22866
Labels
team-Configurability
Issues for Configurability team
team-Rules-Java
Issues for Java rules
type: feature request
untriaged
Description of the feature request:
java_binary
andjava_test
currently use toolchain resolution to discover the Java runtime toolchain to use, based on the value of--java_runtime_version=
(and--tool_java_runtime_version=
) command-line options (aside from platform matching). However, toolchain resolution is rather cumbersome if we want to use different Java runtime toolchains for different targets.Going further, we often want two distinct
java_binary
targets to share many of the samejava_library
dependencies. Sincejava_runtime_version
is part of the configuration, naïvely setting differentjava_runtime_version
s on the twojava_binary
s with a transition will often result in sharedjava_library
s being compiled twice, in two different configurations' output directories.It would be great if users are allowed to optionally specify which Java runtime to use through an attribute, tentatively named
java_runtime
, onjava_binary
/java_test
. If this attribute is not specified, those rules can fall back to the current toolchain resolution logic.Note: This feature request does not concern compile-time Java versions.
Which category does this issue belong to?
Configurability, Java Rules
What underlying problem are you trying to solve with this feature?
We have a large heterogeneous JVM monorepo that support both backend services and data jobs. Some targets (e.g., backend services) would like to run on a newer Java runtime, while the Java runtime version for data jobs are often constrained by the open-source framework we use. (E.g., Apache Flink does not yet support JDK 21.)
To our knowledge, there are three existing ways to change runtime JDK on a per-target basis. But they all leave something to be desired.
java_runtime_version
for the different binaries.java_binary
, being a built-in rule, does not allow setting incoming-edge transitions; (b) if webazel build
two binaries with different runtime JDKs at the same time, libraries shared by binaries will get compiled twice.deps
to revert thejava_runtime_version
back to the "default" version. But that brings more complexity, and doesn't solve all the problems. (E.g., Bazel's output directory computation uses the top-level target's configuration as the "default" configuration. If this "default configuration" can change for different targets, then developers will see spurious rebuilds.)launcher
attribute of thejava_binary
to call a JDK other than the one Bazel thinks it should use. This requires us to write some C++ code (sincelauncher
must be acc_binary
), doesn't allow sharing action cache keys between different architectures, and overall feels like a hack._stub_template
private attribute onjava_binary
to use a script that looks for another JDK to call into. This relies on Bazel implementation details, and is even more of a hack.Which operating system are you running Bazel on?
macOS
What is the output of
bazel info release
?7.1.2
If
bazel info release
returnsdevelopment version
or(@non-git)
, tell us how you built Bazel.No response
What's the output of
git remote get-url origin; git rev-parse HEAD
?No response
Have you found anything relevant by searching the web?
There are two instances of prior art:
java_toolchain
has long supported ajava_runtime
attribute to define which runtime to use when compiling Java code.rules_scala added a way to select runtime Java version on a per-target basis back in 2022: Allow per-target java runtime selection for scala_junit_tests rules_scala#1373
Their implementation allows something like this:
I'm proposing exactly this
runtime_jdk
attribute, forjava_binary
orjava_test
.Any other information, logs, or outputs that you want to share?
No response
The text was updated successfully, but these errors were encountered: