bazelbuild / bazelbuild/bazel

Bazel >= 7.0.0 busted on Docker with M4 Macs

Open
#25,414 3 comments 2 reactions 0 assignees View on GitHub
P3 stale team-Rules-Java type: bug
Dominant language
Java
Stars
25.8k
Forks
4.6k
Avg merge
2d 18h
Merged PRs (30d)
75

Description

### Description of the bug:

Since Bazel 7.0.0, invoking `bazel` at all within a Docker container running on an M4 Mac host produces a fatal error, citing a `SIGILL` and specific complaint about `java.lang.System.registerNatives`:

```
foobar@90e2ad0dd2bd:/opt/app$ cat .bazelversion
7.5.0

foobar@90e2ad0dd2bd:/opt/app$ bazel
Starting local Bazel server and connecting to it...
Server crashed during startup. Now printing /home/foobar/.cache/bazel/_bazel_foobar/8cd13b75700216788cbc2043831c737d/server/jvm.out
OpenJDK 64-Bit Server VM warning: Options -Xverify:none and -noverify were deprecated in JDK 13 and will likely be removed in a future release.
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGILL (0x4) at pc=0x0000ffffa5f3fc5c, pid=1802, tid=1803
#
# JRE version: (21.0.5+11) (build )
# Java VM: OpenJDK 64-Bit Server VM (21.0.5+11-LTS, mixed mode, tiered, compressed oops, compressed class ptrs, g1 gc, linux-aarch64)
# Problematic frame:
# j java.lang.System.registerNatives()V+0 java.base
#
# No core dump will be written. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /opt/app/hs_err_pid1802.log
[0.017s][warning][os] Loading hsdis library failed
#
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
```

