Reputation: 67
I want to use a specific Azul Zulu JDK for my Java builds. Therefore I have stored it in my repository locally e.g. under tools/zulu19.30.11-ca-jdk19.0.1-macosx_x64
. Now I want to configure a java toolchain target such that I can pass it via --java_toolchain=//tools:my_custom_java_toolchain
. I don't want to depend on some remote repositories.
What are the required steps to achieve this?
I have found this repository: https://github.com/salesforce/bazel-jdt-java-toolchain/blob/main/jdt/defs.bzl which defines a target of type default_java_toolchain
but I can not derive something useful for my use case. I don't know e.g. what the field header_compiler
means. My naive assumption is that I just have to pass some paths to the required tools (such as bin/javac
) for java compilation.
My current approach uses the rules java_toolchain
and java_runtime
. My BUILD file looks like this:
java_runtime(
name = "zulu19.30.11-ca-jdk19.0.1-macosx_x64",
srcs = glob(["zulu19.30.11-ca-jdk19.0.1-macosx_x64/**"]),
java_home = "zulu19.30.11-ca-jdk19.0.1-macosx_x64",
)
java_toolchain(
name = "zulu-19",
source_version = "19",
target_version = "19",
java_runtime = ":zulu19.30.11-ca-jdk19.0.1-macosx_x64",
javabuilder = "",
ijar = "",
singlejar = "",
genclass = "",
)
I am trying to execute the command: bazel build --extra_toolchains="//tools:zulu-19" //:ProjectRunner
and it complains about the missing mandatory attributes javabuilder
, ijar
, singlejar
and genclass
but I have no idea which are the correct paths or values.
I'm just wondering how bazel knows how to compile the java code with these few information. Why I don't have to specify javac
for example?
Upvotes: 2
Views: 1733
Reputation: 67
Basically I came up with the following solution which seems to solve my problem and is inspired by the rule default_java_toolchain
. I used the existing targets for javabuilder
, ijar
, singlejar
and genclass
which are defined in @bazel_tools//tools/jdk
. Note that I had to use BASE_JDK9_JVM_OPTS
for a successful build.
load("@bazel_tools//tools/jdk:default_java_toolchain.bzl", "BASE_JDK9_JVM_OPTS")
java_runtime(
name = "zulu19.30.11-ca-jdk19.0.1-macosx_x64",
srcs = glob(["zulu19.30.11-ca-jdk19.0.1-macosx_x64/**"]),
java_home = "zulu19.30.11-ca-jdk19.0.1-macosx_x64",
)
config_setting(
name = "zulu-19-runtime_version_setting",
values = {"java_runtime_version": "19"},
visibility = ["//visibility:private"],
)
toolchain(
name = "zulu-19_runtime_toolchain_definition",
target_settings = ["zulu-19-runtime_version_setting"],
toolchain_type = "@bazel_tools//tools/jdk:runtime_toolchain_type",
toolchain = "zulu19.30.11-ca-jdk19.0.1-macosx_x64",
)
java_toolchain(
name = "zulu-19",
source_version = "19",
target_version = "19",
java_runtime = ":zulu19.30.11-ca-jdk19.0.1-macosx_x64",
jvm_opts = BASE_JDK9_JVM_OPTS,
javabuilder = ["@bazel_tools//tools/jdk:javabuilder"],
ijar = ["@bazel_tools//tools/jdk:ijar"],
singlejar = ["@bazel_tools//tools/jdk:singlejar"],
genclass = ["@bazel_tools//tools/jdk:genclass"],
)
config_setting(
name = "zulu-19_version_setting",
values = {"java_language_version": "19"},
visibility = ["//visibility:private"],
)
toolchain(
name = "zulu-19_toolchain_definition",
toolchain_type = "@bazel_tools//tools/jdk:toolchain_type",
target_settings = ["zulu-19_version_setting"],
toolchain = "zulu-19",
)
The following command now successfully runs without any errors. System.out.println(Runtime.version());
also prints the correct version.
bazel run --extra_toolchains="//tools:zulu-19_toolchain_definition,//tools:zulu-19_runtime_toolchain_definition" --java_language_version="19" --java_runtime_version="19" //:ProjectRunner
But I still have a couple of questions, e.g. why javabuilder
, ijar
, singlejar
and genclass
are needed and what is the purpose of those targets? How does the toolchain target know about my javac
binary for compiling the java code? Why do I have to use BASE_JDK9_JVM_OPTS
for a successful build and can I omit some settings?
Upvotes: 1