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

bazel: building java targets fails because bazel downloads ijar binary #63096

Closed
Profpatsch opened this issue Jun 13, 2019 · 13 comments · Fixed by #63532
Closed

bazel: building java targets fails because bazel downloads ijar binary #63096

Profpatsch opened this issue Jun 13, 2019 · 13 comments · Fixed by #63532
Labels
0.kind: bug Something is broken

Comments

@Profpatsch
Copy link
Member

Issue description

Bazel fetches a binary at runtime and tries to execute it, which of course fails on NixOS:

ERROR: /home/philip/.cache/bazel/_bazel_philip/cccb2d2da8416067607b8c5cff088df0/external/org_apache_spark_spark_core_2_10/BUILD:7:1: Extracting interface @org_apache_spark_spark_core_2_10//:org_apache_spark_spark_core_2_10 failed (Exit 1) ijar failed: error executing command external/remote_java_tools_linux/java_tools/ijar/ijar external/org_apache_spark_spark_core_2_10/spark-core_2.10-1.6.0.jar ... (remaining 3 argument(s) skipped)

Use --sandbox_debug to see verbose messages from the sandbox
src/main/tools/linux-sandbox-pid1.cc:427: "execvp(external/remote_java_tools_linux/java_tools/ijar/ijar, 0x62e860)": No such file or directory

Related to bazelbuild/bazel#8575

Steps to reproduce

Build any Java rule with bazel 0.26.1 in nixpkgs on NixOS.

cc @groodt @kalbasit

@kalbasit
Copy link
Member

I'm having the same issue. They have a new target for the java_runtime, called @bazel_tools//tools/jdk:absolute_javabase: https://github.com/bazelbuild/bazel/blob/cfc6800c64bc97f433e602d0e9d0753b3036502e/tools/jdk/BUILD#L67-L75. I hardcoded the ABSOLUTE_PATH, but it did not work.

diff --git a/src/.bazelrc b/src/.bazelrc
index d67eb3c81..5a2bcc9ce 100644
--- a/src/.bazelrc
+++ b/src/.bazelrc
@@ -48,20 +48,11 @@ test --features=race
 # https://docs.bazel.build/versions/master/be/java.html#java_toolchain
 # https://github.com/bazelbuild/bazel/blob/17794d58cc493d918a98c3250302ca44b1d53e3f/tools/jdk/default_java_toolchain.bzl#L84-L93
 
-build --host_java_toolchain='@bazel_tools//tools/jdk:toolchain_hostjdk8'
-build --host_javabase='@local_jdk//:jdk'
-build --java_toolchain='@bazel_tools//tools/jdk:toolchain_hostjdk8'
-build --javabase='@local_jdk//:jdk'
-build --proto_toolchain_for_java='@bazel_tools//tools/jdk:toolchain_hostjdk8'
+build --host_javabase='@bazel_tools//tools/jdk:absolute_javabase'
+build --define=ABSOLUTE_JAVABASE=/nix/store/543yiclmkvmpy8b9fg00y0bw4xwh3865-openjdk-8u212-ga/lib/openjdk

@kalbasit
Copy link
Member

kalbasit commented Jun 13, 2019

I suspect it's coming from here which is called from here. The absolute_javabase java_runtime defines java_home but not the ijar target.

@kalbasit
Copy link
Member

kalbasit commented Jun 14, 2019

@Profpatsch have you made any progress on this?

@Profpatsch
Copy link
Member Author

tbh I was hoping someone else would fix it. :P

I don’t have much time allocated to bazel work for next week, so it might be ~10 days until I can take an earnest stab.

@kalbasit
Copy link
Member

kalbasit commented Jun 15, 2019

I was honestly expecting the following patch to work, but 🤷‍♂️! I'm not really sure why it's not working.

Force Bazel to build ijar locally
diff --git a/tools/jdk/BUILD b/tools/jdk/BUILD
index d99fb7adb9..b582f7ba67 100644
--- a/tools/jdk/BUILD
+++ b/tools/jdk/BUILD
@@ -327,24 +327,12 @@ default_java_toolchain(
 
 alias(
     name = "toolchain",
-    actual = select({
-        "//src/conditions:darwin": "@remote_java_tools_darwin//:toolchain",
-        "//src/conditions:darwin_x86_64": "@remote_java_tools_darwin//:toolchain",
-        "//src/conditions:windows": "@remote_java_tools_windows//:toolchain",
-        "//src/conditions:linux_x86_64": "@remote_java_tools_linux//:toolchain",
-        "//conditions:default": "@bazel_tools//tools/jdk:legacy_toolchain",
-    }),
+    actual = "@bazel_tools//tools/jdk:legacy_toolchain",
 )
 
 alias(
     name = "remote_toolchain",
-    actual = select({
-        "//src/conditions:darwin": "@remote_java_tools_darwin//:toolchain",
-        "//src/conditions:darwin_x86_64": "@remote_java_tools_darwin//:toolchain",
-        "//src/conditions:windows": "@remote_java_tools_windows//:toolchain",
-        "//src/conditions:linux_x86_64": "@remote_java_tools_linux//:toolchain",
-        "//conditions:default": "@bazel_tools//tools/jdk:legacy_toolchain",
-    }),
+    actual = "@bazel_tools//tools/jdk:legacy_toolchain",
 )
 
 # The 'vanilla' toolchain is an unsupported alternative to the default.
diff --git a/tools/jdk/BUILD.java_tools b/tools/jdk/BUILD.java_tools
index 7d4ee45498..30d26ebd5c 100644
--- a/tools/jdk/BUILD.java_tools
+++ b/tools/jdk/BUILD.java_tools
@@ -18,7 +18,7 @@ java_toolchain(
     genclass = [":Genclass"],
     header_compiler = [":Turbine"],
     header_compiler_direct = [":TurbineDirect"],
-    ijar = [":ijar"],
+    ijar = [":ijar_cc_binary"],
     javabuilder = [":JavaBuilder"],
     javac = [":javac_jar"],
     javac_supports_workers = 1,
@@ -52,7 +52,7 @@ java_toolchain(
         "-g",
         "-parameters",
     ],
-    singlejar = [":singlejar"],
+    singlejar = [":singlejar_cc_bin"],
     source_version = "8",
     target_version = "8",
     tools = [
diff --git a/tools/jdk/BUILD.java_tools.old b/tools/jdk/BUILD.java_tools.old
index ff438af752..6b6e2aea3f 100644
--- a/tools/jdk/BUILD.java_tools.old
+++ b/tools/jdk/BUILD.java_tools.old
@@ -10,7 +10,7 @@ java_toolchain(
     genclass = [":Genclass"],
     header_compiler = [":turbine"],
     header_compiler_direct = [":turbine_direct"],
-    ijar = [":ijar"],
+    ijar = [":ijar_cc_binary"],
     javabuilder = [":javabuilder"],
     javac = [":javac_jar"],
     tools = [
@@ -52,7 +52,7 @@ java_toolchain(
         # Restrict protos to Java 7 so that they are compatible with Android.
        "proto": ["-source", "7", "-target", "7"],
     },
-    singlejar = [":singlejar"],
+    singlejar = [":singlejar_cc_bin"],
     bootclasspath = ["@bazel_tools//tools/jdk:platformclasspath"],
 )

@guibou
Copy link
Contributor

guibou commented Jun 18, 2019

This issue is typical with bazel on nixos: every "prebuilt" binary fetched by any bazel rule will fail with the same issue.

We can fix each issue manually as they arise, but can we do better in a potential more generic way?

From what I know, the only place bazel may generate binaries from the outerworld are in repository rules, and especially the following rules:

What are your thoughts about applying a recursive patchelf to patch at least the dynamic loader on the result of these rules?

Another option may be to just patch https://docs.bazel.build/versions/master/skylark/lib/repository_ctx.html#execute to rewrite the call to /path/to/know/ld/loader binary_path instead.

@kalbasit
Copy link
Member

This issue is typical with bazel on nixos: every "prebuilt" binary fetched by any bazel rule will fail with the same issue.

We can fix each issue manually as they arise, but can we do better in a potential more generic way?

From what I know, the only place bazel may generate binaries from the outerworld are in repository rules, and especially the following rules:

What are your thoughts about applying a recursive patchelf to patch at least the dynamic loader on the result of these rules?

It would be wonderful if that would work, as we don't have to keep specifying Nix provided toolchains. Making this work well might not be a trivial task, as you would most likely have to replicate autoPatchelfHook.

Another option may be to just patch https://docs.bazel.build/versions/master/skylark/lib/repository_ctx.html#execute to rewrite the call to /path/to/know/ld/loader binary_path instead.

How would this allow it to find, say go or javac?

@guibou
Copy link
Contributor

guibou commented Jun 18, 2019

It would be wonderful if that would work, as we don't have to keep specifying Nix provided toolchains. Making this work well might not be a trivial task, as you would most likely have to replicate autoPatchelfHook.

Yes. That's the most difficult solution.

How would this allow it to find, say go or javac?

I don't understand. The only things I'm thinking about is that, instead of using execute(arguments=foo) we rewrite it as execute(arguments=["path/to/a/known/ld/linker", call_to_which(foo[0])] + foo[1:]).

@kalbasit
Copy link
Member

It would be wonderful if that would work, as we don't have to keep specifying Nix provided toolchains. Making this work well might not be a trivial task, as you would most likely have to replicate autoPatchelfHook.

Yes. That's the most difficult solution.

How would this allow it to find, say go or javac?

I don't understand. The only things I'm thinking about is that, instead of using execute(arguments=foo) we rewrite it as execute(arguments=["path/to/a/known/ld/linker", call_to_which(foo[0])] + foo[1:]).

I see what you mean now. I think the autoPatchelfHook is more elegant. Given the amount of work that might require, it might be prudent to just fix the immediate issue right now. @guibou would you be able to take a stab at it?

@guibou
Copy link
Contributor

guibou commented Jun 18, 2019

@kalbasit I'm on it.

@guibou
Copy link
Contributor

guibou commented Jun 19, 2019

Progress: I've built a local package with fixed ijar and I'm using --override_repository to point to that package. This setting is done inside a system-wide bazelrc file.

Hopefully I'll be able to open a PR today.

@kalbasit
Copy link
Member

kalbasit commented Jun 19, 2019

That's great news @guibou! Thank you! Please include a Java test (similar to current python test) with your PR.

@guibou guibou mentioned this issue Jun 19, 2019
10 tasks
@guibou
Copy link
Contributor

guibou commented Jun 20, 2019

That's great news @guibou! Thank you! Please include a Java test (similar to current python test) with your PR.

AFAIK there is a java test in the installCheck phase that I also repaired.

guibou added a commit to guibou/nixpkgs that referenced this issue Jun 24, 2019
- Fixs for newly introduced bin/bash hardcoded reference
- Bazel now references `remote_java_tools_xxx` which contains prebuilt
  binaries. We prefetch them, fix them, and force bazel to use the
  fixed repository.

It also closes NixOS#63096
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
0.kind: bug Something is broken
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants