Patching the JVM to work with native libraries on aarch64 systems

Originally posted on 2020-10-23

I was recently running a Java application on an aarch64 system with Alpine Linux that needed to load a native library. Unfortunately for me the system is using musl libc and the library requires glibc.

I installed gcompat thinking it would magically fix it but it didn't. I dug deeper and figured out that my Java needed a quick mod to get it to use the gcompat layer.

scanelf says Java is using musl and therefore gcompat won't be able to intercept it:

$ scanelf -i /usr/bin/java
TYPE   INTERP                    FILE
ET_DYN /lib/ld-musl-aarch64.so.1 /usr/bin/java

gcompat's site says we need to use PatchELF in this case. So here's what we do...

Get some packages to build PatchELF:

apk add git autoconf automake gcc g++ make

Get PatchELF:

git clone https://github.com/NixOS/patchelf.git

Build and install it (NOTE: --disable-dependency-tracking may not be necessary on all platforms):

cd patchelf
./bootstrap.sh
./configure --disable-dependency-tracking
make
make check
make install

Patch Java:

patchelf --set-interpreter /lib/ld-linux-aarch64.so.1 /usr/bin/java

scanelf shows it was updated:

$ scanelf -i /usr/bin/java
TYPE   INTERP                     FILE
ET_DYN /lib/ld-linux-aarch64.so.1 /usr/bin/java

And now Java works with the native library. Great!