If you need to intercept Ctrl-C, SIGINT, SIGHUP, etc. in Scala, and handle it on the main thread, it is necessary to join() back to the main thread from within the shutdown hook as below because, unlike C signal handlers, the process terminates at the end of the shutdown handler, even though there is no explicit call to System.exit().
object ctrlctest { @volatile var keepRunning = true def main(args: Array[String]) { val mainThread = Thread.currentThread(); Runtime.getRuntime.addShutdownHook(new Thread() {override def run = { println("inside addShutDownHook handler") keepRunning = false mainThread.join() }}) while (keepRunning) {println("in while loop")} // Graceful shutdown code goes here that needs to be on the main thread println("Exiting main") } }And the resulting output is:
in while loop in while loop in while loop inside addShutDownHook handler in while loop Exiting main