You are specifying a user in your .service file, hence you should not need to do any of the su magic in your script.

Replace this:

su -s /bin/sh $user -c "cd /app/myworkingdir ; java -jar myjar.jar >> /var/log/systemout.log 2>> /var/log/systemerr.log"

with this:

cd /app/myworkingdir
java -jar myjar.jar >> /var/log/systemout.log 2>> /var/log/systemerr.log"

Besides, I see two further issues in your script:

  • You are grepping the process table to find the PID for your service. This may fail if there is another running process with a command line that contains the same characters (the system may end up picking the wrong process to terminate). echo pid_file right after launching java is a safer way of accomplishing this.

  • The service type is simple, yet your script forks it as a separate process and then returns. This will confuse systemd, and your service will fail to start.

Both of these might be easy to solve. I assume you need the PID only to stop the service, and doing so is as simple as sending it a SIGINT. In that case you can take advantage of the fact that, in the absence of ExecStop, systemd will simply send a SIGINT to the service process to stop it.

  • Drop the ampersand after the java call, and prefix it with exec instead. That way, the java process becomes will be treated as the daemon process by systemd.

  • Drop the PID magic after the java call altogether.

  • In the .service file, remove the ExecStop entry.

  • Instead, also under [Service], add SuccessExitStatus=143. (When terminated with a signal, the JVM will exit with a nonzero exit status, namely 128 plus the signal. By default, systemd treats an exit status of 143 as a failure; this entry will tell systemd that 143 stands for graceful exit.)

You could take this one step further and drop the script altogether:

  • Specify the java command line as ExecStart
  • Pass the full path to the java binary (as reported by which java)
  • Drop the redirections: by default, systemd will redirect stdout and stderr to the journal. (This can be configured in the .service file as well.)
Answer from user149408 on Stack Overflow
Top answer
1 of 1
6

You are specifying a user in your .service file, hence you should not need to do any of the su magic in your script.

Replace this:

su -s /bin/sh $user -c "cd /app/myworkingdir ; java -jar myjar.jar >> /var/log/systemout.log 2>> /var/log/systemerr.log"

with this:

cd /app/myworkingdir
java -jar myjar.jar >> /var/log/systemout.log 2>> /var/log/systemerr.log"

Besides, I see two further issues in your script:

  • You are grepping the process table to find the PID for your service. This may fail if there is another running process with a command line that contains the same characters (the system may end up picking the wrong process to terminate). echo pid_file right after launching java is a safer way of accomplishing this.

  • The service type is simple, yet your script forks it as a separate process and then returns. This will confuse systemd, and your service will fail to start.

Both of these might be easy to solve. I assume you need the PID only to stop the service, and doing so is as simple as sending it a SIGINT. In that case you can take advantage of the fact that, in the absence of ExecStop, systemd will simply send a SIGINT to the service process to stop it.

  • Drop the ampersand after the java call, and prefix it with exec instead. That way, the java process becomes will be treated as the daemon process by systemd.

  • Drop the PID magic after the java call altogether.

  • In the .service file, remove the ExecStop entry.

  • Instead, also under [Service], add SuccessExitStatus=143. (When terminated with a signal, the JVM will exit with a nonzero exit status, namely 128 plus the signal. By default, systemd treats an exit status of 143 as a failure; this entry will tell systemd that 143 stands for graceful exit.)

You could take this one step further and drop the script altogether:

  • Specify the java command line as ExecStart
  • Pass the full path to the java binary (as reported by which java)
  • Drop the redirections: by default, systemd will redirect stdout and stderr to the journal. (This can be configured in the .service file as well.)
