Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use Bazel's JDK to run coursier #1323

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

cheister
Copy link
Collaborator

@cheister cheister commented Feb 7, 2025

Addresses #445 and #1046 by taking the workaround in #445 and applying it as the default before looking at JAVA_HOME.

I also added a way to give the JVM settings for both coursier and maven if a custom cacerts file was needed. This can be set by doing

build --repo_env=JDK_JAVA_OPTIONS=-Djavax.net.ssl.trustStore=<path-to-cacerts>

in .bazelrc
Based on JDK_JAVA_OPTIONS

@cheister cheister requested review from jin and shs96c as code owners February 7, 2025 07:37
@cheister
Copy link
Collaborator Author

cheister commented Feb 7, 2025

If this looks like an acceptable approach I can update the documentation as well.

Copy link
Collaborator

@shs96c shs96c left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The general approach seems fine, but it might be fragile.

return repository_ctx.path(java_home + "/bin/java")
elif repository_ctx.which("java") != None:
return repository_ctx.which("java")
embedded_java = "../bazel_tools/jdk/bin/java"
Copy link
Collaborator

@shs96c shs96c Feb 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work with Bazel 8? I thought the location of the java binary was somewhere under rules_java now?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It worked when I ran REPIN=1 bazel run @regression_testing_coursier//:pin with Bazel 8.0.1. Adding RJE_VERBOSE=1 showed that the coursier tasks were running with

.../bazel_tools/jdk/bin/java -noverify -jar ...

I also deleted the bazel cache directory and ran it from a clean install and it also worked.

Copy link

@srdo srdo Feb 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this JDK the minimized (jlinked) JDK Bazel bundles, or is it something else (e.g. a downloaded separate one)?

I'm asking because I think the minimized JDK may not contain all normal JDK modules, and so using it to run Coursier could be problematic down the road if the embedded JDK ends up not containing modules Coursier happens to need, which there isn't a good way to prevent, since I think Bazel's own JDK stripping assumes that JDK will only run Bazel and not other things.

https://github.com/bazelbuild/bazel/blob/d2c2ad1c657d517ae421a562028e26c345eaf12f/src/minimize_jdk.sh#L64

When I check the module list for this JDK in a local Bazel install, it looks like it's been stripped down.

$ jimage list bazel_tools/jdk/lib/modules | grep "Module:"
Module: java.base
Module: java.compiler
Module: java.instrument
Module: java.logging
Module: java.management
Module: java.naming
Module: java.security.sasl
Module: java.sql
Module: java.transaction.xa
Module: java.xml
Module: jdk.crypto.ec
Module: jdk.management
Module: jdk.unsupported

as compared to a full JDK:

$ jimage list modules | grep "Module:"
Module: java.base
Module: java.compiler
Module: java.datatransfer
Module: java.desktop
Module: java.instrument
Module: java.logging
Module: java.management.rmi
Module: java.management
Module: java.naming
Module: java.net.http
Module: java.prefs
Module: java.rmi
Module: java.scripting
Module: java.se
Module: java.security.jgss
Module: java.security.sasl
Module: java.smartcardio
Module: java.sql.rowset
Module: java.sql
Module: java.transaction.xa
Module: java.xml.crypto
Module: java.xml
Module: jdk.accessibility
Module: jdk.attach
Module: jdk.charsets
Module: jdk.compiler
Module: jdk.crypto.cryptoki
Module: jdk.crypto.ec
Module: jdk.dynalink
Module: jdk.editpad
Module: jdk.graal.compiler.management
Module: jdk.graal.compiler
Module: jdk.hotspot.agent
Module: jdk.httpserver
Module: jdk.incubator.vector
Module: jdk.internal.ed
Module: jdk.internal.jvmstat
Module: jdk.internal.le
Module: jdk.internal.opt
Module: jdk.internal.vm.ci
Module: jdk.jartool
Module: jdk.javadoc
Module: jdk.jcmd
Module: jdk.jconsole
Module: jdk.jdeps
Module: jdk.jdi
Module: jdk.jdwp.agent
Module: jdk.jfr
Module: jdk.jlink
Module: jdk.jpackage
Module: jdk.jshell
Module: jdk.jsobject
Module: jdk.jstatd
Module: jdk.localedata
Module: jdk.management.agent
Module: jdk.management.jfr
Module: jdk.management
Module: jdk.naming.dns
Module: jdk.naming.rmi
Module: jdk.net
Module: jdk.nio.mapmode
Module: jdk.random
Module: jdk.sctp
Module: jdk.security.auth
Module: jdk.security.jgss
Module: jdk.unsupported.desktop
Module: jdk.unsupported
Module: jdk.xml.dom
Module: jdk.zipfs

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is true, but CI should catch any problems with the minimized JDK when coursier is updated in the future and we'll leave the option to run with java from JAVA_HOME as an option for now.

