[java] Run a Java Application as a Service on Linux

I have written a Java server application that runs on a standard virtual hosted Linux solution. The application runs all the time listening for socket connections and creating new handlers for them. It is a server side implementation to a client-server application.

The way I start it is by including it in the start up rc.local script of the server. However once started I do not know how to access it to stop it and if I want to install an update, so I have to restart the server in order to restart the application.

On a windows PC, for this type of application I might create a windows service and then I can stop and start it as I want. Is there anything like that on a Linux box so that if I start this application I can stop it and restart it without doing a complete restart of the server.

My application is called WebServer.exe. It is started on server startup by including it in my rc.local as such:

java -jar /var/www/vhosts/myweb.com/phpserv/WebServer.jar &

I am a bit of a noob at Linux so any example would be appreciated with any posts. However I do have SSH, and full FTP access to the box to install any updates as well as access to a Plesk panel.

This question is related to java linux service

The answer is



From Spring Boot application as a Service, I can recommend the Python-based supervisord application. See that stack overflow question for more information. It's really straightforward to set up.


Referring to Spring Boot application as a Service as well, I would go for the systemd version, since it's the easiest, least verbose, and best integrated into modern distros (and even the not-so-modern ones like CentOS 7.x).


Another alternative, which is also quite popular is the Java Service Wrapper. This is also quite popular around the OSS community.


To run Java code as daemon (service) you can write JNI based stub.

http://jnicookbook.owsiak.org/recipe-no-022/

for a sample code that is based on JNI. In this case you daemonize the code that was started as Java and main loop is executed in C. But it is also possible to put main, daemon's, service loop inside Java.

https://github.com/mkowsiak/jnicookbook/tree/master/recipes/recipeNo029

Have fun with JNI!


Linux service init script are stored into /etc/init.d. You can copy and customize /etc/init.d/skeleton file, and then call

service [yourservice] start|stop|restart

see http://www.ralfebert.de/blog/java/debian_daemon/. Its for Debian (so, Ubuntu as well) but fit more distribution.


You can use Thrift server or JMX to communicate with your Java service.


Im having Netty java application and I want to run it as a service with systemd. Unfortunately application stops no matter of what Type I'm using. At the end I've wrapped java start in screen. Here are the config files:

service

[Unit]
Description=Netty service
After=network.target
[Service]
User=user
Type=forking
WorkingDirectory=/home/user/app
ExecStart=/home/user/app/start.sh
TimeoutStopSec=10
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target

start

#!/bin/sh
/usr/bin/screen -L -dmS netty_app java -cp app.jar classPath

from that point you can use systemctl [start|stop|status] service.


Here is a sample shell script (make sure you replace the MATH name with the name of the your application):

#!/bin/bash

### BEGIN INIT INFO
# Provides:                 MATH
# Required-Start:           $java
# Required-Stop:            $java
# Short-Description:        Start and stop MATH service.
# Description:              -
# Date-Creation:            -
# Date-Last-Modification:   -
# Author:                   -
### END INIT INFO

# Variables
PGREP=/usr/bin/pgrep
JAVA=/usr/bin/java
ZERO=0

# Start the MATH
start() {
    echo "Starting MATH..."
    #Verify if the service is running
    $PGREP -f MATH > /dev/null
    VERIFIER=$?
    if [ $ZERO = $VERIFIER ]
    then
        echo "The service is already running"
    else
        #Run the jar file MATH service
        $JAVA -jar /opt/MATH/MATH.jar > /dev/null 2>&1 &
        #sleep time before the service verification
        sleep 10
        #Verify if the service is running
        $PGREP -f MATH  > /dev/null
        VERIFIER=$?
        if [ $ZERO = $VERIFIER ]
        then
            echo "Service was successfully started"
        else
            echo "Failed to start service"
        fi
    fi
    echo
}

# Stop the MATH
stop() {
    echo "Stopping MATH..."
    #Verify if the service is running
    $PGREP -f MATH > /dev/null
    VERIFIER=$?
    if [ $ZERO = $VERIFIER ]
    then
        #Kill the pid of java with the service name
        kill -9 $($PGREP -f MATH)
        #Sleep time before the service verification
        sleep 10
        #Verify if the service is running
        $PGREP -f MATH  > /dev/null
        VERIFIER=$?
        if [ $ZERO = $VERIFIER ]
        then
            echo "Failed to stop service"
        else
            echo "Service was successfully stopped"
        fi
    else
        echo "The service is already stopped"
    fi
    echo
}

