Extended JDK 8 Support
Protobuf v30.0 upgraded rules_jvm_external to 6.3 for Bazel 8 support which seems to have also dropped support for JDK8.
This can be observed by users when using bazel targets that rely on rules_jvm_external's maven.install (i.e. //java/util which depends on gson, etc), probably due to this change. This also seems to have broken JDK8 support for our maven release artifacts which are generated via java_export and -source 8 -target 8 javacopts (i.e. //java/core:core_mvn)
We're currently slated to continue supporting JDK8 until late 2026 per our OSS Java Support Policies.
Is it possible to extend JDK 8 support accordingly in rules_jvm_external as well?
Related Issues:
- https://github.com/bazel-contrib/rules_jvm_external/issues/1337
- https://github.com/protocolbuffers/protobuf/issues/20580
Modern JDK releases are removing Java 8 support, so we can't rely on -release 8 to work as expected moving forwards. With the current most recent JDK you already get warnings about this on the console, and we don't want to display those to users. We will likely require a transition to enable Java 8 support (which is technically doable) for whichever specific classes are required.
Are there specific targets you need to work with Java 8? If you can mandate that people use a lockfile with rules_jvm_external, then we can also simplify the codepaths for regular builds so that those don't need any compiled java code, which means that Java 11+ is only needed for regenerating the lock file.
Put another way, do you need all the functionality of rules_jvm_external to work with Java 8, or just the build time pieces? The latter is significantly easier to do than the former.
The other thing to be aware of is that our transitive dependencies may depend on Java 11+. I'm not sure what JVM coursier is targeting, but I imagine some of the libraries we use have already made the jump. We could hold back the tide here for a while, but it will not do any good in the long run.
I hope that the next update to the plan aligns a little more closely with the JDK roadmap, and jumps to a minimum version of 17, as I'd hate for us to get into this same situation with Java 11 (especially since that was EoL'd in September 2023). Could you please advocate for this with the appropriate team within Google?
I think using Bazel's JDK from https://github.com/bazel-contrib/rules_jvm_external/pull/1323 would fix this right?
For JDK8 support for our Maven users, we use rules_jvm_external for java_export/kt_jvm_export rules to generate maven artifacts. We need the outputted artifacts to target java 8 compatibility but it probably doesn't matter as much java version is used when we actually build the artifacts -- we're using java 11 today. I believe we're currently getting artifacts that require minimum JDK11 (https://github.com/protocolbuffers/protobuf/issues/20580)
For JDK8 support for our Bazel users, we need maven.install to work to install dependencies. This is where we're hitting coursier errors when running with JDK8 when users are using //java/util package which has dependencies fetched via maven.install (https://github.com/bazel-contrib/rules_jvm_external/issues/1337). This might be mostly isolated to users of our utils library, since I think most of our other maven deps are for tests.
A little unclear what you mean by build time piece -- is the former non-build-time and the second build time?
I believe the next bump is currently slated to be to minimum version of JDK 11 unfortunately, but we can certainly start some conversations internally to see if the ecosystem has moved on sufficiently to advance our JDK support windows accordingly.
@zhangskz, there are two modes in which maven.install works. If the lock_file attribute is set, then we just use the information from the lock file, and I think all that work is done in pure Starlark. However, if there is no lock file, then we need to run a resolver. The underlying resolver we use is either coursier or one derived from Maven. The default is the coursier-based resolver, and I suspect that's the one you're using.
If that's the case, this should really be a request for coursier to support Java 8 and not us.
If that's not the case, could you please supply a small reproducible example of the issue that you're facing, as it's not entirely clear what it is we need to do to support you properly.
I believe the lock_file workaround would work since we use maven_install.json when using rules_jvm_external from WORKSPACE, which didn't hit the coursier error in our CI with JDK8 even though their bzlmod counterparts did. Will try this out and report back.
For the non-JDK8 compatible artifacts obtained using java_export despite setting -source 8 and -target 8, did something change in rules_jvm_external regarding how those javacopts are handled or passed on? Looks like maybe we should actually be setting -release 8 instead, but not clear what may have changed here.
I'll wait to hear back from you before doing anything else here.
FWIW, no resolver does a check to see which java version dependencies rely on. They just do the constraint solving of making sure the version numbers match up. The flags you pass the compiler come far too late to influence that.