Domanda

i'm trying to get a clean and gracefull shutdown, and for some reason, it wont execute. iv'e tried:

sys addShutdownHook{
    logger.warn("SHUTTING DOWN...")
    // irrelevant logic here...
}

and also:

Runtime.getRuntime.addShutdownHook(ThreadOperations.delayOnThread{
        logger.warn("SHUTTING DOWN...")
        // irrelevant logic here...
    }
)

where ThreadOperations.delayOnThread definition is:

object ThreadOperations {

    def startOnThread(body: =>Unit) : Thread = {
        onThread(true, body)
    }

    def delayOnThread(body: =>Unit) : Thread = {
        onThread(false, body)
    }

    private def onThread(runNow : Boolean, body: =>Unit) : Thread = {
        val t=new Thread {
            override def run=body
        }
        if(runNow){t.start}
        t
    }

    // more irrelevant operations...
}

but when i run my program (executable jar, double activation), the hook does not start. so what am i doing wrong? what is the right way to add a shutdown hook in scala? is it in any way related to the fact i'm using double activation?

double activation is done like that:

object Gate extends App {
    val givenArgs = if(args.isEmpty){
                        Array("run")
                    }else{
                        args
                    }

    val jar = Main.getClass.getProtectionDomain().getCodeSource().getLocation().getFile;
    val dir = jar.dropRight(jar.split(System.getProperty("file.separator")).last.length + 1)
    val arguments = Seq("java", "-cp", jar, "boot.Main") ++ givenArgs.toSeq
    Process(arguments, new java.io.File(dir)).run();
}

(scala version: 2.9.2 ) thanks.

È stato utile?

Soluzione 2

Solved it.

For some reason, I thought that run as opposed to ! would detach the process. It actually hangs on because there are open streams left to the Process, which is returned from run (or maybe it just hangs for another reason, 'cause exec doesn't hang, but returns a Process with open streams to and from the child process, much like run). For this reason, the original process was still alive, and I accidentally sent the signals to it. Of course, it did not contain a handler, or a shutdown hook, so nothing happened.

The solution was to use Runtime.getRuntime.exec(arguments.toArray) instead of Process(arguments, new java.io.File(dir)).run();, close the streams in the Gate object, and send the ^C signal to the right process.

Altri suggerimenti

In your second attempt, your shutdown hook you seems to just create a thread and never start it (so it just gets garbage collected and does nothing). Did I miss something? (EDIT: yes I did, see comment. My bad).

In the first attempt, the problem might just be that the underlying log has some caching, and the application exits before the log is flushed.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top