Copy link

@srdo srdo Feb 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 The risk is probably still there that CI doesn't exercise all the coursier code so missing class errors could be lurking. Since the JVM is tied to Bazel, different bazel versions might also have different modules loaded, so it's not just down to coursier upgrades. Might not be an issue in practice though.

Sorry for butting in, but I'm wondering why rules_jvm_external can't find Java via a toolchain, like other Java-using rulesets do, instead of trying to use the embedded JDK?

embedded_java = "../bazel_tools/jdk/bin/java"
if _is_file(repository_ctx, embedded_java):
return repository_ctx.path(embedded_java)
else:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We've already returned at this point if embedded_java is a file, so the else is unnecessary and introduces extra indentation.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, removed the else

java_home = repository_ctx.os.environ.get("JAVA_HOME")
if java_home != None:
return repository_ctx.path(java_home + "/bin/java")
elif repository_ctx.which("java") != None:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see we did the same thing here, but I don't think it makes things clearer. shrug

@@ -120,6 +121,9 @@ pin_dependencies = rule(
doc = "Location of the generated lock file",
mandatory = True,
),
"jvm_flags": attr.string(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A string_list would better model what you're doing here, and would match how we set jvm args in the regular java rules.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

True, but is there value in parsing the JDK_JAVA_OPTIONS env var into a string_list only to immediately re-concatenate it so we can pass it to the --jvm_flags option of the java wrapper script?

@cheister cheister force-pushed the use-bazel-java-for-coursier branch from b4a815e to 48176f4 Compare February 7, 2025 21:07
@cheister
Copy link
Collaborator Author

cheister commented Feb 7, 2025

Since this would change the default java running coursier do we want to provide an option for people to opt back to using JAVA_HOME if they need to?

@shs96c
Copy link
Collaborator

shs96c commented Feb 11, 2025

@cheister, that's probably a good idea. The neatest way would be a configurable build attribute, but an env variable would be simpler.

@cheister cheister force-pushed the use-bazel-java-for-coursier branch from 48176f4 to 9f99a11 Compare February 11, 2025 23:58
@cheister cheister force-pushed the use-bazel-java-for-coursier branch from 9f99a11 to 5e1ff9b Compare February 12, 2025 00:02
@cheister
Copy link
Collaborator Author

@cheister, that's probably a good idea. The neatest way would be a configurable build attribute, but an env variable would be simpler.

Yeah, going for the env var since I'm hoping we can remove it later

@blockjon-dd
Copy link

Thank you so much for working on this PR.

I'm at the brink of installing the JDK on all of our Bazel CI and developer machines. However, it seems like once this PR merges, I could avoid doing that.

Therefore, I feel like I have to ask when this PR might merge. If the answer is really soon, that would be amazing. Otherwise, I will start installing the JDK in the global systems.

@srdo
Copy link

srdo commented Feb 16, 2025

@blockjon-dd If you need it urgently, you could just point Bazel at this branch and use this immediately?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants