Running a Java process from Systemd

74,284

Solution 1

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.

Solution 2

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.

Solution 3

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

Solution 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

Solution 5

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

Share:
74,284

Related videos on Youtube

wax_lyrical
Author by

wax_lyrical

Updated on September 18, 2022

Comments

  • wax_lyrical
    wax_lyrical over 1 year

    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)
    
    • JGlass
      JGlass about 6 years
      And, if you're getting class not found exceptions - might take a look at my answer on SO stackoverflow.com/questions/21503883/… took a few hours of my life to figure out the stupid issue ;-(
  • wax_lyrical
    wax_lyrical almost 8 years
    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.
  • Balaji Boggaram Ramanarayan
    Balaji Boggaram Ramanarayan about 6 years
    How do you account for ExecStop ?
  • Betlista
    Betlista almost 6 years
    my opinion is, that script is easier to maintain...
  • Radu Toader
    Radu Toader about 5 years
    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