How to install and use Java 11 and JavaFX 11 on Raspberry Pi boards with ARMv6 processor
In a previous post “Installing Java and JavaFX on the Raspberry Pi”, you can read how to install BellSoft LibericaJDK to be able to run JavaFX applications with a graphical user interface on a Raspberry Pi with ARMv7 or ARMv8 processor.
But this won’t work for some (older) versions of the Raspberry Pi as these use an ARMv6 processor which is not compatible with the default OpenJDK 11 which is part of Raspberry Pi OS.
This post will guide you through the steps to have a working Java JDK and JavaFX 11 on these Raspberry Pi board versions.
Prepare a Raspberry Pi
ARMv6 Raspberry Pi board
For this post, I’m using an old Raspberry Pi B+ 1.2. To be sure which ARM-version is used, check the output of “cat /proc/cpuinfo” in the terminal:
$ cat /proc/cpuinfo
processor : 0
model name : ARMv6-compatible processor rev 7 (v6l)
BogoMIPS : 697.95
Features : half thumb fastmult vfp edsp java tls
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xb76
CPU revision : 7
Hardware : BCM2835
Revision : 0010
Serial : 000000005f9ba615
Model : Raspberry Pi Model B Plus Rev 1.2
For a clear overview of the different board- and ARM-version, check this table on Wikipedia. The boards with ARMv6 are:
- Raspberry Pi 1 A and A+
- Raspberry Pi 1 B and B+
- Compute Module 1
- Zero 1.2, 1.3 and W
Prepare SD card with Raspberry Pi OS (Full)
We start with a fresh new Raspberry Pi OS on the SD card using the “Imager” tool.
When we now boot the Rasberry Pi board with an ARMv6 processor and check the Java version we get this result:
$ java -version
Error occurred during initialization of VM
Server VM is only supported on ARMv7+ VFP
As expected, the default included OpenJDK for ARM is build for version 7 or higher, so doesn’t work on this ARMv6-based Raspberry Pi B+ 1.2.
Change the Java JDK
The sources of Java are available through the open-source project OpenJDK. So anyone can build Java JDK packages - yes you can even do it yourself! - and luckily a lot of free pre-build versions are available.
Install Java 11 for ARMv6 provided by Azul
Only Azul seems to provide an ARMv6 version with there Zulu JDK, which is available for free!
Let’s get it from their download page and extract it on our Raspberry Pi.
$ cd /usr/lib/jvm
$ sudo wget https://cdn.azul.com/zulu-embedded/bin/zulu11.41.75-ca-jdk11.0.8-linux_aarch32hf.tar.gz
$ sudo tar -xzvf zulu11.41.75-ca-jdk11.0.8-linux_aarch32hf.tar.gz
$ sudo rm zulu11.41.75-ca-jdk11.0.8-linux_aarch32hf.tar.gz
$ ls -l
total 12
lrwxrwxrwx 1 root root 21 Jul 23 15:58 java-1.11.0-openjdk-armhf -> java-11-openjdk-armhf
drwxr-xr-x 9 root root 4096 Aug 20 11:41 java-11-openjdk-armhf
drwxr-xr-x 2 root root 4096 Aug 20 11:41 openjdk-11
drwxrwxr-x 10 111 122 4096 Jul 10 16:50 zulu11.41.75-ca-jdk11.0.8-linux_aarch32hf
OK, there it is! A new JDK on our board. Now let’s configure the OS to be aware of this new one.
$ sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/zulu11.41.75-ca-jdk11.0.8-linux_aarch32hf/bin/java 1
$ sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/zulu11.41.75-ca-jdk11.0.8-linux_aarch32hf/bin/javac 1
Now we can select the new JDK so it’s linked to the “java” and “javac” command.
$ sudo update-alternatives --config java
There are 2 choices for the alternative java (providing /usr/bin/java).
Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/lib/jvm/java-11-openjdk-armhf/bin/java 1111 auto mode
1 /usr/lib/jvm/java-11-openjdk-armhf/bin/java 1111 manual mode
2 /usr/lib/jvm/zulu11.41.75-ca-jdk11.0.8-linux_aarch32hf/bin/java 1 manual mode
Press <enter> to keep the current choice[*], or type selection number: 2
update-alternatives: using /usr/lib/jvm/zulu11.41.75-ca-jdk11.0.8-linux_aarch32hf/bin/java to provide /usr/bin/java (java) in manual mode
$ sudo update-alternatives --config javac
There are 2 choices for the alternative javac (providing /usr/bin/javac).
Selection Path Priority Status
------------------------------------------------------------
* 0 /usr/lib/jvm/java-11-openjdk-armhf/bin/javac 1111 auto mode
1 /usr/lib/jvm/java-11-openjdk-armhf/bin/javac 1111 manual mode
2 /usr/lib/jvm/zulu11.41.75-ca-jdk11.0.8-linux_aarch32hf/bin/javac 1 manual mode
Press <enter> to keep the current choice[*], or type selection number: 2
update-alternatives: using /usr/lib/jvm/zulu11.41.75-ca-jdk11.0.8-linux_aarch32hf/bin/javac to provide /usr/bin/javac (javac) in manual mode
If everything went well, we should be able to check the Java version now…
$ java -version
openjdk version "11.0.8" 2020-07-14 LTS
OpenJDK Runtime Environment Zulu11.41+75-CA (build 11.0.8+10-LTS)
OpenJDK Client VM Zulu11.41+75-CA (build 11.0.8+10-LTS, mixed mode)
We have a winner! We now successfully replaced the default OpenJDK 11 (which only works on ARMv7+) with the Azul Zulu JDK which works on ARMv6.
Testing with a non-compiled Java file
Let’s try out the newly installed Java JDK. Since Java 11, we can run Java-files directly without the need to compile them. Let’s create a simple file with nano and run it.
$ cd /home/pi
$ nano HelloWorld.java
public class HelloWorld {
public static void main (String[] args) {
System.out.println("Hello World");
}
}
$ java HelloWorld.java
Hello World
Perfect! Java works as expected, but it takes about 15 seconds before the “Hello World” is shown on this old board dating from 2014.
Graphical user interfaces with JavaFX
If you also want to use JavaFX user interfaces, additional steps are needed as this library is not included in the JDK 11. It is developed as an independant open-source project on openjfx.io. The main contributor and maintainer is Gluon. They also offer commercial support to companies who want to use JavaFX for desktop and mobile application development.
Make sure you successfully updated to Azul Zulu JDK 11 before proceeding with the next steps.
Install JavaFX 11 for ARMv6 provided by GluonHQ
We are going to use the free public version provided by Gluon on their download page.
$ cd /home/pi
$ wget -O javafx.zip https://gluonhq.com/download/javafx-11-0-2-sdk-armv6hf/
$ unzip javafx.zip
$ rm javafx.zip
We can now check the JavaFX library which was unpacked in “armv6hf-sdk”:
pi@raspberrypi:~ $ ls -l
total 44
drwxr-xr-x 4 pi pi 4096 Mar 12 2019 armv6hf-sdk
drwxr-xr-x 2 pi pi 4096 Aug 20 11:40 Bookshelf
drwxr-xr-x 2 pi pi 4096 Aug 20 12:10 Desktop
...
$ ls -l armv6hf-sdk/
total 8
drwxr-xr-x 8 pi pi 4096 Mar 12 2019 legal
drwxr-xr-x 2 pi pi 4096 Mar 12 2019 lib
$ ls -l armv6hf-sdk/lib/
total 17124
-rw-r--r-- 1 pi pi 845637 Mar 12 2019 javafx.base.jar
-rw-r--r-- 1 pi pi 2761905 Mar 12 2019 javafx.controls.jar
-rw-r--r-- 1 pi pi 143926 Mar 12 2019 javafx.fxml.jar
-rw-r--r-- 1 pi pi 5270589 Mar 12 2019 javafx.graphics.jar
-rw-r--r-- 1 pi pi 294822 Mar 12 2019 javafx.media.jar
-rw-r--r-- 1 pi pi 992 Mar 12 2019 javafx.platform.properties
-rw-r--r-- 1 pi pi 113 Mar 12 2019 javafx.properties
-rw-r--r-- 1 pi pi 41802 Mar 12 2019 javafx-swt.jar
-rw-r--r-- 1 pi pi 786021 Mar 12 2019 javafx.web.jar
-rwxr-xr-x 1 pi pi 61200 Mar 12 2019 libdecora_sse.so
-rwxr-xr-x 1 pi pi 31428 Mar 12 2019 libglass_monocle.so
-rwxr-xr-x 1 pi pi 15946 Mar 12 2019 libglass_monocle_x11.so
-rwxr-xr-x 1 pi pi 200074 Mar 12 2019 libglass.so
-rwxr-xr-x 1 pi pi 22409 Mar 12 2019 libjavafx_font_freetype.so
-rwxr-xr-x 1 pi pi 20508 Mar 12 2019 libjavafx_font_pango.so
-rwxr-xr-x 1 pi pi 15206 Mar 12 2019 libjavafx_font.so
-rwxr-xr-x 1 pi pi 231402 Mar 12 2019 libjavafx_iio.so
-rwxr-xr-x 1 pi pi 43339 Mar 12 2019 libprism_common.so
-rwxr-xr-x 1 pi pi 54506 Mar 12 2019 libprism_es2_monocle.so
-rwxr-xr-x 1 pi pi 56505 Mar 12 2019 libprism_sw.so
-rw-r--r-- 1 pi pi 6598638 Mar 12 2019 src.zip
Test with a minimal JavaFX application
We are going to reuse the minimal JavaFX application which was created in this post “PiJava - Part 4 - Building a minimal JavaFX 11 application with Maven”. First, we need to clone the sources from GitHub:
$ cd /home/pi
$ git clone https://github.com/FDelporte/MinimalJavaFx11Application.git
To be able to build the application, we also need Maven to be installed.
$ sudo apt install maven
Now let’s build the application:
$ cd MinimalJavaFx11Application
$ mvn clean package
This will take some time as all the dependencies need to be downloaded.
When finished, we can now run the application with the following start command which points to the downloaded JavaFX library and the generated jar-application in the out-directory of “MinimalJavaFx11Application”:
$ sudo java --module-path /home/pi/armv6hf-sdk/lib
--add-modules=javafx.controls
-jar /home/pi/MinimalJavaFx11Application/out/MinimalJavaFx11Application-0.1-SNAPSHOT.jar
And there we have it! JavaFX running on an ARMv6 Raspberry Pi B+ 1.2!!!
Conclusion
Compared to the latest Raspberry Pi with a much faster processor and more memory, the application starts a lot slower on my 6-year old test board. But it works! Yes, really, it works :-)
Again this small-superhero-board proves to be able to handle everything, even the most modern Java versions on an old processor.
This article has also been published on “foojay.io - a place for friends of OpenJDK”