🌐
Baeldung
baeldung.com › home › administration › service management › run a java application as a service on linux
Run a Java Application as a Service on Linux | Baeldung on Linux
March 18, 2024 - Before that, however, we should notify systemd that it has to rebuild its internal service database. Doing this will make it aware of the new system unit we introduced. We can do this by passing the daemon-reload command to systemctl. Now, we’re ready to run all the commands we mentioned: sudo systemctl daemon-reload sudo systemctl start javasimple.service sudo systemctl status javasimple.service ● javasimple.service - My Java driven simple service Loaded: loaded (/etc/systemd/system/javasimple.service; disabled; vendor preset: disabled) Active: active (running) since Sun 2021-01-17 20:10:19 CET; 8s ago Main PID: 8124 (java) CGroup: /system.slice/javasimple.service └─8124 /path/to/jvmdir/bin/java -jar javaapp.jar
🌐
DEV Community
dev.to › davey › running-a-java-application-as-a-service-1c0o
Running a Java Application as a Service - DEV Community
August 11, 2021 - In this post, I'm going to show how to run a Java application (or any other application for that matter) as a system service. When running as a system service, we get the following benefits: ... We can configure the application to start again in the case of failure. To create a service, I'm going to assume that we have a Jar packaged version of the application. This can be created by Maven with the package command: ... To control our application, we're going to run it as a systemd service.
🌐
Medium
medium.com › @ameyadhamnaskar › running-java-application-as-a-service-on-centos-599609d0c641
Running Java application as Linux service with systemd | by Ameya Dhamnaskar | Medium
January 24, 2019 - sudo systemctl daemon-reload sudo systemctl enable Service_Name sudo systemctl start Service_Name sudo systemctl stop Service_Name · This should get your Java Application up and running as a System Service.
🌐
ComputingForGeeks
computingforgeeks.com › home › how to run java jar application with systemd on linux
How To Run Java Jar Application with Systemd on Linux [Guide]
August 6, 2024 - The next thing to do is start the application service, but first, reload systemd so that it knows of the new application added. ... $ systemctl status myapp ● myapp.service - Manage Java service Loaded: loaded (/etc/systemd/system/myapp.service; enabled; vendor preset: disabled) Active: active ...
🌐
LinkedIn
linkedin.com › pulse › how-run-java-jar-application-systemd-linux-service-dhaval-gajjar
How to run java jar application with systemd on Linux as service
December 14, 2022 - Considering the application jar file located at /opt/apps/ directory and we will be using a logged-in user (ubuntu) to run the application with systemd. You can also create a system user for the same purpose as well. ... [Unit] Description=Email service Requires=network.target remote-fs.target After=network.target remote-fs.target [Service] Type=simple User=ubuntu WorkingDirectory=/opt/apps/ ExecStart=/usr/bin/java -jar /opt/apps/email-1.0.0.jar Restart=on-failure RestartSec=10 [Install] WantedBy=multi-user.target
Top answer
1 of 1
18

Here's some minor modifications:

  1. Since it listens on a network socket, make it a dependency of network.target.
  2. nohup is not needed since systemd will daemonize the executable for you.
  3. I think a separate shell script would be an overkill, so just merge it into the service file.
  4. Redirection (< /dev/null and so forth) isn't needed since systemd sets up an appropriate standard I/O context. Indeed, if you take the redirection out systemd will log anything sent to standard output by the Java program in its journal, with no special logging mechanism required.
  5. Running asynchonously from the invoking shell (&) isn't needed or appropriate.
  6. There's a specific behaviour pattern required by Type=forking, and if it isn't followed by the dæmon things go wrong. So try for Type=simple (or Type=notify).

So the service file looks like this:

[Unit]
Description=Some job
After=network.target

[Service]
WorkingDirectory=/home/user/tmp/testout
SyslogIdentifier=SocketTest
ExecStart=/bin/sh -c "exec java -jar /home/user/programming/tests/java/core/SocketTest/SocketTest.jar"
User=dlt
Type=simple

[Install]
WantedBy=multi-user.target

Notes:

  1. You cannot just use java as the name of the program to run. systemd doesn't search PATH for executables, and the name of the executable given to ExecStart must be absolute. So if you want path searching you have to invoke via a shell or /usr/bin/env. We choose /bin/sh here.
  2. Because this is Type=simple the shell must exec Java, not run it as a child process. systemd controls the service through the main process, and that needs to be Java, not a parent shell process.
  3. Because this isn't invoking the Java executable directly, systemd will put the name sh in its journal as the service name. See How to avoid /usr/bin/env being marked in systemd logs as the executable for more on this.

