Running Vaadin Flow as systemd service

@Matti in a tutorial

used systemctl without sudo so I presume Matti was running it as admin.
I am trying to run an Installbuilder install as a user and having a problem with the DISPLAY env variable.
To do this I have a script

#!/bin/bash

sudo -S <<< $1 cp /home/paulf/QNE/install/qne.service /etc/systemd/system/qne.service
sudo systemctl start qne.service

# sudo systemctl enable qne.service 

# sudo systemctl daemon-reload

When I run this script the service runs but when I try to browse to a view

java.awt.AWTError: Can't connect to X11 window server using ':0.0' as the value of the DISPLAY variable.

The service unit is

[Unit]
Description=QNE Spring Boot application
After=syslog.target

[Service]
User=paulf
ExecStart=/home/paulf/QNE/install/jdk-21.0.2/bin/java --enable-preview -jar /home/paulf/QNE/install/qne.jar
SuccessExitStatus=143
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

If I just run

/home/paulf/QNE/install/jdk-21.0.2/bin/java --enable-preview -jar /home/paulf/QNE/install/qne.jar

it works OK.

Any clues how to run Vaadin Flow as systemd service or comments on the above much appreciated.

1 Like

Two things come in mind:

  • the auto generating favicon might be the culprit; remove that by adding your own with correct resolutions (dynamic file creations is always bad)
  • try to add -Djava.awt.headless=true and -Dserver to the java process (preferable in an environment file)
1 Like

@knoobie Thanks for your reply.
I have no idea why you might suspect the favicon. A pointer to some background info as to why “dynamic file creations” might interfere with systemd would be very helpful.
Also, why would java.awt.headless be set to true when it is not a headless setup?

I am investigating the systemd user facility which may be an alternative approach that might work. systemd/User - ArchWiki

I’m not sure why and how it interferes my knowledge about AWT is quite limited; but I’ve seen that it does - therefore my suggestion to alter your setup by either removing the need for PWA to create the files and/or apply the mentioned flag.

Flow is creating the files for PWA with AWT APIs flow/flow-server/src/main/java/com/vaadin/flow/server/PwaIcon.java at f722b0afc8b4bedb275f1de1516d7ab22dc78979 · vaadin/flow · GitHub

Solved.
Systemd/user using this unit file works.
The secret being the Environment entry that ensures that the DISPLAY variable is set early in the linux startup process.

[Unit]
Description=QNE Spring Boot application

[Service]
Type=simple
Environment="DISPLAY=:0"
ExecStart=/home/paulf/QNE/install/jdk-21.0.2/bin/java --enable-preview -jar /home/paulf/QNE/install/qne.jar
SuccessExitStatus=143
Restart=always
RestartSec=5

[Install]
WantedBy=default.target
4 Likes

Good that it is solved!

I was still thinking about this:

why would java.awt.headless be set to true when it is not a headless setup?

Since Vaadin applications are client-server applications (= Java web server and a web browser), the server actually is “headless” and only the browser needs the DISPLAY to be set. That is why having -Djava.awt.headless=true usually helps to start the server.

The web browser is running as separate process and environment and if you are starting that also as system service, it will need the display (ok, you can run browsers as headless too), but based on the error that was not the case.