This appears to be a manifestation of [this](https://bugs.openjdk.org/browse/JDK-8345296) bug in the JDK and has been cited elsewhere, e.g. [here](https://github.com/corretto/corretto-21/issues/85).

While including a `startup --host_jvm_args=-XX:UseSVE=0` in `.bazelrc` gets Bazel itself working again (NB: this also occurs when using version-specific Bazel binaries without Bazelisk in the picture):

```
foobar@90e2ad0dd2bd:/opt/app$ cat .bazelrc
startup --host_jvm_args=-XX:UseSVE=0

foobar@90e2ad0dd2bd:/opt/app$ bazel version
Bazelisk version: v1.25.0
Build label: 7.5.0
Build target: @@//src/main/java/com/google/devtools/build/lib/bazel:BazelServer
Build time: Thu Jan 30 18:34:53 2025 (1738262093)
Build timestamp: 1738262093
Build timestamp as int: 1738262093

foobar@90e2ad0dd2bd:/opt/app$ $(bazel info java-home)/bin/java -XX:UseSVE=0 -version
openjdk version "21.0.5" 2024-10-15 LTS
OpenJDK Runtime Environment Zulu21.38+21-CA (build 21.0.5+11-LTS)
OpenJDK 64-Bit Server VM Zulu21.38+21-CA (build 21.0.5+11-LTS, mixed mode)
```

it persists when getting Java targets build or run, as it looks like that embedded problematic Java still pops up despite various incantations of the Java-related options (e.g. `--java_runtime_version` and friends); passing `--subcommands` appears to indicate that it's still using the offending JDK 21 binaries to run the `JavaBuilder` with no apparent way, aside from setting up a custom toolchain with `javabuilder_jvm_opts = ["-XX:UseSVE=0"]` (which is not always feasible due to a sea of varying versions of things), to pass along this mitigating option.

21.0.7 purports to fix this, and indeed building that in an affected Docker container does seem to produce `java`, etc. binaries that no longer encounter this issue. Attempting to then use this via `--server_javabase` does get Bazel itself working again without the `.bazelrc` change:

```
foobar@90e2ad0dd2bd:/opt/app$ /tmp/jdk21u-jdk-21.0.7-4/build/linux-aarch64-server-release/jdk/bin/java -version
OpenJDK 64-Bit Server VM warning: Unable to get SVE vector length on this system. Disabling SVE. Specify -XX:UseSVE=0 to shun this warning.
openjdk version "21.0.7-internal" 2025-04-15
OpenJDK Runtime Environment (build 21.0.7-internal-adhoc.foobar.jdk21u-jdk-21.0.7-4)
OpenJDK 64-Bit Server VM (build 21.0.7-internal-adhoc.foobar.jdk21u-jdk-21.0.7-4, mixed mode)

foobar@90e2ad0dd2bd:/opt/app$ cat .bazelrc
# startup --host_jvm_args=-XX:UseSVE=0

foobar@90e2ad0dd2bd:/opt/app$ bazel --server_javabase=/tmp/jdk21u-jdk-21.0.7-4/build/linux-aarch64-server-release/jdk version
Bazelisk version: v1.25.0
Build label: 7.5.0
...
```

but Java targets still fail in the same fashion even with combos of `--java_runtime_version`, etc.

Is this fixed JDK version upgrade slated for inclusion within Bazel sometime soon, ideally on the 7.x.x track, or is there anything else one might do to ensure Bazel itself uses this fixed/an alternate version of Java even when running the `JavaBuilder`, etc.? Alternatively, is there any means by which that flag (`-XX:UseSVE=0`) may be passed along where the embedded Java version is used to get around this in the meantime without fashioning a custom toolchain?

I've included here a bare Bazel/Java project and `Dockerfile` which leverages Bazel 7.5.0 (adjustable via `.bazelversion`; this is using Bazelisk) and includes a very basic `java_binary` (`//:foo`) that can reproduce this. To do so, simply

```
docker build -t foo:latest .
docker run -it foo:latest bash
```

and, within the container, attempt to run `bazel` -- from the outset this should produce the above, and after uncommenting the `common` line in `.bazelrc` therein, while `bazel` itself works, attempting to build or run the target `//:foo` fails:

```
foobar@90e2ad0dd2bd:/opt/app$ bazel run //:foo
INFO: Analyzed target //:foo (0 packages loaded, 0 targets configured).
ERROR: /opt/app/BUILD:5:12: Building foo.jar (1 source file) failed: Worker process returned an unparseable WorkResponse!

Did you try to print something to stdout? Workers aren't allowed to do this, as it breaks the protocol between Bazel and the worker process.

---8<---8<--- Start of response ---8<---8<---
#
# A fatal error has been detected ---8<---8<--- End of response ---8<---8<---
...
```

### Which category does this issue belong to?

Core

### What's the simplest, easiest way to reproduce this bug? Please provide a minimal example if possible.

- Be on an M4 Mac
- Clone https://github.com/vistar-tmaglione/busted-bazel-repro somewhere
- Build and enter that container (`Dockerfile` is included)
- Attempt to run `bazel` (it should blow up)
- Uncomment `# startup --host_jvm_args=-XX:UseSVE=0` in `.bazelrc` and try again (`bazel` itself should run at this point)
- Attempt to build or run the `//:foo` `java_binary` target

### Which operating system are you running Bazel on?

macOS 15.3.1; Docker 4.38.0

### What is the output of `bazel info release`?

release 7.5.0

### If `bazel info release` returns `development version` or `(@non-git)`, tell us how you built Bazel.

_No response_

### What's the output of `git remote get-url origin; git rev-parse HEAD` ?

```text

```

### If this is a regression, please try to identify the Bazel commit where the bug was introduced with bazelisk --bisect.

_No response_

### Have you found anything relevant by searching the web?

I've come across a couple general issues to this effect, e.g. [this](https://bugs.openjdk.org/browse/JDK-8345296) as a JDK bug and [this](https://github.com/corretto/corretto-21/issues/85) outlining the same situation being encountered with Java itself in a Docker container on M4. Nothing Bazel-specific though

### Any other information, logs, or outputs that you want to share?

Bazel 6.5.0 (which we'd previously been using) embedded OpenJDK 11, which appears to be unaffected.

It seems that even at least as early as `7.0.0-pre.20230628.2` which embeds `openjdk version "20.0.1" 2023-04-18` this still occurs with base `bazel` until the `UseSVE=0` directive is uncommented. However, weirdly, the runner on that version still reportedly is using `external/remotejdk17_linux_aarch64/bin/java` (per `--subcommands`) and as such seems to be able to build/run things. `7.0.0` flat still seems to be busted though in both respects.

Contributor guide

Open the contributing guide

Research direction

Start with the repro Dockerfile, .bazelversion, .bazelrc, and BUILD file, then reproduce both bazel startup and bazel run //:foo on an M4 Mac. Trace which embedded JDK launches Bazel and JavaBuilder across the affected Bazel versions and documented options. Done means Bazel and the Java target run successfully in the container without a custom toolchain or manual workaround.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, java
Domain
build-system
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.