B4J Tutorial Raspberry Pi B4J UI Applications with Liberica JDK

Tutorial Raspberry Pi B4J UI Applications with Liberica JDK v20180513

To build B4J UI applications, using the Liberica JDK10, running on the Raspberry Pi.
This tutorial covers setup of the Raspberry Pi, Liberica, development hints and few sample applications.

NOTE 20190406
Since Java 11 is available, recommend this thread https://www.b4x.com/android/forum/threads/raspberry-pi-with-java-11.99606/ instead using Liberica JDK10.

The B4J UI applications have been tested with:
* Raspberry Pi 3B+ with HDMI connected monitor Philips 223V
* Raspberry Pi 2Bv1.1 with 7" touchscreen display

Especially the 7" touchscreen solution is interesting, i.e. Information Display, Dashboards, Control GPIO and the likes.

Prototype with 7" touchscreen running the CPU-Temperature-Dashboard sample application.

Screenshot of the prototype with 7" touchscreen running the HomeAutomation-Dashboard sample application.

For the shown sample applications, the jGauges library (@Erel) and the xChart class (@klaus) are used. Many thanks to the authors.

Liberica Information
As taken from here, Liberica is a 100% open-source Java 10 implementation for Raspberry Pi.
It is built from the OpenJDK to which BellSoft contributes. Recommend to read the release notes.
The source is on GitHub.

Raspberry Pi 3B+ with HDMI connected monitor Philips 223V
Raspberry Pi 2 with 7" Touchscreen Display

