Java layer with 32bit binaries?

I have built an image using the layer FROM balenalib/raspberrypi4-64-debian-openjdk:8-jdk-stretch-run . I’m running my app from the Dockerfile with a simple java -jar myapp.jar. It starts up and runs but I’m getting an error that appears to be an incompatibility with 64bit Java. I get the following:

java.lang.UnsatisfiedLinkError: /tmp/libNRJavaSerial_root_0/libNRJavaSerial.so: /tmp/libNRJavaSerial_root_0/libNRJavaSerial.so: wrong ELF class: ELFCLASS32 (Possible cause: architecture word width mismatch)

I’m able to run the app on raspbian running directly on my Pi’s using openjdk 8 without this error. What change do I need to make to resolve this? What other info might be useful?

Hey there! I did some quick Google research, and I think the error is telling you that libNRJavaSerial is compiled as 32-bit while the OpenJDK version on the base image is 64-bit.

How are you compiling the jar? Are you re-using any previously built library?

Unfortunately it’s a third party jar, our vendor provides the compiled app. I’m fairly sure they are using a prebuilt library for serial comms though, so it tracks.

Here’s the version output from the Pi running bare debian and openjdk:

openjdk version "1.8.0_212"
OpenJDK Runtime Environment (build 1.8.0_212-8u212-b01-1+rpi1-b01)
OpenJDK Client VM (build 25.212-b01, mixed mode)

And from the debian container on the Pi running balenaOS:

openjdk version "1.8.0_232"
OpenJDK Runtime Environment (build 1.8.0_232-8u232-b09-1~deb9u1-b09)
OpenJDK 64-Bit Server VM (build 25.232-b09, mixed mode)

So frankly I’m not smart enough to understand the difference between openjdk 64bit server and openjdk client vm. Is there just a package I need to install in the Dockerfile, combined with an update-alternatives?

The base image that you are using is Debian based and its installing the JDK from the official sources: https://github.com/balena-io-library/base-images/blob/master/balena-base-images/openjdk/raspberry-pi/debian/stretch/8-jdk/run/Dockerfile#L46.

How does that Dockerfile compare with the Debian Pi that you successfully ran this on? Could it be that you were using 32-bit Debian there?

So I’m not sure if this makes a big difference but the non-balena Pi is running Raspbian 10, whereas the container is Debian 9. I can’t imagine that makes a big difference, but maybe it does?

I noticed the Buster image for balena only has Java 11 available, but if that’s the lynch pin here then I could use the buster image and just install Java from my Dockerfile instead of relying on the image.

I noticed the Buster image for balena only has Java 11 available, but if that’s the lynch pin here then I could use the buster image and just install Java from my Dockerfile instead of relying on the image.

I’m not super familiar with Java, but that sounds worth trying

Ok so this is a bit hackey, but after trying several things the ultimate “fix” was to just use balenalib/raspberrypi3-debian-openjdk:8-jdk-stretch-run .

There may be some way to force 32bit Java 8 onto aarch64 but I think it’s easier to do it this way.

Oddly enough, Raspbian built for the Pi4 does use an arm7 build of Debian.

Good to see you got it working :). Update us if you need anything else.

1 Like