From fdf89a04f28b7b5f3db9f4ccae4335dc0a644b46 Mon Sep 17 00:00:00 2001 From: Viktor Klang Date: Fri, 29 Oct 2010 15:31:07 +0200 Subject: [PATCH] Adding shutdown hook that clears logging levels registered by Configgy, closing ticket 486 --- akka-actor/src/main/scala/actor/Actor.scala | 40 ++++++++++++++++++++- akka-http/src/main/scala/AkkaLoader.scala | 2 ++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/akka-actor/src/main/scala/actor/Actor.scala b/akka-actor/src/main/scala/actor/Actor.scala index 943854fc61..a2f7d60848 100644 --- a/akka-actor/src/main/scala/actor/Actor.scala +++ b/akka-actor/src/main/scala/actor/Actor.scala @@ -82,6 +82,45 @@ class ActorTimeoutException private[akka](message: String) extends AkkaException * @author Jonas Bonér */ object Actor extends Logging { + + /** + * Add shutdown cleanups + */ + private[akka] lazy val shutdownHook = { + val hook = new Runnable { + override def run { + log.info("Running shutdown hook to do a cleanup of registered components.") + // Shutdown HawtDispatch GlobalQueue + org.fusesource.hawtdispatch.ScalaDispatch.globalQueue.asInstanceOf[org.fusesource.hawtdispatch.internal.GlobalDispatchQueue].shutdown + + // Clear Thread.subclassAudits + val tf = classOf[java.lang.Thread].getDeclaredField("subclassAudits") + tf.setAccessible(true) + val subclassAudits = tf.get(null).asInstanceOf[java.util.Map[_,_]] + subclassAudits.synchronized {subclassAudits.clear} + + // Clear and reset j.u.l.Level.known (due to Configgy) + val lf = classOf[java.util.logging.Level].getDeclaredField("known") + lf.setAccessible(true) + val known = lf.get(null).asInstanceOf[java.util.ArrayList[java.util.logging.Level]] + known.synchronized { + known.clear + known.add(java.util.logging.Level.OFF) + known.add(java.util.logging.Level.SEVERE) + known.add(java.util.logging.Level.WARNING) + known.add(java.util.logging.Level.INFO) + known.add(java.util.logging.Level.CONFIG) + known.add(java.util.logging.Level.FINE) + known.add(java.util.logging.Level.FINER) + known.add(java.util.logging.Level.FINEST) + known.add(java.util.logging.Level.ALL) + } + } + } + Runtime.getRuntime.addShutdownHook(new Thread(hook)) + hook + } + val TIMEOUT = Duration(config.getInt("akka.actor.timeout", 5), TIME_UNIT).toMillis val SERIALIZE_MESSAGES = config.getBool("akka.actor.serialize-messages", false) @@ -110,7 +149,6 @@ object Actor extends Logging { def actorOf[T <: Actor : Manifest]: ActorRef = actorOf(manifest[T].erasure.asInstanceOf[Class[_ <: Actor]]) /** -<<<<<<< HEAD:akka-actor/src/main/scala/actor/Actor.scala * Creates an ActorRef out of the Actor with type T. *
    *   import Actor._
diff --git a/akka-http/src/main/scala/AkkaLoader.scala b/akka-http/src/main/scala/AkkaLoader.scala
index d8afac67bc..22ff40016c 100644
--- a/akka-http/src/main/scala/AkkaLoader.scala
+++ b/akka-http/src/main/scala/AkkaLoader.scala
@@ -6,6 +6,7 @@ package akka.servlet
 
 import akka.config.Config
 import akka.util.{Logging, Bootable}
+import akka.actor.Actor
 
 /*
  * This class is responsible for booting up a stack of bundles and then shutting them down
@@ -40,6 +41,7 @@ class AkkaLoader extends Logging {
       log.info("Shutting down Akka...")
       _bundles.foreach(_.onUnload)
       _bundles = None
+      Actor.shutdownHook.run
       log.info("Akka succesfully shut down")
     }
   }