Raspberry Pi Raspbian Stretch (Linux raspberrypi 4.14.30-v7+ #1102 SMP Mon Mar 26 16:45:49 BST 2018 armv7l).
B4J v6.01
Liberica JDK 10
Note: Newer software versions might be available after writing this tutorial.

Raspberry Pi Setup
For the testing, installed the latest, at the time of developing, Raspberry Pi NOOBS.
Configuration Modifications
Increase the GPU Memory: Menu Preferences > Raspberry Pi Configuration > Tab Performance > Field GPU Memory: 512.

Disable Monitor Sleep
sudo nano /etc/lightdm/lightdm.conf
Add the following lines to the [Seat*] section:
# Disable monitor sleep
xserver-command=X -s 0 dpms

Prior Liberica installation run an Raspberry Pi software upgrade and update:
sudo apt-get update && sudo apt-get upgrade

Liberica Installation
On the Raspberry Pi, open a terminal, login as user pi and execute next steps.
// Create a folder java to store the downloads.
mkdir /home/pi/java
// Set the created java folder as default
cd /home/pi/java
// Download the Liberica JDK10 package from BellSoft
// Note: This example shows JDK10. In the mean time there might be newer versions, i.e. JDK10.0.1.
wget https://github.com/bell-sw/Liberica/releases/download/10/bellsoft-jdk10-linux-arm32-vfp-hflt.deb
Logging information snippet ...
--2018-04-18 09:33:42--  https://github.com/bell-sw/Liberica/releases/download/10/bellsoft-jdk10-linux-arm32-vfp-hflt.deb
Saving to: ‘bellsoft-jdk10-linux-arm32-vfp-hflt.deb’
bellsoft-jdk10-linu 100%[===================>] 209.58M   752KB/s    in 4m 48s
2018-04-18 09:38:31 (745 KB/s) - ‘bellsoft-jdk10-linux-arm32-vfp-hflt.deb’ saved [219758630/219758630]
// Install the Liberica JDK10 package
sudo apt install ./bellsoft-jdk10-linux-arm32-vfp-hflt.deb
// Check the installed java and javac versions
java -version
resulting in: java version "1.8.0_162"
javac -version
resulting in: javac 1.8.0_162
// Set the right javac version (compiler)
// The list of javac options depends on the installed java versions.
// Note: Prior using the Liberica JDK (BellSoft) tested also the jdk8.0_161/162.
$sudo update-alternatives --config javac
There are 4 choices for the alternative javac (providing /usr/bin/javac).
  Selection    Path                                                   Priority   Status
  0            /usr/lib/jvm/jdk-10-bellsoft-arm32-vfp-hflt/bin/javac   1902      auto mode
  1            /opt/jdk1.8.0_161/bin/javac                             1         manual mode
* 2            /opt/jdk1.8.0_162/bin/javac                             1         manual mode
  3            /usr/lib/jvm/jdk-10-bellsoft-arm32-vfp-hflt/bin/javac   1902      manual mode
  4            /usr/lib/jvm/jdk-7-oracle-arm-vfp-hflt/bin/javac        317       manual mode
Press <enter> to keep the current choice[*], or type selection number: 3
update-alternatives: using /usr/lib/jvm/jdk-10-bellsoft-arm32-vfp-hflt/bin/javac to provide /usr/bin/javac (javac) in manual mode
// Set the right java version (runtime)
// The list of options depends on the installed java versions.
$sudo update-alternatives --config java
There are 4 choices for the alternative java (providing /usr/bin/java).
  Selection    Path                                                  Priority   Status
  0            /usr/lib/jvm/jdk-10-bellsoft-arm32-vfp-hflt/bin/java   1902      auto mode
  1            /opt/jdk1.8.0_161/bin/java                             1         manual mode
* 2            /opt/jdk1.8.0_162/bin/java                             1         manual mode
  3            /usr/lib/jvm/jdk-10-bellsoft-arm32-vfp-hflt/bin/java   1902      manual mode
  4            /usr/lib/jvm/jdk-7-oracle-arm-vfp-hflt/jre/bin/java    317       manual mode
Press <enter> to keep the current choice[*], or type selection number: 3
update-alternatives: using /usr/lib/jvm/jdk-10-bellsoft-arm32-vfp-hflt/bin/java to provide /usr/bin/java (java) in manual mode
// Check the java and javac versions again = should be the BellSoft java 10 versions
$javac -version
javac 10-BellSoft
$java -version
openjdk version "10-BellSoft" 2018-03-20
OpenJDK Runtime Environment (build 10-BellSoft+0)
OpenJDK Server VM (build 10-BellSoft+0, mixed mode)
The downloaded deb file is not required anymore and can be deleted to freeup space.

Liberica Installation Folder
The Liberica JDK is installin folder: /usr/lib/jvm/jdk-10-bellsoft-arm32-vfp-hflt
Recommend to read the file readme.txt. The file release contains release version and module information.

Setup Hints
Performance GPU Memory

To state again = ensure to set the Raspberry Pi GPU memory from default 64 to at least 256 or 512.
If not the case, then a memory glGetError occurs:
Memory Error glGetError 0x505 or the B4J IDE Logs, like
  at com.sun.prism.impl.ps.PaintHelper.initGradientTextures(PaintHelper.java:131)
  at com.sun.prism.impl.ps.PaintHelper.getGradientTexture(PaintHelper.java:141)
Be carefull using resources, i.e. a Label with a Big Font size consumes high amount of GPU memory.

Error Message Failed to write to /sys/class/input/mice/uevent
Udev: Failed to write to /sys/class/input/mice/uevent – Check that you have permission to access input devices
This message occurs when executing a JavaFX application on a Raspberry Pi using a user other than root, i.e. user pi.

JavaFX requires direct write access to device hardware.

Solution Option 1
Execute the application as sudo, i.e. sudo java -jar myjavafxapp.jar

Solution Option 2
Modify settings to grant write access to the devices all users that belongs to the input group.
Edit the 99-com.rules file:
$sudo nano /etc/udev/rules.d/99-com.rules
Add at the bottom:
SUBSYSTEM=="input*", PROGRAM="/bin/sh -c '\
 chown -R root:input /sys/class/input/*/ && chmod -R 770 /sys/class/input/*/;\
Run the application without root: java -jar myjavafxapp.jar

Application Test - B4J-Bridge
To test the application developed on a device, i.e. Windows 10 PC, use the B4J Bridge.
by creating a B4J folder, set as default, delete any previous versions, then download the B4J-Bridge:
mkdir /home/pi/b4j
cd /home/pi/b4j         
rm b4j-bridge.jar
wget https://www.b4x.com/b4j/files/b4j-bridge.jar

Alternative to wget
Transfer (via f.e. WinSCP) the B4J-Bridge from a development device to the RPi folder /home/pi/b4j.

To run as root (do not forget esp, when using Pi4j) when logged in as user Pi:
sudo <path to java> -jar b4j-bridge.jar

If the path to java is set in the environment path, then call
sudo java -jar b4j-bridge

It is useful to run the B4J-Bridge from a dedicated terminal, like f.e. from the development device using Putty.
When doing so, the output of the running application can be watched.

Application Test - Full Screen Mode
On the Raspberry Pi, the JavaFX application runs in Full Screen Mode and captures all Linux input devices.
When using VNC, the application is not visible - only on the monitor connected to the Raspberry Pi.
There is no titlebar for forms & dialogs and Control-C is not working, means has to be catered for in the application.

Autostart the B4J UI Application at Boot
As an example application jar: dashboard.jar located in folder /home/pi/b4j

Bash Script
Create a bash script dashboard.sh in folder /home/pi/b4j
sudo nano dashboard.sh
cd /home/pi/b4j
sudo java -jar dashboard.jar
Make the bash script executable:
sudo chmod +x dashboard.sh

Edit autostart
nano ~/.config/lxsession/LXDE-pi/autostart
add at file end:
Resulting in example:
@lxpanel --profile LXDE-pi
@pcmanfm --desktop --profile LXDE-pi
@xscreensaver -no-splash

... and reboot the Raspberry Pi to test if working.

B4J UI Application Development Hints
Merge Libraries
When using additional libraries (i.e. Pi4J, SQLite ...), set the Project Attribute MergeLibraries:True.
Example for a SQLite driver which is set by using a Conditional Symbol:
#Region Project Attributes
   #MainFormWidth: 1000
   #MainFormHeight: 800
   ' SQLite driver - located in the B4J core libraries folder - ensure to set the correct version
   #If PC
       #AdditionalJar: sqlite-jdbc-3.7.2
       #AdditionalJar: sqlite-raspberry.jar
   #End If
   #MergeLibraries: True
   ' #CommandLineArgs: -l
#End Region

Application Close
In the B4J application, ensure to implement a close button to exit the application as the generated application has not titlebar.
Example of using a Close Button at the form bottom right and a Close [X] Button at the top right.
Sub Process_Globals
   Private btnClose As Button
   Private btnCloseX As Button

Sub AppClose
End Sub

' Close the app using X Button top right corner
Sub btnCloseX_Action
End Sub

' Close the app using close button bottom right
Sub btnClose_Action
   fx.Msgbox(MainForm, "Hello World", "Information")
End Sub

The fx.MsgBox is displayed without titlebar and borders. The background color is white.
Instead using the fx message boxes, consider to build an own class with a message box having a titlebar and other options.

To make a snapshot of a form, the jfxrt.jar (i.e. from JDK8) is required and must be added to the B4J additional libraries folder.
'Make a snapshot of the mainform. The png file is stored in the dirapp folder.
'Requires #AdditionalJar: jfxrt with jfxrt.jar located in the B4J additional libraries folder
Sub FormSnapShot   'ignore
   Dim img As Image = MainForm.RootPane.Snapshot
   Dim Out As OutputStream = File.OpenOutput(File.DirApp, "snapshot.png", False)
End Sub
Use the conditional snapshot to enable snapshots
#Region Project Attributes
   'Set the conditional snapshot to enable snapshots
   #If snapshot
       'The jar jfxrt is required for the class SwingFXUtils to make a screenshot of the mainform when running on the RPi.
       'This to avoid runtime error: java.lang.NoClassDefFoundError: javafx/embed/swing/SwingFXUtils
       'Copy c:\Program Files (x86)\Java\jdk8\jre\lib\ext\jfxrt.jar to the B4J additional libraries folder.
       'Note: Check your JDK path prior copying to the B4J additional library folder.
       #AdditionalJar: jfxrt
   #End If
#End Region
Sub AppClose_Action
   #If snapshot
   #End If
End Sub

Maximize Screen
As mentioned, the application runs in full screen.
When setting the Project Attributes MainFormWidth and MainFormHeight to a certain value, which is smaller then the full screen size, the form is displayed as sub window from the full screen.
Recommend to set the form to full screen.
Example sub routine setting to full screen with an offset.
The offset was used to handle an openJDK error, where the cursor disappears when moving to the far right of the form. In newer JDK versions, this error did not show up anymore.
' Set the form to fill the screen with an offset
Sub SetFormFillScreenOffset(frm As Form, offset As Int)   'ignore
   Dim ps As Screen = fx.PrimaryScreen
   frm.WindowLeft = ps.MinX + offset
   frm.WindowWidth = ps.MaxX - frm.WindowLeft - offset
   frm.WindowTop = ps.MinY + offset
   frm.WindowHeight = ps.MaxY - frm.WindowTop - offset
End Sub
'Set the form to fill the screen with an offset - comment if want to use the window dimensions defined in the project attributes
SetFormFillScreenOffset(MainForm, 50)

Java Version
If want to know or display the Java version on the Raspberry Pi:
Private lblStatus As Label
lblStatus.Text = $"Java ${GetSystemProperty("java.version","0.0.0_00")}"$

Raspberry Pi 7" Touchscreen
The sample applications have been tested esp. on the Raspberry Pi 7" touchscreen with dimensions 800*480.
In the B4J Visual Designer, defined a new Variant 800*480,scale=1 (160dpi).
Layout used for the samples:
[Top Pane [Label Title][Button CloseX] ]
[Bottom Pane [Label Info][Button Close] ]
View Properties
Top Pane=Parent:Main,Hor Anchor:Both,Ver Anchor:Top,Left:5,Top:5,Right:5,Height:50
Label Title=Parent:Top Pane,Hor Anchor:Both,Ver Anchor:Both,Left:10,Top:10,Right:10,Bottom:10
Button CloseX:Parent:Top Pane,Hor Anchor:Right,Ver Anchor:Both,Right:10,Top:0,Width;50,Bottom:0. Used Fontawesome close icon Chr(0xF2D4) with size 18.
Bottom Pane=Parent:Main,Hor Anchor:Both,Ver Anchor:Bottom,Left:5,Top:5,Right:5,Height:50
Label Info=Parent:Bottom Pane,Hor Anchor:Both,Ver Anchor:Both,Left:10,Top:10,Right:10,Bottom:10
Button CloseX:Parent:Bottom Pane,Hor Anchor:Right,Ver Anchor:Both,Right:20,Top:10,Width;100,Bottom:10

Application Samples
Build a few sample B4J UI applications - B4J source code attached.
As mentioned, tested the samples esp. with the 7" touchscreen.

IMPORTANT: For tests, please check if the conditional symbol snapshot is set and take out as required - used for making snapshots.

01-HelloWorld - The classic one to start with
02-LEDSwitch - Switch an LED connected to GPIO ON/OFF
03-LCDClock - Simple label showing time
04-Look4HowViewer - View Look4How databases (only source, no libs and database)
06-CPU-Temperature-Dashboard - Display & log the Raspberry CPU temperature (Gauge)
07-HomeAutomationDashboard - Weather information displayed in Gauges and logged in a listview on a 7" touchscreen
99-WebView - Currently not supported by Liberica JDK v10. Awaiting update information.



  • B4JHowToRPiLiberica.zip
    189.4 KB · Views: 506
Last edited:


Licensed User
Great got them - thanks

I just tried the LCDClock worked fine, however the CPU-Temp compiles and downloads ok, on the Pi 3b+ the program starts - screen goes blank (Monitor) and then returns saying ProcessCompleted - nothing else.
The GPU is at 512, using Stretch Linux version 4.14.32v7

Using the latest version of B4J

Any ideas ?

Attached are the returned Error messages of B4J, version 6.30


  • error.png
    42.1 KB · Views: 499
Last edited:


Licensed User
That did not help

main._appinit (java line: 101)
java.lang.NumberFormatException: For input string: "0xccccccff"
at java.base/jdk.internal.math.FloatingDecimal.parseHexString(FloatingDecimal.java:2082)
at java.base/jdk.internal.math.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1870)
at java.base/jdk.internal.math.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.base/java.lang.Double.parseDouble(Double.java:543)
at anywheresoftware.b4a.BA.ObjectToNumber(BA.java:394)
at b4j.example.main._appinit(main.java:101)
at b4j.example.main._appstart(main.java:129)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:90)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:77)
at b4j.example.main.s
at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:919)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$11(PlatformImpl.java:449)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$9(PlatformImpl.java:418)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:417)
at javafx.graphics/com.sun.glass.ui.monocle.RunnableProcessor.runLoop(RunnableProcessor.java:92)
at javafx.graphics/com.sun.glass.ui.monocle.RunnableProcessor.run(RunnableProcessor.java:51)
at java.base/java.lang.Thread.run(Thread.java:844)

