With the default java language versions, the var
keyword causes errors, but specifying version 11 results in references to com.sun.tools.javac.*
causing errors.
See the Minimal Example
Versions of things:
Background: I've recently migrated to bzlmod
and got the basics working with a local registry. I wanted to try my hand at a custom errorprone BugChecker
, which meant expanding my registry's errorprone
module to include the check_api
directory tree in addition to just the annotations.
After fighting with other dependencies, I was able to find the maven additions I'd need for the module, but ran into one last issue I can't figure out how to resolve:
The code under this directory references com.sun.tools.javac.*
and also uses the var
keyword. If I don't specify java language versions in my .bazelrc
, the var
keyword causes the error:
warning: as of release 10, 'var' is a restricted type name \
and cannot be used for type declarations or as the element type of an array
Which I found confusing at first as I thought the default language level was now 11, but I was wrong. So this is expected.
But when I specify a higher language level by adding build --java_language_version=11 --tool_java_language_version=11
to my bazelrc
then the com.sun.tools.javac
references cause the error:
error: package com.sun.tools.javac.code is not visible
import com.sun.tools.javac.code.Symbol.ClassSymbol;
^
(package com.sun.tools.javac.code is declared in module jdk.compiler, which does not export it to the unnamed module)
What makes this especially confusing is that when this happens bazel indicates that the full command is:
external\rules_java~~toolchains~remotejdk21_win\bin\java.exe \
--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED \
... (remaining 19 arguments skipped)
and those --add-exports
flags would seem to be exactly the flags needed to solve this issue.
I was able to reproduce this in a small Minimal Example that doesn't depend on the registry.
I don't know much about the java toolchain setup or how to customize it (or where to do so if need be). Ideally if it is necessary it would be something I could do centrally. I have many different workspaces and it would be better if I didn't have to reconfigure the toolchain separately in each one.
Another potential concern is that eventually some projects will be Android based (I haven't gotten any Android to work with the bzlmod registry yet, but that's a different problem for another time if I can't crack it), so changes to the toolchain that would prevent that would be less than ideal.
Since any of the custom errorprone checks would only be run by bazel itself through its a part of the errorprone integration, maybe I just need a toolchain to use for those checks (and their tests) specifically? Still, ideally if it can be done without toolchain customization, that would be better.
Unrelated to the problem specifically, but potentially helpful to improve my understanding:
To see what would happen, I tried setting the language level higher (17) and then I got:
ERROR: D:/_bazel_out/sfuxpclr/external/rules_jvm_external~~maven~javax_maven/BUILD:26:11: Stamping the manifest of @@rules_jvm_external~~maven~javax_maven//:javax_annotation_javax_annotation_api failed: (Exit 1): AddJarManifestEntry.exe failed: error executing StampJarManifest command (from targ
et @@rules_jvm_external~~maven~javax_maven//:javax_annotation_javax_annotation_api) bazel-out\x64_windows-opt-exec-ST-13d3ddad9198\bin\external\rules_jvm_external~\private\tools\java\com\github\bazelbuild\rules_jvm_external\jar\AddJarManifestEntry.exe --source ... (remaining 5 arguments skipped)
Error: LinkageError occurred while loading main class com.github.bazelbuild.rules_jvm_external.jar.AddJarManifestEntry
java.lang.UnsupportedClassVersionError: com/github/bazelbuild/rules_jvm_external/jar/AddJarManifestEntry has been compiled by a more recent version of the Java Runtime (class file version 61.0), this version of the Java Runtime only recognizes class file versions up to 55.0
At first I thought this would be caused by including jars from maven that were compiled under an earlier version that then cannot be linked in. But the error message seems backwards, as "this version of the java runtime" would be the older one, and it's complaining (presumably) about my code compiled under the v17 runtime I specified. But if I specified (tool_)java_language_version=17
, then where is "this" older runtime coming from? What's trying to use it?
Credit to Fabian on the bazel project for helping with this.
It turned out the issue stemmed from a misunderstanding of how the add-exports
and add-opens
flags worked.
javacopts
flags.add-exports
and add-opens
becomes important as add-opens
is ignored at compile time so the flags I'd copied from a query to get the list from the toolchain were not correct as the add-opens
flags in that list needed to be changed to add-exports
.With the flags added as either --javacopt
flags in the bazelrc
file or as javacopts
on the java_library
target, the build was able to succeed.