How to convert a java program to daemon with jsvc?

35,334

Solution 1

Java class:

package example;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import org.apache.commons.daemon.*;

class EchoTask extends TimerTask {
    @Override
    public void run() {
        System.out.println(new Date() + " running ...");
    }
}

public class Main implements Daemon {

    private static Timer timer = null;

    public static void main(String[] args) {
        timer = new Timer();
        timer.schedule(new EchoTask(), 0, 1000);
    }

    @Override
    public void init(DaemonContext dc) throws DaemonInitException, Exception {
        System.out.println("initializing ...");
    }

    @Override
    public void start() throws Exception {
        System.out.println("starting ...");
        main(null);
    }

    @Override
    public void stop() throws Exception {
        System.out.println("stopping ...");
        if (timer != null) {
            timer.cancel();
        }
    }

    @Override
    public void destroy() {
        System.out.println("done.");
    }

 }

Shell start/stop script:

#!/bin/sh

# Setup variables
EXEC=/usr/bin/jsvc
JAVA_HOME=/usr/lib/jvm/java-6-sun
CLASS_PATH="/usr/share/java/commons-daemon.jar":"/path/to/your.jar"
CLASS=example.Main
USER=foo
PID=/tmp/example.pid
LOG_OUT=/tmp/example.out
LOG_ERR=/tmp/example.err

do_exec()
{
    $EXEC -home "$JAVA_HOME" -cp $CLASS_PATH -user $USER -outfile $LOG_OUT -errfile $LOG_ERR -pidfile $PID $1 $CLASS
}

case "$1" in
    start)
        do_exec
            ;;
    stop)
        do_exec "-stop"
            ;;
    restart)
        if [ -f "$PID" ]; then
            do_exec "-stop"
            do_exec
        else
            echo "service not running, will do nothing"
            exit 1
        fi
            ;;
    *)
            echo "usage: daemon {start|stop|restart}" >&2
            exit 3
            ;;
esac

And the effect:

$ ./service start && sleep 5 && ./service stop
$ cat /tmp/example.out
initializing ...
starting ...
Fri Oct 07 16:26:54 EEST 2011 running ...
Fri Oct 07 16:26:55 EEST 2011 running ...
Fri Oct 07 16:26:56 EEST 2011 running ...
Fri Oct 07 16:26:57 EEST 2011 running ...
Fri Oct 07 16:26:58 EEST 2011 running ...
stopping ...
done.

Solution 2

Are you 100% sure you need to use jsvc? If you just want to have your application bind to a port and run at boot time, you don't need to use it. jsvc allows your application to bind to a privileged port (<1024) and then resume running as a normal user.

Solution 3

Check out the Jakarta Commons Daemon documentation. There's an example of how to implement the Daemon interface on their wiki. Once you've implemented Daemon, you should be able to start the process by following the "Starting jsvc" and "Using jsvc" docs.

Share:
35,334
Ozer
Author by

Ozer

Updated on October 08, 2020

Comments

  • Ozer
    Ozer over 3 years

    I wrote a program and now I am expected to convert it to a daemon. Since I am a noob and dont know anything about it, can you please tell me how can I do it or can you please give me basic tutorials or readings about it ? I really want to learn how I can do it ?

    Thank you all

  • Ozer
    Ozer over 12 years
    Actually I am sure because I am expected to do so. But I really dont know how to do that
  • Switch
    Switch about 11 years
    Nice approach, but I have a one question in mind. How do you define classpath if there are more than one dependent jar files? Do I need define one by one separately as per your script?
  • barti_ddu
    barti_ddu about 11 years
    @MMRUser: if the dependent jars are specified in your.jar manifest, you don't.
  • Ethan T
    Ethan T about 8 years
    jsvc also gives you things like startup error handling, PID tracking, and clean shutdown. It can be tricky to get a Java-based app running as a Linux service without those features.