I get the above back in Logs


Well-Known Member
Licensed User
Checked the application again (B4J v6.30, java 10.0.1 bellsoft, Linux raspberrypi 4.14.34-v7+ #1110, RPi 3B+) and is running ok:

Looking at the error in post #6, seems (but not sure) this setting (in AppInit) is causing the issue (checked the source in the created main.java):
' xChart - do not use transparent as background color because lines are not displayed correct
 xChart_CPUTemperature.ChartBackgroundColor = fx.Colors.LightGray
' converted to
_xchart_cputemperature._setchartbackgroundcolor((anywheresoftware.b4j.objects.JFX.PaintWrapper) anywheresoftware.b4a.AbsObjectWrapper.ConvertToWrapper(new anywheresoftware.b4j.objects.JFX.PaintWrapper(), (javafx.scene.paint.Paint)(_fx.Colors.LightGray)));

Suggest to take a step back and try, with the B4J Bridge running, step-by-step

1) Ensure the conditional snapshot is not set (Menu Project > Build Configurations)

2) Create a minimal Sub AppInit to check if the layout is working. The timer is disabled.
The appinit in the example is used to init the datapoints, set label text, make styling changes, init the timer to read the CPU temperature.
Sub AppInit
    Timer_Dashboard.Initialize("Timer_Dashboard", Timer_DashboardInterval)
    Timer_Dashboard.Enabled = False
