shutdown hook won't start upon ^C (scala)

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.

Answers


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.


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.


Need Your Help

UINavigationController not showing on modal view controller

ios cocoa-touch uinavigationcontroller modalviewcontroller navigationbar

I am showing up programmatically a modal view controller when the user presses a button on the main view controller. The problem I have is that the modal view is displayed without the navigation ba...

Issue with PHP Sql query

php mysql mysqli

Could anyone maybe tell me why i get this error message here ?

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.