ARMアーキテクチャーでBazel 8.xを使う時は8.1.1を使う
TL;DR
Bazel(含むBazelisk)をARMアーキテクチャーのDebian系OSで動かす場合で、8.xのバージョンを使用したい場合には、8.1.1までに留めて、それより上位のバージョンについては検証を踏まえていけるかの判断をするのがおすすめ。
結論の背景
Raspberry Piの上でBazelを使ったビルドを実施しようとしたところ、次のようなエラーに遭遇した。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ bazel
Starting local Bazel server (8.4.1) and connecting to it...
Server crashed during startup. Now printing /home/xxxx/.cache/bazel/_bazel_xxxx/ef5e718a8805684c98da7c98a126c8c0/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.
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.InternalError: unexpected format: java.class
at java.base/java.util.ResourceBundle.loadBundle(Unknown Source)
at java.base/java.util.ResourceBundle.findBundle(Unknown Source)
at java.base/java.util.ResourceBundle.getBundleImpl(Unknown Source)
at java.base/java.util.ResourceBundle.getBundleImpl(Unknown Source)
at java.base/java.util.ResourceBundle.getBundleImpl(Unknown Source)
at java.base/java.util.ResourceBundle.getBundle(Unknown Source)
at java.base/sun.launcher.LauncherHelper$ResourceBundleHolder.<clinit>(Unknown Source)
at java.base/sun.launcher.LauncherHelper.getLocalizedMessage(Unknown Source)
at java.base/sun.launcher.LauncherHelper.abort(Unknown Source)
at java.base/sun.launcher.LauncherHelper.getMainClassFromJar(Unknown Source)
at java.base/sun.launcher.LauncherHelper.loadMainClass(Unknown Source)
at java.base/sun.launcher.LauncherHelper.checkAndLoadMain(Unknown Source)
普段使用していたAMDの開発環境では遭遇しなかったエラー。そもそもビルド自体を始められていない様子。
検索結果や生成AIへの問いかけの内容から、原因の可能性として問われたのは
- 使用しているDebianのバージョンが新しすぎるため、古いバージョンで試みるべき
- 使用しているJavaのバージョンが新しすぎるため、古いバージョンで試みるべき
という点。
使用していたRaspberry Pi OSはDebian 13がベースになっているもの。そこに標準のJDKを入れるとJava 21が入る。 が、Debian 12およびJava 17を使用するべき、というのがひとまず提案された方法。
そこで次の組み合わせでそれぞれ確認することにした。
- Debian 13 x Java 21:デフォルトの組み合わせ
- Debian 13 x Java 17:Stableでは確認できないがUnstableチャンネルからパッケージを取得すれば確認できる組み合わせ
- Debian 12 x Java 17:デフォルトの組み合わせ
- (Debian 12 x Java 21は割愛)
またBazelについては、8.4.1の他、8.5.0(1/4時点で最新)でも確認をしている。 が、エラー内容に差はないように見える。
Unstable Distributionからのパッケージインストール
確認にあたってはDebian 13 x Java 17については、Sid1からJDKをインストールした。 なお、OpenJDK 17自体はここにある。
Debian – Details of package openjdk-17-jdk in sid
具体的には次のように実現できる。
sudo vi /etc/apt/sources.list.d/debian.sourcesで次の内容を追加。これによりUnstable Distributionからインストール可能になる。
1
2
3
4
5
6
#sid
Types: deb
URIs: http://deb.debian.org/debian
Suites: sid
Components: main contrib
Signed-By: /usr/share/keyrings/debian-archive-keyring.pgp
sudo vi /etc/apt/preferences.d/99-pin-sidで次の内容を追加。これにより明示的にsidを使うと指定しなければインストールされない。
1
2
3
Package: *
Pin: release n=sid
Pin-Priority: 100
次のコマンドで確かにsid関連の出力が100となって追加されていればOK。
1
apt-cache policy
上記設定の上で、インストールをすると、Debian 13でもOpenJDK 17がインストールできる。
1
2
sudo apt update
sudo apt install -t sid openjdk-17-jdk
のだが、ここまで対応した上で、Bazelが使用するJavaをシステムのものに切り替えるなど対応をしてもエラー内容に変化はなかった。無念。
Docker上のDebian 12系での再現
続いて、Debian 12系だったらうまくいく可能性があるという話。 こちらは、OpenJDK 17でうまくいかなかった時点で望みが相当薄いと理解していたが、念のため確認をした。
Dockerをインストールして、Debian 12系を動かす。
1
2
3
4
docker run --rm -it debian:12 bash
apt install openjdk-17-jdk wget
wget https://github.com/bazelbuild/bazelisk/releases/download/v1.27.0/bazelisk-arm64.deb
dpkg -i bazelisk-arm64.deb
Bazeliskを入れた後は同様のコマンドで確認できたが、結果は一緒。
先行事例
Debian系のOSにおいてBazelの8.4.1ないし8.5.0を使おうとすると簡単に確認できる方法では使用ができないことまでは確認できた。
それを踏まえて改めて同じような事例を探してみたところ、次のIssueがなかなか気になる内容だった。
Bazel 8.2.0 Won’t run on Debian bookworm arm64 · Issue #25843 · bazelbuild/bazel
I tried installing a binary tar file release of JDK24 and using “–server_javabase=/opt/jdk-24.0.1” on the bazel command line. It got further, but crashed with a different Java internal error. So that’s a failed experiment, and I’m going to proceed with pinning
.bazelversionversion to 8.1.1 for now.
エラー内容は全く同じ、その上で、8.2.0で遭遇し、そのため、8.1.1にStayしているという話。
まさか、と思いながら、.bazelversionを8.1.1に落として改めて実行すると、ビルドが始まった。
同じ8系の中では新しいものを使えない点は僅かに残念ではあるものの、当面としてはどうしても新しいバージョンで使いたい機能がない限りにおいては8.1.1で様子を見るのが良いのではないかな、と試行錯誤にあれやこれやと時間をかけた結果、達した結論。
根本原因については今のところ見つけられていないけど、8.1.1と8.2.0の間に特異点がある、のかもしれない。
-
Debian系のUnstableバージョンのこと Debian – The unstable distribution (“sid”) ↩︎