End Sub

The gauge is visible but the chart not as no datapoints.

3) Use the minimal AppInit again with the timer enabled.
Sub AppInit
    Timer_Dashboard.Initialize("Timer_Dashboard", Timer_DashboardInterval)
    Timer_Dashboard.Enabled = True
End Sub

This will show the gauge and the chart with datapoints (the timer is set to 1 minute, but for test change to 5 seconds to get faster response).

4) Enhance the AppInit with styling for the gauge but NOT for the line chart.
Sub AppInit
 Gauge_SetBarColor(Gauge_CPUTemperature, fx.Colors.Red)
 Gauge_SetTitle(Gauge_CPUTemperature, "CPU")
 Gauge_SetUnit(Gauge_CPUTemperature, "°C")
 Gauge_SetValueColor(Gauge_CPUTemperature, fx.Colors.Blue)
 Gauge_SetKnobColor(Gauge_CPUTemperature, fx.Colors.yellow)
 Timer_Dashboard.Initialize("Timer_Dashboard", Timer_DashboardInterval)
 Timer_Dashboard.Enabled = True
End Sub

5) Enhance the AppInit with additional styling for the chart.
Sub AppInit2
 Gauge_SetBarColor(Gauge_CPUTemperature, fx.Colors.Red)
 Gauge_SetTitle(Gauge_CPUTemperature, "CPU")
 Gauge_SetUnit(Gauge_CPUTemperature, "°C")
 Gauge_SetValueColor(Gauge_CPUTemperature, fx.Colors.Blue)
 Gauge_SetKnobColor(Gauge_CPUTemperature, fx.Colors.yellow)
 xChart_CPUTemperature.ChartBackgroundColor = fx.Colors.LightGray
 Timer_Dashboard.Initialize("Timer_Dashboard", Timer_DashboardInterval)
 Timer_Dashboard.Enabled = True