# Verify the status of MATH
status() {
    echo "Checking status of MATH..."
    #Verify if the service is running
    $PGREP -f MATH > /dev/null
    VERIFIER=$?
    if [ $ZERO = $VERIFIER ]
    then
        echo "Service is running"
    else
        echo "Service is stopped"
    fi
    echo
}

# Main logic
case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        status
        ;;
    restart|reload)
        stop
        start
        ;;
  *)
    echo $"Usage: $0 {start|stop|status|restart|reload}"
    exit 1
esac
exit 0

Other answers do a good job giving custom scripts and setups depending on your platform. In addition to those, here are the mature, special purpose programs that I know of:

  • JSW from TanukiSoftware
  • YAJSW is an open source clone from the above. It is written in Java, and it is a nanny process that manages the child process (your code) according to configurations. Works on windows / linux.
  • JSVC is a native application. Its also a nanny process, but it invokes your child application through the JNI, rather than as a subprocess.

A simple solution is to create a script start.sh that runs Java through nohup and then stores the PID to a file:

nohup java -jar myapplication.jar > log.txt 2> errors.txt < /dev/null &
PID=$!
echo $PID > pid.txt

Then your stop script stop.sh would read the PID from the file and kill the application:

PID=$(cat pid.txt)
kill $PID

Of course I've left out some details, like checking whether the process exists and removing pid.txt if you're done.


However once started I don't know how to access it to stop it

You can write a simple stop script that greps for your java process, extracts the PID and calls kill on it. It's not fancy, but it's straight forward. Something like that may be of help as a start:

#!/bin/bash
PID = ps ax | grep "name of your app" | cut -d ' ' -f 1
kill $PID

From Spring Boot Reference Guide

Installation as an init.d service (System V)

Simply symlink the jar to init.d to support the standard start, stop, restart and status commands. Assuming that you have a Spring Boot application installed in /var/myapp, to install a Spring Boot application as an init.d service simply create a symlink:

$ sudo ln -s /var/myapp/myapp.jar /etc/init.d/myapp

Once installed, you can start and stop the service in the usual way. For example, on a Debian based system:

$ service myapp start

Tip If your application fails to start, check the log file written to /var/log/<appname>.log for errors.

Continue reading to know how to secure a deployed service.

After doing as written I've discovered that my service fails to start with this error message in logs: start-stop-daemon: unrecognized option --no-close. And I've managed to fix it by creating a config file /var/myapp/myapp.conf with the following content

USE_START_STOP_DAEMON=false

It is possible to run the war as a Linux service, and you may want to force in your pom.xml file before packaging, as some distros may not recognize in auto mode. To do it, add the following property inside of spring-boot-maven-plugin plugin.

                    <embeddedLaunchScriptProperties>
                        <mode>service</mode>
                    </embeddedLaunchScriptProperties>

Next, setup your init.d with:

ln -s myapp.war /etc/init.d/myapp

and you will be able to run

service myapp start|stop|restart

There are many other options that you can find in Spring Boot documentation, including Windows service.


Maybe not the best dev-ops solution, but good for the general use of a server for a lan party or similar.

Use screen to run your server in and then detach before logging out, this will keep the process running, you can then re-attach at any point.

Workflow:

Start a screen: screen

Start your server: java -jar minecraft-server.jar

Detach by pressing: Ctl-a, d

Re-attach: screen -r

More info here: https://www.gnu.org/software/screen/manual/screen.html


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to linux

grep's at sign caught as whitespace How to prevent Google Colab from disconnecting? "E: Unable to locate package python-pip" on Ubuntu 18.04 How to upgrade Python version to 3.7? Install Qt on Ubuntu Get first line of a shell command's output Cannot connect to the Docker daemon at unix:/var/run/docker.sock. Is the docker daemon running? Run bash command on jenkins pipeline How to uninstall an older PHP version from centOS7 How to update-alternatives to Python 3 without breaking apt?

Examples related to service

Starting ssh-agent on Windows 10 fails: "unable to start ssh-agent service, error :1058" startForeground fail after upgrade to Android 8.1 Context.startForegroundService() did not then call Service.startForeground() How to restart a windows service using Task Scheduler the MySQL service on local computer started and then stopped Android: keep Service running when app is killed How to create a service running a .exe file on Windows 2012 Server? Start systemd service after specific service? Spring Boot application as a Service SSRS expression to format two decimal places does not show zeros