Today, I want to talk about how to create a Systemd unit file for Java program.
Unit File Structure
Unit files typically consist of three sections:
- [Unit] — contains generic options that are not dependent on the type of the unit. These options provide unit description, specify the unit’s behavior, and set dependencies to other units.
- [unit type] — if a unit has type-specific directives, these are grouped under a section named after the unit type. For example, service unit files contain the [Service] section.
- [Install] — contains information about unit installation used by
systemctlenable and disable commands.
Service Unit File Sample
Here’s the Systemd unit file
gitty.service that I’ve created:
[Unit] Description=Gitty Server [Service] ExecStart=/usr/bin/java \ -Dgitty.basePath='/opt/gitty/repositories' \ -Dgitty.bindAddr='0.0.0.0' \ -Dgitty.bindPort='18080' \ -Dgitty.hostName='kira' \ -jar '/opt/gitty/gitty-server.jar' SuccessExitStatus=143 [Install] WantedBy=multi-user.target
In this sample, several options are defined. Let’s take a look together:
Descriptionis a meaningful description of the unit. This text is displayed for example in the output of the
ExecStartspecifies commands or scripts to be executed when the unit is started.
ExecStartPostspecify custom commands to be executed before and after
ExecStart. Note that execution requires absolute path for command, you need to specify /usr/bin/java instead of java.
ExecStopspecifies commands or scripts to be executed when the unit is stopped. If not specified, the basic way for systemd to stop a running service is by sending the
SIGTERMsignal (a regular
kill) to the process control group of the service, and after a configurable timeout, a
SIGKILLto make things really go away if not responding. As for Java application, the JVM process is setup so that it gracefully shuts down the service upon reception of the
SIGTERMsignal using shutdown hooks. However, the JVM will still exit with code
143in the end due to receiving
SIGTERM. Modify systemd success status to
WantedByis a list of units that weakly depend on the unit. When this unit is enabled, the units listed in
Wantdependency on the unit.
Create the Systemd Unit File
The systemd unit file
name.service needs to be created in
directory /etc/systemd/system and have 644 permission as root. Note that
it does not need to be executable. You need to fill options as I did in the
Once done, notify systemd that a new
name.service file is
created by reloading the daemon as root:
After that, you can either testing the service startup using command
systemctl start name.service (the suffix
.service can be
omitted), or enable the service startup using command
name.service. You can also check the status of the service using
systemctl status name.service.
systemctl start name.service systemctl enable name.service systemctl status name.service
JAR File Accessibility
Jul 03 21:29:00 mincong-KIRA-102 java: Error: Unable to access jarfile /home/mincong/.m2/repository/gitty/gitty-server/1.0-SNAPSHOT/gitty-server-1.0-SNAPSHOT-jar-with-dependencies.jar
The JAR file is not accessible from Systemd as
root. Move the JAR file to
another directory owned by
root, such as
Service Failed to Start
jps- JVM Process Status Tool to check whether the process is started.
- See the log in
journalctl, to understand what happened
- See the status of target service
systemctl status name.service. Understand its status, its exit-code, the environment variables, the related log trace etc.
Using symbolic link for Systemd unit file might cause problem during the service enabling. I suggest to use regular file directly.