As far as I know, there is no special caveat of running Java application with Systemd.

Find elsewhere
🌐
Medium
snehalchaure.medium.com › running-an-application-as-a-service-with-systemctl-63a51dece4c5
Run an Application as a Service with Systemctl | by Snehal Chaure | Medium
June 15, 2023 - To run java app as system service you need to create a unit file with ‘.service’ suffix in ‘/etc/systemd/system’ directory. I have created the ‘javaapp.service’ file as follows.
🌐
The Art of Code
artofcode.wordpress.com › 2025 › 01 › 14 › running-java-application-as-a-linux-service
Running Java application as a Linux service | The Art of Code
April 1, 2025 - This post is a continuation of my previous one, “Turning a laptop into a Java app server in 2025”. In this part we’re going to setup a Java application as a service in Linux. We will use Systemd for this so a service will be automatically started on system boot and it will be run again if it crashed.
🌐
Mincong Huang
mincong.io › 2018 › 07 › 03 › create-systemd-unit-file-for-java
Create Systemd Unit File for Java - Mincong Huang
May 8, 2020 - This post explains how to create a systemd unit file for Java, so that you can run your Java application as a service in Linux. It also explains the structure of a service file, and tells your the useful commands after service’s creation.
🌐
GitHub
gist.github.com › tjohander-splunk › ee13bc8f3263538ff90a4937f28e4645
Getting a Java app to run as a Systemd service on Linux · GitHub
In a sane systemd path (/etc/systemd/system/ or /usr/lib/systemd/system) Create a Systemd service definition file called ... [Unit] Description=webserver Daemon [Service] ExecStart= /usr/bin/java -jar /home/ec2-user/spring-pet-clinic/target/spring-petclinic-2.4.5.jar [Install] WantedBy=multi-user.target
🌐
Stack Exchange
unix.stackexchange.com › questions › 692275 › systemd-service-on-java-script-which-has-to-be-ran-from-a-working-folder
scripting - Systemd service on java script which has to be ran from a working folder - Unix & Linux Stack Exchange
February 27, 2022 - I know nothing about java, however then was asked to create a myJAVA.service via systemctl, this will ensure that the application is restarted automatically when the server reboots or unexpected exit. I know a unit file in /etc/system/systemd/myJAVA.service will do this, but no idea how to make it works, below is my unit file.
🌐
Za
shrimpworks.za.net › 2020 › 09 › 01 › run-your-java-services-with-systemd
ShrimpWorks | Run Your Java Services with SystemD
Create this file in /etc/systemd/system/, named myservice.service. [Unit] Description=My Service After=syslog.target After=network.target [Service] WorkingDirectory=/opt/myservice/ ExecStart=/usr/bin/java -jar /opt/myservice/myservice.jar EnvironmentFile=/etc/myservice/config.env User=svcuser Type=simple StandardOutput=syslog StandardError=syslog SyslogIdentifier=myservice SuccessExitStatus=0 TimeoutStopSec=120 Restart=always [Install] WantedBy=multi-user.target ·
🌐
Fabian Lee
fabianlee.org › 2018 › 04 › 15 › java-spring-boot-application-as-a-service-using-systemd-on-ubuntu-16-04
Java: Spring Boot application as a service using systemd on Ubuntu 16.04 | Fabian Lee : Software Engineer
April 17, 2018 - $ sudo update-alternatives --config java $ cd /usr/lib/jvm $ sudo cp -r java-8-openjdk-amd64 java-8-openjdk-amd64-setcap $ sudo setcap 'cap_net_bind_service=+eip' /usr/lib/jvm/java-8-openjdk-amd64-setcap/jre/bin/java · The java binary in our new directory now has privileges to bind to ports less than 1024. So we edit “/lib/systemd/system/springechoservice.service” so that it runs the jar using this specific binary like below:
🌐
GitHub
github.com › jpmsilva › jsystemd
GitHub - jpmsilva/jsystemd: Java integration library for systemd services
This project contains modules to integrate Java services with systemd.
Starred by 33 users
Forked by 10 users
Languages   Java 99.2% | Shell 0.8% | Java 99.2% | Shell 0.8%