End Sub

Lets see how these steps work out.
Last edited:


Well-Known Member
Licensed User
Hi rwblinn
can you try to develop small B4J UI program for set time (and date) on a raspberry with RTC on board?
I with Openjfx 8u62 and java1.51 have problem.
I use a shell command for send formatted string to raspy but it's lock the device.
If i reboot the device however, the correct date and time was written.
If i send the same string in a ssl session with putty work well.
Last edited:


Licensed User
Hi rwblinn

Sorry for the delay in getting back to you - I did as you suggested - all was good until I added the last line back to the AppInit - I can also run it with debug (no errors) chart populates, but as soon as I introduce that line (in either mode) i get the ProcessCompleted msg on the Pi and in B4J - debug closes with the same error messages (#6) in Logs.

I'm using xChart 1.5 (2018.05.21) - just an FYI


Active Member
Licensed User
Can we run ui apps under X window? Oracle java does not support javafx on arm devices. I tried gluon and openjfx, not perfect.


Well-Known Member
Licensed User
Trying to install java, it spits out a ton of selecting blah blah blah, and then not found blah blah blah and aborts the installation. any ideas?


Licensed User
It runs in Raspberry pi, but:
1.- numeric keyboard don't respond
2.- mouse pointer change to square black...
any clue?


Licensed User
I tried to get this working today but the app started without any errors but nothing was visible.

As mentioned in your initial post rendering is done to the main gpu and SPI based LCD screens can't seem to capture this.

Attaching a hdmi monitor to it resulted in a black screen with the hello world form on top of it!

So I guess I need an LCD screen that uses this flat wire connection to make this work?


Licensed User
unable to install
// Install the Liberica JDK10 package
sudo apt install ./bellsoft-jdk10-linux-arm32-vfp-hflt.deb

it is giving
t found
> E: Release 'bellsoft-jdk10-linux-arm32-vfp-hflt.deb' for 'pi-greeter' was not found
> E: Release 'bellsoft-jdk10-linux-arm32-vfp-hflt.deb' for 'piclone' was not found
> E: Release 'bellsoft-jdk10-linux-arm32-vfp-hflt.deb' for 'pimixer' was not found
> E: Release 'bellsoft-jdk10-linux-arm32-vfp-hflt.deb' for 'pipanel' was not found
> E: Release 'bellsoft-jdk10-linux-arm32-vfp-hflt.deb' for 'pishutdown' was not found
> E: Release 'bellsoft-jdk10-linux-arm32-vfp-hflt.deb' for 'pix-icons' was not found
> E: Release 'bellsoft-jdk10-linux-arm32-vfp-hflt.deb' for 'pix-plym-splash' was not found
> E: Release 'bellsoft-jdk10-linux-arm32-vfp-hflt.deb' for 'pixel-wallpaper' was not found
> E: Release 'bellsoft-jdk10-linux-arm32-vfp-hflt.deb' for 'point-rpi' was not found
> E: Release 'bellsoft-jdk10-linux-arm32-vfp-hflt.deb' for 'rc-gui' was not found
> E: Release 'bellsoft-jdk10-linux-arm32-vfp-hflt.deb' for 'rpi-chromium-mods' was not found

Please help