B4J Question How to set a systemd (linux) watchdog ping in B4J

aminoacid

Active Member
Licensed User
Longtime User
How would you execute:

sd_notify (0, "WATCHDOG=1");

in B4J to ping the systemd watchdog timer?

I am running a B4J server application as a systemd service and would like to setup a watchdog timer to restart the service if it hangs. I have setup the service unit properly with the "WatchdogSec=" set to the interval I need. I just need to find a way to ping the systemd watchdog timer in my application without have to resort to using "Shell" and the "systemd-notify" command.

I assume there may be a way to call "sd_notify" using the javaobject library but am not very familiar with using it.

Appreciate any input. Thanks!
 

aminoacid

Active Member
Licensed User
Longtime User
The server should never hang. I'm running many B4J servers and they can run for years without any problem.

sd_notify is not a Java command and cannot be accessed with JavaObject. You will either need to find a library that uses jni to call it or use jShell.

Just to clarify ... the server does not hang - it works perfectly. The issue is that the Application accesses an external USB device for data every 10 seconds and very occasionally will become unresponsive because of some issue with the USB driver. Restarting the service cures the problem. Since a driver fix is not possible and the issue happens very rarely, I wanted to implement a watchdog timer using the capabilities of "systemd".

I managed to get it working using jShell and the "systemd-notify" command and am posting my code below in case anyone would find it useful. However due to a known problem with "systemd-notify" ( see: https://stackoverflow.com/questions...g-timeout-in-systemd-notify/36992645#36992645 ) the service will restart due to inconsistent timeouts from the watchdog. So far I have not encountered that but you may want to keep an eye open for that possibility.

The ideal and most elegant solution is to use sd_notify() which I believe can be done using JNA (mentioned in the same link given above). However my familiarity with Java is very limited especially when it comes to interfacing it with B4J.

Here is the code I used which works:

Ping the systemd watchdog timer:
Sub PingWatchDog
    Private shl As Shell
    shl.Initialize("shl","systemd-notify",Array As String("WATCHDOG=1"))
    shl.Run(-1)
    Wait For shl_ProcessCompleted(Success As Boolean, ExitCode As Int, StdOut As String, StdErr As String)
End Sub

Here are the settings for the service unit:

B4X:
[Unit]
Description=WatchDog Test mainservice
StartLimitIntervalSec=0

[Service]
WorkingDirectory=/home/pi
ExecStart=/opt/jdk/jdk1.8.0_241/bin/java -jar /home/pi/WatchDog.jar
Type=notify
NotifyAccess=all
Restart=on-failure
RestartSec=1
WatchdogSec=20
# Must have if using Type=notify, otherwise not needed
TimeoutSec=0

[Install]
WantedBy=multi-user.target

"Type=simple" will also work and if you use that, you don't need "TimeoutSec=0"
 
Last edited:
Upvote 0
Top