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.
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"))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With