bazel: incompatible_use_toolchain_resolution_for_java_rules: use toolchain resolution for Java rules

Flag: --incompatible_use_toolchain_resolution_for_java_rules Available since: 5.0.0 Will be flipped in: 5.0.0 Tracking issue: #4592

Motivation

Currently, Java rules find their Java toolchain and JDK using the --javabase / --java_toolchain / --host_javabase / --host_java_toolchain command line options. This will be changed to use platform-based toolchain resolution so as to be consistent with the rest of Bazel and to support multiple platforms more easily.

Migration notes

For --javabase with old values:

  • @local_jdk://jdk
  • @remotejdk11_{linux,window,darwin}_{cpu}//:jdk
  • @remotejdk14_{linux,window,darwin}//:jdk
  • @remotejdk15_{linux,window,darwin}.*//:jdk

Replace the flag with --java_runtime_version={local_jdk,remotejdk_14,remotejdk_15}.

For --java_toolchain with old values:

  • @bazel_tools//tools/jdk:toolchain,
  • @bazel_tools_hostjdk8,
  • @bazel_tools//jdk:legacy_toolchain,
  • @bazel_tools//tools/jdk:remote_toolchain,
  • @bazel_tools//tools/jdk:toolchain_java_{ver},
  • @remote_java_tools_xxx//:toolchain,
  • @remote_java_tools_xxx//:toolchain_jdk_11,
  • @remote_java_tools_xxx//:toolchain_jdk_14,
  • @remote_java_tools_xxx//:toolchain_jdk_15

Replace the flag with --java_language_version={8,...,15}

Migration of more advanced cases

For --javabase=@bazel_tools//tools/jdk:​absolute_javabase, use local_java_repositoy in the WORKSPACE file.

For custom --javabase labels, do the following:

  1. replace http_archive with remote_java_repository:
remote_java_repository(
   name = ...
   sha256 = ...
   strip_prefix = ...
   urls = ...
   prefix = "myjdk",
   version = "11",
   exec_compatible_with = ["@platforms//cpu:arm", "@platforms//os:linux"]
)
  1. replace the old flag with --java_runtime_version with the specified version or prefix_version value (for example --java_runtime_version=myjdk_11).

For old --java_toolchain values:

  • @bazel_tools//tools/jdk:toolchain_vanilla
  • @remote_java_tools_xxx//:prebuilt_toolchain
  • custom label
  1. add custom toolchain definition to a BUILD file (or replace custom target):
default_java_toolchain(
  name = "mytoolchain",
  configuration = "PREBUILT_TOOLCHAIN_CONFIGURATION"
     #or "VANILLA_TOOLCHAIN_CONFIGURATION"
  ...
)
  1. register custom toolchain in the WORKSPACE or use configuration flag --extra_toolchains.

RBE migration

  1. Update the version of bazel_toolchains.
  2. Add following flags to .bazelrc affecting remote configuration:
build:remote --java_runtime_version=rbe_jdk     # Uses JDK installed on docker, configured by bazel_toolchains
build:remote --tool_java_runtime_version=rbe_jdk
build:remote --extra_toolchains=@rbe_ubuntu1804//java:all   # Optional: uses JDK installed on docker to compile 
  1. In case the sources are not Java 8, also add:
build --java_language_version=11
build --tool_java_language_version=11
  1. Once Bazel 4.1.0 is released and used on RBE Remove --{,host}javabase and --{,host}_javatoolchain flags.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 1
  • Comments: 34 (27 by maintainers)

Commits related to this issue

Most upvoted comments

What is the status of this? It is really confusing right now, because docs seem to indicate we can use Java toolchains but since the PR is not merged this does not work. I would love to be able to use toolchains with Java rules!

This breaks for me when I upgraded one of my repositories and none of the fixes here worked.

Someone else has a reproducible example here which breaks for bazel coverage: https://github.com/bazelbuild/bazel/issues/15035

We were able to make it work starting from Bazel 5.0.0. See this pending CL: [1].

[1] https://gerrit-review.googlesource.com/c/gerrit/+/291864

Could someone add the label breaking-change-5.0? It would be slightly easier to find when searching for all Bazel 5.0 breaking changes

Done.

@comius

On Bazel@HEAD (32fc451600b6e94a015263eb1c8a63e974f6f4cc), after flipping of: --incompatible_use_toolchain_resolution_for_java_rules all toolchain parameters don’t seem to have any effect. IOW, if I am using (on Gerrit project):

  $ bazel build \
  --java_toolchain=@bazel_tools//tools/jdk:toolchain_jdk_15 \
  --host_java_toolchain=@bazel_tools//tools/jdk:toolchain_jdk_15 \
  --javabase=@bazel_tools//tools/jdk:remotejdk_15 \
  --host_javabase=@bazel_tools//tools/jdk:remotejdk_15 \
  java/com/google/gerrit/common:server
Starting local Bazel server and connecting to it...
WARNING: Option 'java_toolchain' is deprecated
WARNING: Option 'host_java_toolchain' is deprecated
WARNING: Option 'javabase' is deprecated
WARNING: Option 'host_javabase' is deprecated
INFO: Invocation ID: dd6a4236-2ba0-49b2-8595-9ab4b043d6f7
DEBUG: /home/dos/.cache/bazel/_bazel_dos/f1d575400f8c6aeef34fcf7819876747/external/bazel_toolchains/rules/rbe_repo/version_check.bzl:59:14: 
Current running Bazel is not a release version and one was not defined explicitly in rbe_autoconfig target. Falling back to '3.1.0'
INFO: Analyzed target //java/com/google/gerrit/common:server (81 packages loaded, 3388 targets configured).
INFO: Found 1 target...
Target //java/com/google/gerrit/common:server up-to-date:
  bazel-bin/java/com/google/gerrit/common/libserver.jar
INFO: Elapsed time: 17.393s, Critical Path: 0.75s
INFO: 1 process: 1 internal.
INFO: Build completed successfully, 1 total action

Then it works, but it doesn’t produce Java major byte version 59:

  $ javap -v -cp bazel-bin/java/com/google/gerrit/common/libserver.jar \
  com.google.gerrit.common.data.Capable | grep major
  major version: 52

To make it work again, I have to explicitly un-flip: --incompatible_use_toolchain_resolution_for_java_rules=false, only then it works as expected:

  $ javap -v -cp bazel-bin/java/com/google/gerrit/common/libserver.jar \
  com.google.gerrit.common.data.Capable | grep major
  major version: 59

I would rather expect that toolchain options are not silently ignored, but rather rejected, as usually, right?