Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala shutdown hooks never running?

Tags:

scala

The scaladoc for sys.addShutdownHook says shutdown hooks are NOT guaranteed to be run. Now this is entirely reasonable, as the JVM can hardly run shutdown hooks if you send the JVM a SIGKILL, or whatever the Windows equivalent is.

However shutdown hooks added with sys.addShutdownHook never seem to run, although those run with Runtime.getRuntime.addShutdownHook do.

A test -

scala> val t = new Thread { override def run = println("hi!") }
t: java.lang.Thread = Thread[Thread-4,5,main]

scala> Runtime.getRuntime.addShutdownHook(t)

scala> hi!
george@george-MacBook:~$ scala

(Skipped the startup message)

scala> val t = new Thread { override def run = println("hi!") }
t: java.lang.Thread = Thread[Thread-4,5,main]

scala> sys.addShutdownHook(t.run _)
res0: scala.sys.ShutdownHookThread = Thread[shutdownHook1,5,main]

scala> george@george-MacBook:~$

The documentation says "The hook is automatically registered: the returned value can be ignored" so it's not that we're supposed to add the thread returned by sys.addShutdownHook (and at any rate that causes "IllegalArgumentException: Hook previously registered" to be thrown).

Also, calling run on thread returned by addShutdownHook doesn't seem to do anything, which is suspicious.

like image 412
George Simms Avatar asked Nov 15 '14 09:11

George Simms


1 Answers

The type signature of addShutdownHook is (source):

def addShutdownHook(body: => Unit): ShutdownHookThread

So, it is obvious why your code is not working. Expected is a call-by-name argument => Unit and you pass t.run _, which returns () => Unit - that is something entirely different.

Call-by-name parameters are not run until they are executed, passing t.run _ to it means that a function is created at the time when the call-by-name argument is called - you are not passing the function itself instead of the call-by-name argument.

Use

sys.addShutdownHook(t.run)

instead. Or don't use the thread at all and just pass the code that should be executed:

sys.addShutdownHook(println("hi"))
like image 153
kiritsuku Avatar answered Oct 02 '22 09:10

kiritsuku