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

Add option to use JDK from remote repository instead of the embedded JDK as default host javabase. #6216

Closed
wants to merge 1 commit into from

Conversation

meisterT
Copy link
Member

After 09cf76e we should only download
that remote JDK if we actually need it.

We plan to hide the embedded JDK so that minimize it in order to shrink
Bazel's binary size. Users that don't need the JDK shouldn't pay the
price for it.
The minimizing step will reduce Bazel's binary size by about 40MB to
~130MB.

RELNOTES[INC]: Add --incompatible_use_remotejdk_as_host_javabase to default the host javabase to remote repository.

@meisterT
Copy link
Member Author

cc @iirina @buchgr

@@ -602,6 +615,9 @@ public FragmentOptions getHost() {
JavaOptions host = (JavaOptions) getDefault();

host.javaBase = hostJavaBase;
if (useRemoteJdkAsHostJavaBase) {
host.javaBase = Label.parseAbsoluteUnchecked("@bazel_tools//tools/jdk:remotejdk");
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Instead of unconditionally overriding the --host_javabase, could this supply a default to be used if --host_javabase is unset?

If there's an explicit --host_javabase flag I think we should try to honour that.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks. I've updated the PR and added a test.

tools/jdk/BUILD Outdated
"//src/conditions:darwin_x86_64": "@remotejdk_macos//:jdk",
"//src/conditions:windows": "@remotejdk_win//:jdk",
"//src/conditions:linux_aarch64": "@remotejdk_linux_aarch64//:jdk",
"//conditions:default": "@remotejdk_linux//:jdk",
Copy link
Contributor

Choose a reason for hiding this comment

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

On non-linux platforms it might be better to not provide a default, and instead require an explicitly configured --host_javabase.

Copy link
Member Author

Choose a reason for hiding this comment

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

Why is that? I want to hide the embedded JDK without breaking anyone. This is basically maintaining the status quo where people don't have to specify a host_javabase.

Copy link
Contributor

Choose a reason for hiding this comment

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

Are you referring to this status quo?

bazel/src/BUILD

Line 210 in 1e68ace

"//conditions:default": [

That select is used when building Bazel itself, and binaries with embedded JDKs are provided for a fixed set of platforms.

This select will be used by Bazel installs on arbitrary platforms, and defaulting to linux on non-linux platforms is unhelpful. It's a regression compared to the current behaviour of the binaries without an embedded JDK, which I think default to using the local JDK as the server, host, and target javabases.

Copy link
Member Author

Choose a reason for hiding this comment

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

I see what you mean now - I've to do some research and will come back to you.

Copy link
Contributor

Choose a reason for hiding this comment

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

I was about to say the same :) I think it's fine to submit "are we on $OPERATING_SYSTEM to @bazel_tools somewhere. We already have //tools/osx:darwin, which should probably stay as an alias to whatever you come up with.

/cc @ilya-biryukov @mhlopko @katre because this is also interesting for C++ and platforms in general.

Copy link
Contributor

Choose a reason for hiding this comment

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

re: unknown platforms, I also prefer erroring out. It only happens with the incompatible flag set so it should give people heads-up, and I'd expect that those OSes are a niche use case which is served well enough by an appropriate --host_javabase flag.

Copy link
Member Author

Choose a reason for hiding this comment

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

As discussed offline: that already exists in @bazel_tools and I'm using it (I had to add linux as an option though).

@@ -601,6 +614,10 @@ public ImportDepsCheckingLevelConverter() {
public FragmentOptions getHost() {
JavaOptions host = (JavaOptions) getDefault();

if (useRemoteJdkAsHostJavaBase
&& "@bazel_tools//tools/jdk:host_jdk".equals(hostJavaBase.toString())) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can the default be null? That would avoid the duplication here, and also make it possible to distinguish between 'unset' and 'explicitly set to the default value'.

Copy link
Member Author

Choose a reason for hiding this comment

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

Done.

Copy link
Contributor

@lberki lberki left a comment

Choose a reason for hiding this comment

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

In general, I am for this change. @meisterT : if you step up to do this work, please also consider the relative merits / demerits of explicitly opting into downloading the JDK and looking for a local one first.

@@ -597,11 +610,22 @@ public ImportDepsCheckingLevelConverter() {
+ "--java_header_compilation is enabled.")
public boolean requireJavaToolchainHeaderCompilerDirect;

private Label getHostJavaBase() {
if (hostJavaBase == null) {
if (useRemoteJdkAsHostJavaBase) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggestion: how about implementing this as a config_setting()? Then you need less logic in core (only the incompatible flag)

Copy link
Member Author

Choose a reason for hiding this comment

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

This is just temporary. When we switch the flag on, we can remove all the code here.

tools/jdk/BUILD Outdated
"//src/conditions:darwin_x86_64": "@remotejdk_macos//:jdk",
"//src/conditions:windows": "@remotejdk_win//:jdk",
"//src/conditions:linux_aarch64": "@remotejdk_linux_aarch64//:jdk",
"//conditions:default": "@remotejdk_linux//:jdk",
Copy link
Contributor

Choose a reason for hiding this comment

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

I was about to say the same :) I think it's fine to submit "are we on $OPERATING_SYSTEM to @bazel_tools somewhere. We already have //tools/osx:darwin, which should probably stay as an alias to whatever you come up with.

/cc @ilya-biryukov @mhlopko @katre because this is also interesting for C++ and platforms in general.

tools/jdk/BUILD Outdated
"//src/conditions:darwin_x86_64": "@remotejdk_macos//:jdk",
"//src/conditions:windows": "@remotejdk_win//:jdk",
"//src/conditions:linux_aarch64": "@remotejdk_linux_aarch64//:jdk",
"//conditions:default": "@remotejdk_linux//:jdk",
Copy link
Contributor

Choose a reason for hiding this comment

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

re: unknown platforms, I also prefer erroring out. It only happens with the incompatible flag set so it should give people heads-up, and I'd expect that those OSes are a niche use case which is served well enough by an appropriate --host_javabase flag.

@meisterT
Copy link
Member Author

I think I've addressed all comments now.

CI is green and I've also tested with the _nojdk variant to make sure that we do the right thing.

@@ -597,11 +610,22 @@ public ImportDepsCheckingLevelConverter() {
+ "--java_header_compilation is enabled.")
public boolean requireJavaToolchainHeaderCompilerDirect;

private Label getHostJavaBase() {
if (hostJavaBase == null) {
if (useRemoteJdkAsHostJavaBase && "1".equals(System.getProperty("embedded_jdk"))) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you document this part? Why would we only use the remote JDK with binaries that have an embedded JDK?

Copy link
Member Author

Choose a reason for hiding this comment

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

Added a comment - we do want to make the switch as soft as possible.

if (hostJavaBase == null) {
if (useRemoteJdkAsHostJavaBase
// If there's no embedded JDK, we did use the local JDK as host JDK in the past.
// In order to make this flag flip as soft as possible, we will continue to do so.
Copy link
Contributor

Choose a reason for hiding this comment

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

To confirm: there are no known reasons to prefer using a local JDK in this case, and the motivation for this logic is to make this change a direct replacement for the current behaviour?

Any concerns with following up with another change (maybe behind another --incompatible_ flag) to remove this part? Being able to rely on the supported --host_javabase version for Bazel binaries without an embedded JDK seems like a Feature.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, my motivation is to have a direct replacement for current behavior.

I guess we should figure out what the long term plan is before we the other flag, i.e. whether we want to default to the local JDK for everything or the remote JDK.

Copy link
Contributor

Choose a reason for hiding this comment

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

Okay. I'm not sure the additional complexity here is buying us much, but I understand wanting to reduce the risk of this change. How is this logic being tested? Is there coverage in bazel_java_test.sh for the no-JDK case?

Copy link
Member Author

Choose a reason for hiding this comment

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

I tested the logic manually. We could set up a test for it (next to bazel_java_test.sh) but that would require building another bazel and duplicating some bits of test setup. Do you think that's worth it, given this will go away again when we flip the flag?

Copy link
Contributor

Choose a reason for hiding this comment

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

The "1".equals(System.getProperty("embedded_jdk") part is going away after we flip the flag?

Is the removal of "1".equals(System.getProperty("embedded_jdk") going to happen behind a different --incompatible_changes_ flag?

Copy link
Member Author

Choose a reason for hiding this comment

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

It results in different behaviour for the binaries with and without embedded JDKs, which is visible to users. Maybe I'm just not understanding the plan.

Yes, the behavior is different for users with and without embedded JDK. It is already different today and I don't want to make it the same in this PR. This is basically maintaining current behavior.

What will the replacement for "1".equals(System.getProperty("embedded_jdk") be when that happens?

external/embedded_jdk links to the local JDK if there's no embedded JDK if I'm not mistaken. We'll use that then.

Copy link
Contributor

Choose a reason for hiding this comment

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

The whole check that we do in Java code now will go away once we flip/remove the flag since we'll do that in the BUILD file instead.

What will the replacement for "1".equals(System.getProperty("embedded_jdk") be when that happens?

external/embedded_jdk links to the local JDK if there's no embedded JDK if I'm not mistaken. We'll use that then.

I mean, how will that logic be expressed? You mentioned something about putting it in the BUILD file instead of current Java code?

Maybe it would be helpful to see the follow-up patch you have in mind, if I'm not following the explanation.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks for pushing on it.
Turns out that we have to keep some logic about the embedded JDK if we don't want to switch the no JDK case. Example commit:
meisterT@5a2c55a

So we have two options:

  • keep this check and don't change how we handle the host JDK in the no JDK case
  • remove the check and also switch how we handle the host JDK in the no JDK case

Preferences?

Copy link
Contributor

Choose a reason for hiding this comment

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

Got it, thanks.

remove the check and also switch how we handle the host JDK in the no JDK case

I vote for this one, for two reasons:

  1. I think it's where we want to end up eventually, for all of the reasons we aren't using a locally-installed JDK as the default host javabase for the embedded JDK binaries. It's mostly of question of whether to do it now or as a follow-up change with yet another --incompatible_changes_* flag.
  2. The current nojdk --host_javabase behaviour isn't well-tested, and if remove this difference between the nojdk and embedded-JDK cases we have one fewer configuration to test. I'm uneasy about adding this logic without test coverage.

Copy link
Contributor

Choose a reason for hiding this comment

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

As discussed offline with @lberki, the plan is to try the "remove the check and also switch how we handle the host JDK in the no JDK case" option. Everything else here LGTM.

@meisterT meisterT force-pushed the remotejdk branch 2 times, most recently from 06d94a2 to 4962301 Compare October 5, 2018 08:53
…JDK as default host javabase.

After 09cf76e we should only download
that remote JDK if we actually need it.

We plan to hide the embedded JDK so that minimize it in order to shrink
Bazel's binary size. Users that don't need the JDK shouldn't pay the
price for it.
The minimizing step will reduce Bazel's binary size by about 40MB to
~130MB.

RELNOTES[INC]: Add --incompatible_use_remotejdk_as_host_javabase to default the host javabase to remote repository.
@dslomov
Copy link
Contributor

dslomov commented Nov 5, 2018

Please follow the process for communicating this breaking change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes team-Rules-Java Issues for Java rules
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants