22

I'm trying to execute a shell script from systemd. The script runs fine from command line.

The script (runServer.sh), runs up a Java process and looks like this:

#!/bin/bash
java -jar -Dresources=/home/pruss/dev/ServerDeploy5-4.1/Server/resources/MyServer.jar "0" "Test"

Inside /usr/lib/systemd/system (or /lib/systemd/system/ on other OSes) I've created a service file (myService.service):

[Unit]
Description=My Servers service
[Service]
ExecStart=/home/pruss/dev/ServerDeploy5-4.1/Server/runServer.sh
User=root
Type=oneshot
[Install]
WantedBy=multi-user.target

The result

Job for myService.service failed. See "systemctl status myService.service" and "journalctl -xn" for details.

I try:

systemctl status myService.service


   Loaded: loaded (/usr/lib/systemd/system/myService.service; disabled)
   Active: failed (Result: exit-code) since Thu 2015-07-23 12:27:38 BST; 26s ago
   Main PID: 28413 (code=exited, status=203/EXEC)
1

6 Answers 6

14

You may not need the shell script. You can start the process from the myService.service file provided you use the full path to both the java binary and the jar file. It should look something like

ExecStart=/usr/bin/java -jar /home/pruss/dev/ServerDeploy5-4.1/Server/resources/MyServer.jar

Works on CentOS 7.2.

1
  • 1
    my opinion is, that script is easier to maintain...
    – Betlista
    Jul 24, 2018 at 12:16
12

Not sure who gave this a thumbs down..

I found the solution and post it to save others the effort.

What you see above works. However, the final service is thus:

[Unit]
Description=MyProgramThing
[Service]
ExecStart=/home/prus/dev/Blah-4.1/Server/runServer.sh
Type=simple
User=prus
[Install]
WantedBy=multi-user.target

Importantly, inside my shell script, I needed to put in the full path the the .jar file. java -jar /home/myprog.jar etc

i.e. ./myJar.jar did not work. Hope that helps.

2
  • 1
    How do you account for ExecStop ? Apr 20, 2018 at 18:17
  • CTRL+C/SIGINT is sent to the java process when you stop the systemd service, if you app responds to that then is good, after the TimeoutStopSec (default : DefaultTimeoutStopSec 90s) it will send sigkill Mar 9, 2019 at 18:49
4

Take a look at my answer on stackoverflow which details how to create a systemd service for a Java application:

https://stackoverflow.com/a/22121547/272180

1
  • 1
    Thanks, Yglodt for filling out what I wrote. I did manage to sort this out a year ago, but if your writing helps anyone else, that's all good. Jul 14, 2016 at 8:27
4

This is my systemd template for java a process

[Unit]
Description=Spring MVC Java Service

[Service]
User=spring-mvc
# The configuration file application.properties should be here:
WorkingDirectory=/usr/local/spring-mvc


# Run ExecStartPre with root-permissions
PermissionsStartOnly=true

ExecStartPre=-/bin/mkdir -p /var/log/spring-mvc


ExecStartPre=/bin/chown -R spring-mvc:syslog /var/log/spring-mvc
ExecStartPre=/bin/chmod -R 775 /var/log/spring-mvc


Environment="ENV=stage"

#https://www.freedesktop.org/software/systemd/man/systemd.service.html#ExecStart=
ExecStart=/usr/bin/java \
        -Dlog4j.configurationFile=log4j2-spring.xml \
        -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector \
        -Dspring.profiles.active=stage \
        -Denvironment-type=stage \
        -XX:+UseConcMarkSweepGC \
        -XX:CMSInitiatingOccupancyFraction=80 \
        -XX:NewSize=756m \
        -XX:MetaspaceSize=256m \
        -Dsun.net.inetaddr.ttl=5 \
        -Xloggc:/var/log/spring-mvc/gc.log \
        -verbose:gc \
        -verbosegc \
        -XX:+DisableExplicitGC \
        -XX:+PrintGCDetails \
        -XX:+PrintGCDateStamps \
        -XX:+PreserveFramePointer \
        -XX:+StartAttachListener \
        -Xms768m \
        -Xmx768m \
        -XX:+HeapDumpOnOutOfMemoryError \
        -jar spring-mvc.war

SuccessExitStatus=143
StandardOutput=journal
StandardError=journal


KillSignal=SIGINT
TimeoutStopSec=20
Restart=always
RestartSec=5
StartLimitInterval=0
StartLimitBurst=10

LimitNOFILE=500000
LimitNPROC=500000

#https://www.freedesktop.org/software/systemd/man/systemd.exec.html#LimitCPU=
#LimitCPU=, LimitFSIZE=, LimitDATA=, LimitSTACK=, LimitCORE=, LimitRSS=, LimitNOFILE=, LimitAS=, LimitNPROC=, LimitMEMLOCK=, LimitLOCKS=, LimitSIGPENDING=, LimitMSGQUEUE=, LimitNICE=, LimitRTPRIO=, LimitRTTIME=¶

SyslogIdentifier=spring-mvc

[Install]
WantedBy=multi-user.target


# https://www.freedesktop.org/software/systemd/man/journalctl.html
#check logs --- journalctl -u spring-mvc -f -o cat
1

You may need to add a WorkingDirectory= so it knows where to run things from.

-1

I had the same problem (code=exited, status=203/EXEC).

Don't forget to give script execution permissions to your user.

You may want to change 777 to something more restrictive.

chmod 777 /home/yourscript.sh

or

chmod u+x /home/yourscript.sh

Then:

systemctl daemon-reload 
systemctl start yourScript.service 
systemctl enable yourScript.service

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .