The https://docs.spring.io/spring-boot/docs/current/reference/html/deployment-install.html chapter 64.2.2 Installation as a systemd Service is not complete. Several points are not clear or just missing in documentation and will lead to "bad" system usage.

Service unit file according to documentation

[Service]
ExecStart=/opt/myApplication/myApplication.jar
SuccessExitStatus=143

will print out the stdout application logging into journalctl -xe

Jun 03 15:36:24 serverhostname myApplication.jar[25061]: Application is running as root (UID 0). This is considered insecure.
Jun 03 15:36:27 serverhostname myApplication.jar[25061]:   .   ____          _            __ _ _
Jun 03 15:36:27 serverhostname myApplication.jar[25061]:  /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
Jun 03 15:36:27 serverhostname myApplication.jar[25061]: ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
Jun 03 15:36:27 serverhostname myApplication.jar[25061]:  \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
Jun 03 15:36:27 serverhostname myApplication.jar[25061]:   '  |____| .__|_| |_|_| |_\__, | / / / /
Jun 03 15:36:27 serverhostname myApplication.jar[25061]:  =========|_|==============|___/=/_/_/_/
Jun 03 15:36:27 serverhostname myApplication.jar[25061]:  :: Spring Boot ::        (v2.1.1.RELEASE)
Jun 03 15:36:27 serverhostname myApplication.jar[25061]: 2019-06-03 15:36:27.765  INFO 25080 --- [           main] 

and /var/log/messages contains the full stdout application logging too.

In my case the JAR file with embedded Spring Boot Startup Script is not linked to /etc/init.d/ thus it is not recognized to run as init_script and default action="run" will apply.

To start the application via systemd service unit file, I need to set MODE=service environment. The example service unit starts fine, but never stops via systemctl stop myApplication.service, because of missing ExecStop:

[Service]
#Type=forking
Type=simple
Environment="JAVA_HOME=/opt/java"
Environment="MODE=service"
#Environment="DEBUG=1"
WorkingDirectory=/opt/myApplication
ExecStart=/opt/myApplication/myApplication.jar start
SuccessExitStatus=143

A kill <java pid> is required :(

Simply adding ExecStop statement is not working too:

[Service]
#Type=forking
Type=simple
Environment="JAVA_HOME=/opt/java"
Environment="MODE=service"
#Environment="DEBUG=1"
WorkingDirectory=/opt/myApplication
ExecStart=/opt/myApplication/myApplication.jar start
ExecStop=/opt/myApplication/myApplication.jar stop
SuccessExitStatus=143

because it results into start & stop together:

Jun 03 15:14:12 serverhostname myApplication.jar[24595]: Started [24620]
Jun 03 15:14:13 serverhostname myApplication.jar[24622]: myApplication is running as root (UID 0). This is considered insecure.
Jun 03 15:14:14 serverhostname myApplication.jar[24622]: Stopped [24620]

My only working service unit (in MODE=service) is with usage of RemainAfterExit=yes:

[Service]
#Type=forking
Type=simple
Environment="JAVA_HOME=/opt/java"
Environment="MODE=service"
#Environment="DEBUG=1"
WorkingDirectory=/opt/myApplication
ExecStart=/opt/myApplication/myApplication.jar start
RemainAfterExit=yes
ExecStop=/opt/myApplication/myApplication.jar stop
SuccessExitStatus=143

Comment From: vpavic

I think there's some confusion here as you seem to mix SysV-style init and systemd concerns.

In my case the JAR file with embedded Spring Boot Startup Script is not linked to /etc/init.d/ thus it is not recognized to run as init_script and default action="run" will apply.

With systemd you shouldn't be linking the executable JAR to /etc/init.d - the only part of Spring Boot's embedded script that's really relevant for the systemd deployment is run as systemd itself is more advanced init system that handles concerns such as PID file and log redirection (which are handled by embedded script in SysV-style init).

In fact, you could quite easily configure systemd descriptor for Spring Boot application without using embedded script at all but rather having a jar -jar type command in the ExecStart.

Comment From: psytester

I'm not sure I fully understood your point, or you mean mine.

My development provides a Spring-Boot application with this embedded launch script. I do the integration test and it has to run as a service in production. It will be a SystemD with usage of systemctl <action> myApplikation and service myApplikation <action>, but if someone should set an init.d symlink and then do something via direct init.d call, it must still work reliably and failsafe. So e.g. do not start another process, but allow a stop or restart or only a status query.

I also don't want to set a symlink to /etc/init.d/ at all, as this will mix up too much. As SystemD Service Unit I have to set the MODE=service in any case, to use the other action cases in the launch script. Otherwise, action=run is always used internally, even for a status query.

That the application started via SystemD ExecStart can also be stopped again, an ExecStop must of course be added. To prevent ExecStop from being executed immediately on ExecStart, RemainAfterExit=yes is required.

The complete log output to /var/log/messages or as a separate file to /var/log/myApplication is only prevented if I set the configuration exactly as specified with correct MODE and action

Building and running the application as a stand alone JAR file is not my decision and why else should there be the launch script?

Some or most will certainly not even be aware of this behavior and there is this gap in the documentation.

Comment From: wilkinsona

Closing in favour of https://github.com/spring-projects/spring-boot/issues/28453.