diff options
author | David Ostrovsky <david@ostrovsky.org> | 2018-08-23 08:25:24 +0200 |
---|---|---|
committer | David Ostrovsky <david.ostrovsky@gmail.com> | 2018-09-25 07:31:33 +0000 |
commit | f55b69f5c95df676f38d286cf3772939007892a9 (patch) | |
tree | a8389c67024282f44182355b7d74d4330296551d | |
parent | 51cb2ea2ff2f78105bcc9b633b7526535083578b (diff) |
Bazel: Add support for Java 10
Bazel@HEAD doesn't support Java 10 any more. The tool chain is extended
to support building with Java 10 using host_javabase option and vanilla
java builder. To use --host_javabase option we have to provide absolute
path to the JDK 10. To keep that non-portable part out of the build file
we use variable that is substitued during build invocation. Say, the
location of the JDK 10 is: /usr/lib64/jvm/java-10, then the build is
invoked with:
$ bazel build --host_javabase=:absolute_javabase \
--define=ABSOLUTE_JAVABASE=/usr/lib64/jvm/java-10 ...
Given that absolute_javabase rule is not a part of released Bazel yet,
but will be only included in future Bazel releases, we have to add it in
our own build file:
java_runtime(
name = "absolute_javabase",
java_home = "$(ABSOLUTE_JAVABASE)",
visibility = ["//visibility:public"],
)
While this works, it fails the Gerrit-CI, because recently it was
changed to exercise //... rule, and cannot resolve ABSOLUTE_JAVABASE
variable, because it wasn't provided in the CI environment. CI is still
using Java 8.
One approach to address that problem would be to use "manual" tag for a
rule that would exclude it from generic targets like //..., but
unfortunately, java_runtime rule doesn't expose tag attribute.
The next workaround is to hide that variable behind a select statement.
This is a harmless hack:
config_setting(
name = "use_absolute_javabase",
values = {"define": "USE_ABSOLUTE_JAVABASE=true"},
)
java_runtime(
name = "absolute_javabase",
java_home = select({
":use_absolute_javabase": "$(ABSOLUTE_JAVABASE)",
"//conditions:default": "",
}),
visibility = ["//visibility:public"],
)
Now from the CI the rule: //:absolute_javabase would produce non working
java_runtime, because java_home wasn't specified, but given that this
java_runtime is not used during the build, it doesn't matter. Add also
a TODO comment to replace that interim solution when absolute_javabase
is supported in released Bazel version. As the consequence for hiding
that rule behind a condition, we need to provide additional variable so
that Bazel can correctly resolve java_home in java_runtime rule:
$ bazel build --host_javabase=:absolute_javabase \
--define=ABSOLUTE_JAVABASE=/usr/lib64/jvm/java-10 \
--define=USE_ABSOLUTE_JAVABASE=true [...]
Also extend tools/eclipse/project.py to accept Java 10 specific options.
There is already --java <jdk number> option that was added recently to
support Eclipse .classpath generation when JDK 9 is used, but this can
not be used, because for Java 10 we have to provide absolute path to the
Java 10 location. Add new option --edge_java where all Java 10 specific
options can be passed:
$ tools/eclipse/project.py --edge_java \
"--host_javabase=:absolute_javabase \
--define=ABSOLUTE_JAVABASE=/usr/lib64/jvm/java-10 \
--define=USE_ABSOLUTE_JAVABASE=true \
--host_java_toolchain=//:toolchain_vanilla \
--java_toolchain=//:toolchain_vanilla"
Alternative approach would be to add those options to Bazel resource
file.
Test Plan:
$ bazel build --host_javabase=:absolute_javabase \
--define=ABSOLUTE_JAVABASE=/usr/lib64/jvm/java-10 \
--define=USE_ABSOLUTE_JAVABASE=true \
--host_java_toolchain=//:toolchain_vanilla \
--java_toolchain=//:toolchain_vanilla \
:release
and replace ABSOLUTE_JAVABASE variable with the location of JDK 10.
To verify that major version of generated classes is 54, use:
$ $JAVA_HOME/bin/javap -verbose \
-cp bazel-bin/java/com/google/gerrit/common/libserver.jar \
com.google.gerrit.common.data.ProjectAccess | grep "major version"
54
[1] https://github.com/bazelbuild/bazel/issues/6012
Change-Id: I5e652f7a19afbcf3607febd9a7a165dc07918bd0
-rw-r--r-- | BUILD | 41 | ||||
-rw-r--r-- | Documentation/dev-bazel.txt | 26 | ||||
-rw-r--r-- | tools/bzl/junit.bzl | 17 | ||||
-rwxr-xr-x | tools/eclipse/project.py | 12 |
4 files changed, 86 insertions, 10 deletions
@@ -2,6 +2,10 @@ package(default_visibility = ["//visibility:public"]) load("//tools/bzl:genrule2.bzl", "genrule2") load("//tools/bzl:pkg_war.bzl", "pkg_war") +load( + "@bazel_tools//tools/jdk:default_java_toolchain.bzl", + "default_java_toolchain", +) config_setting( name = "java9", @@ -10,6 +14,43 @@ config_setting( }, ) +config_setting( + name = "java10", + values = { + "java_toolchain": ":toolchain_vanilla", + }, +) + +# TODO(davido): Switch to consuming it from @bazel_tool//tools/jdk:absolute_javabase +# when new Bazel version is released with this change included: +# https://github.com/bazelbuild/bazel/issues/6012 +# https://github.com/bazelbuild/bazel/commit/0173bdbf7bdd1874379d4dd3eb70d5321e0f1816 +# As the interim use a hack that works around it by putting the variable reference +# behind a select +config_setting( + name = "use_absolute_javabase", + values = {"define": "USE_ABSOLUTE_JAVABASE=true"}, +) + +java_runtime( + name = "absolute_javabase", + java_home = select({ + ":use_absolute_javabase": "$(ABSOLUTE_JAVABASE)", + "//conditions:default": "", + }), + visibility = ["//visibility:public"], +) + +# TODO(davido): Switch to consuming it from @bazel_tool//tools/jdk:toolchain_vanilla +# when my change is included in released Bazel version: +# https://github.com/bazelbuild/bazel/commit/0bef68e054eccecd690e5d9f46db8a0c4b2d887a +default_java_toolchain( + name = "toolchain_vanilla", + forcibly_disable_header_compilation = True, + javabuilder = ["@bazel_tools//tools/jdk:VanillaJavaBuilder_deploy.jar"], + jvm_opts = [], +) + genrule( name = "gen_version", outs = ["version.txt"], diff --git a/Documentation/dev-bazel.txt b/Documentation/dev-bazel.txt index 6331581fc7..0ecc82075c 100644 --- a/Documentation/dev-bazel.txt +++ b/Documentation/dev-bazel.txt @@ -6,7 +6,7 @@ To build Gerrit from source, you need: * A Linux or macOS system (Windows is not supported at this time) -* A JDK for Java 8 +* A JDK for Java 8|9|10 * Python 2 or 3 * Node.js * link:https://www.bazel.io/versions/master/docs/install.html[Bazel] @@ -14,6 +14,30 @@ To build Gerrit from source, you need: * zip, unzip * gcc +[[Java 10 support]] +Java 10 is supported through vanilla java toolchain +link:https://docs.bazel.build/versions/master/toolchains.html[Bazel option]. +To build Gerrit with Java 10, specify vanilla java toolchain and provide +path to Java 10 home: + +``` + $ bazel build --host_javabase=:absolute_javabase \ + --define=ABSOLUTE_JAVABASE=<path-to-java-10> \ + --define=USE_ABSOLUTE_JAVABASE=true \ + --host_java_toolchain=//:toolchain_vanilla \ + --java_toolchain=//:toolchain_vanilla \ + :release +``` + +Note that the following options must be added to `container.javaOptions` +in `$gerrit_site/etc/gerrit.config` to run Gerrit with Java 10: + +``` +[container] + javaOptions = --add-modules java.activation + javaOptions = --add-opens=jdk.management/com.sun.management.internal=ALL-UNNAMED +``` + [[Java 9 support]] Java 9 is supported through alternative java toolchain link:https://docs.bazel.build/versions/master/toolchains.html[Bazel option]. diff --git a/tools/bzl/junit.bzl b/tools/bzl/junit.bzl index d711356b40..08d50457f9 100644 --- a/tools/bzl/junit.bzl +++ b/tools/bzl/junit.bzl @@ -64,6 +64,14 @@ _GenSuite = rule( implementation = _impl, ) +POST_JDK8_OPTS = [ + # Enforce JDK 8 compatibility on Java 9, see + # https://docs.oracle.com/javase/9/intl/internationalization-enhancements-jdk-9.htm#JSINT-GUID-AF5AECA7-07C1-4E7D-BC10-BC7E73DC6C7F + "-Djava.locale.providers=COMPAT,CLDR,SPI", + "--add-modules java.activation", + "--add-opens=jdk.management/com.sun.management.internal=ALL-UNNAMED", +] + def junit_tests(name, srcs, **kwargs): s_name = name + "TestSuite" _GenSuite( @@ -73,13 +81,8 @@ def junit_tests(name, srcs, **kwargs): ) jvm_flags = kwargs.get("jvm_flags", []) jvm_flags = jvm_flags + select({ - "//:java9": [ - # Enforce JDK 8 compatibility on Java 9, see - # https://docs.oracle.com/javase/9/intl/internationalization-enhancements-jdk-9.htm#JSINT-GUID-AF5AECA7-07C1-4E7D-BC10-BC7E73DC6C7F - "-Djava.locale.providers=COMPAT,CLDR,SPI", - "--add-modules java.activation", - "--add-opens=jdk.management/com.sun.management.internal=ALL-UNNAMED", - ], + "//:java9": POST_JDK8_OPTS, + "//:java10": POST_JDK8_OPTS, "//conditions:default": [], }) native.java_test( diff --git a/tools/eclipse/project.py b/tools/eclipse/project.py index 64d837a2b4..e515a3a27c 100755 --- a/tools/eclipse/project.py +++ b/tools/eclipse/project.py @@ -53,21 +53,29 @@ opts.add_option('--name', help='name of the generated project', opts.add_option('-b', '--batch', action='store_true', dest='batch', help='Bazel batch option') opts.add_option('-j', '--java', action='store', - dest='java', help='Post Java 8 support (9|10|11|...)') + dest='java', help='Post Java 8 support (9)') +opts.add_option('-e', '--edge_java', action='store', + dest='edge_java', help='Post Java 9 support (10|11|...)') args, _ = opts.parse_args() batch_option = '--batch' if args.batch else None custom_java = args.java +edge_java = args.edge_java def _build_bazel_cmd(*args): + build = False cmd = ['bazel'] if batch_option: cmd.append('--batch') for arg in args: + if arg == "build": + build = True cmd.append(arg) - if custom_java: + if custom_java and not edge_java: cmd.append('--host_java_toolchain=@bazel_tools//tools/jdk:toolchain_java%s' % custom_java) cmd.append('--java_toolchain=@bazel_tools//tools/jdk:toolchain_java%s' % custom_java) + if edge_java and build: + cmd.append(edge_java) return cmd |