0

Please note: Commons Daemon hasn't had a release since 2013. So, if there is a more modern alternative for that (that's more compatible with systemd), then I'm all ears and open to any ideas!


I'm trying to get my Java 8 app deployed and running as a true Linux service managed by systemd. I have read through the Commons Daemon docs and I believe the way to accomplish this is as follows:

  1. Write a systemd service unit file, say, a /lib/systemd/system/myapp.service file; this will allow me to manually control my app via systemctl start myapp, etc. and will also allow me to do things like: configure my app to start when Linux starts up, always attempt to restart if it crashes, etc.
  2. I also then need to implement the Daemon interface (from Commons Daemon), which will allow my app to "listen" to events sent to it from systemd and invoke the correct Java methods when certain things happen (the app is started, stopped, restarted, Linux is shutdown, etc.).

My best attempt at such a Daemon impl:

public class MyApp implements Daemon {
    private BillingService billingService;
    private PizzaDeliveryService pizzaDeliveryService;

    public MyApp() {
        super();

        // Do NOT initialize any services from inside here.
    }

    public static void main(String[] args) {
        MyApp app = new MyApp();
    }

    @Override
    public void init(DaemonContext context) throws DaemonInitException, Exception {
        // 1. I assume this is where I do all my initializing,
        // and that I don't init anything in my default ctor above?
        billingService = new StripBillingService();
        pizzaDeliveryService = new LittleCaesarsDeliveryService();
        // etc.
    }

    @Override
    public void start() throws Exception {
        // 2. This is where my service starts actually doing things,
        // firing up other threads, etc.
    }

    @Override
    public void stop() throws Exception {
        // 3. Will this respond to a Linux 'sudo shutdown -P now'
        // command?
    }

    @Override
    public void destroy() {
        // 4. Where I'm supposed to actually release resources
        // and terminate gracefully.
    }
}

Is my understanding of the Daemon interface correct? Is it correct to simply instantiate a MyApp instance inside main, and then Commons Daemon take care of invoking init(...) and start(...) for me? Am I correct in not initializing any MyApp fields or doing dependency injection from the default constructor, and instead doing all that from inside init(...)?

More importantly (my actual question): what Linux commands will trigger the stop(...) method?

I ask because I intend on shutting the server down either by issuing sudo shutdown -P now or by sudo halt -p and am wondering which (if any) command will prompt systemd to invoke the MyApp#stop(...) method. Any ideas?

smeeb
  • 27,777
  • 57
  • 250
  • 447
  • 1
    systemd sends a signal (term by default but [it's configurable](https://www.freedesktop.org/software/systemd/man/systemd.kill.html)) to a daemon process. A daemon process is expected to set up a signal handler which then triggers an appropriate shutdown method – user3159253 Sep 27 '17 at 17:42
  • Thanks for clarifying that @user3159253 (+1) - but isn't that what Commons Daemon is doing for me (setting the signal handlers)? Or are you saying that there are other things I need to do (either at the Linux/systemd layer or at the app/Java layer) here? Thanks again! – smeeb Sep 27 '17 at 17:44
  • 2
    In case of Apache Commons Daemon native system signals are handled by jsvc helper daemon and then translated to java process via internal parent-child protocol as described [here](https://commons.apache.org/proper/commons-daemon/jsvc.html#How_jsvc_works). You may also find useful [DaemonUserSignal](https://commons.apache.org/proper/commons-daemon/apidocs/org/apache/commons/daemon/DaemonUserSignal.html) – user3159253 Sep 27 '17 at 18:00
  • Ok thanks for the clarification there @user3159253 (+1 again). So I *think* I'm hearing that, with my above setup, issuing a `sudo shutdown -P now` on the command line would trigger `systemctl stop myapp`, which in turn would invoke `MyApp#stop()`, **yes**? – smeeb Sep 27 '17 at 18:12
  • The standard path for shutdown is to trigger the `init` daemon (systemd in your case), which then shuts down all running daemons, then unmounts all filesystems etc. Regardless of a daemon's implementation language/framework each daemon is asked to terminate. In case of systemd the procedure is described in the page systemd.kill mentioned above. Yes, `systemctl stop ` does basically the same for a particular service – user3159253 Sep 27 '17 at 18:12

0 Answers0