16

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)
12

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.

| improve this answer | |
  • 1
    my opinion is, that script is easier to maintain... – Betlista Jul 24 '18 at 12:16
10

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.

| improve this answer | |
  • 1
    How do you account for ExecStop ? – Balaji Boggaram Ramanarayan Apr 20 '18 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 – Radu Toader Mar 9 '19 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

| improve this answer | |
  • 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. – wax_lyrical Jul 14 '16 at 8:27
2

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
| improve this answer | |
1

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

| improve this answer | |
-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
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.