You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by te...@apache.org on 2012/05/09 20:33:41 UTC

svn commit: r1336334 - in /hbase/trunk/src/main/java/org/apache/hadoop/hbase: regionserver/ShutdownHook.java util/ShutdownHookManager.java

Author: tedyu
Date: Wed May  9 18:33:41 2012
New Revision: 1336334

URL: http://svn.apache.org/viewvc?rev=1336334&view=rev
Log:
HBASE-5963 ClassCastException: FileSystem$Cache$ClientFinalizer cannot be cast to Thread

Added:
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/ShutdownHookManager.java
Modified:
    hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/ShutdownHook.java

Modified: hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/ShutdownHook.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/ShutdownHook.java?rev=1336334&r1=1336333&r2=1336334&view=diff
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/ShutdownHook.java (original)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/regionserver/ShutdownHook.java Wed May  9 18:33:41 2012
@@ -31,6 +31,7 @@ import org.apache.hadoop.conf.Configurat
 import org.apache.hadoop.fs.FileSystem;
 import org.apache.hadoop.hbase.HBaseConfiguration;
 import org.apache.hadoop.hbase.Stoppable;
+import org.apache.hadoop.hbase.util.ShutdownHookManager;
 import org.apache.hadoop.hbase.util.Threads;
 
 /**
@@ -83,7 +84,7 @@ public class ShutdownHook {
       final Stoppable stop, final Thread threadToJoin) {
     Thread fsShutdownHook = suppressHdfsShutdownHook(fs);
     Thread t = new ShutdownHookThread(conf, stop, threadToJoin, fsShutdownHook);
-    Runtime.getRuntime().addShutdownHook(t);
+    ShutdownHookManager.affixShutdownHook(t, 0);
     LOG.info("Installed shutdown hook thread: " + t.getName());
   }
 
@@ -186,7 +187,10 @@ public class ShutdownHook {
         Field cacheField = FileSystem.class.getDeclaredField("CACHE");
         cacheField.setAccessible(true);
         Object cacheInstance = cacheField.get(fs);
-        hdfsClientFinalizer = (Thread)field.get(cacheInstance);
+        Runnable finalizerRunnable = (Runnable)field.get(cacheInstance);
+        if (!(finalizerRunnable instanceof Thread)) {
+          hdfsClientFinalizer = new Thread(finalizerRunnable);
+        } else hdfsClientFinalizer = (Thread)finalizerRunnable;
       } else {
         // Then we didnt' find clientFinalizer in Cache.  Presume clean 0.20 hadoop.
         field = FileSystem.class.getDeclaredField(CLIENT_FINALIZER_DATA_METHOD);
@@ -197,7 +201,7 @@ public class ShutdownHook {
         throw new RuntimeException("Client finalizer is null, can't suppress!");
       }
       if (!fsShutdownHooks.containsKey(hdfsClientFinalizer) &&
-          !Runtime.getRuntime().removeShutdownHook(hdfsClientFinalizer)) {
+          !ShutdownHookManager.deleteShutdownHook(hdfsClientFinalizer)) {
         throw new RuntimeException("Failed suppression of fs shutdown hook: " +
           hdfsClientFinalizer);
       }

Added: hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/ShutdownHookManager.java
URL: http://svn.apache.org/viewvc/hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/ShutdownHookManager.java?rev=1336334&view=auto
==============================================================================
--- hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/ShutdownHookManager.java (added)
+++ hbase/trunk/src/main/java/org/apache/hadoop/hbase/util/ShutdownHookManager.java Wed May  9 18:33:41 2012
@@ -0,0 +1,97 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase.util;
+
+import java.io.IOException;
+
+/**
+ * This class provides ShutdownHookManager shims for HBase to interact with the Hadoop 1.0.x and the
+ * Hadoop 2.0+ series.
+ * 
+ * NOTE: No testing done against 0.22.x, or 0.21.x.
+ */
+abstract public class ShutdownHookManager {
+  private static ShutdownHookManager instance;
+
+  static Class shutdownHookManagerClass = null;
+  static {
+    try {
+      // This class exists in hadoop 2.0+ but not in Hadoop 20.x/1.x
+      shutdownHookManagerClass = Class.forName("org.apache.hadoop.util.ShutdownHookManager");
+      instance = new ShutdownHookManagerV2();
+    } catch (Exception e) {
+      instance = new ShutdownHookManagerV1();
+    }
+  }
+
+  abstract public void addShutdownHook(Thread shutdownHook, int priority);
+  
+  abstract public boolean removeShutdownHook(Runnable shutdownHook);
+    
+  public static void affixShutdownHook(Thread shutdownHook, int priority) {
+    instance.addShutdownHook(shutdownHook, priority);
+  }
+  
+  public static boolean deleteShutdownHook(Runnable shutdownHook) {
+    return instance.removeShutdownHook(shutdownHook);
+  }
+
+  private static class ShutdownHookManagerV1 extends ShutdownHookManager {
+    // priority is ignored in hadoop versions earlier than 2.0
+    public void addShutdownHook(Thread shutdownHookThread, int priority) {      
+      Runtime.getRuntime().addShutdownHook(shutdownHookThread);
+    }
+    
+    public boolean removeShutdownHook(Runnable shutdownHook) {
+      Thread shutdownHookThread = null;
+      if (!(shutdownHook instanceof Thread)) {
+        shutdownHookThread = new Thread(shutdownHook);
+      } else shutdownHookThread = (Thread) shutdownHook;
+      
+      return Runtime.getRuntime().removeShutdownHook(shutdownHookThread);
+    }
+  };
+
+  private static class ShutdownHookManagerV2 extends ShutdownHookManager {
+    public void addShutdownHook(Thread shutdownHookThread, int priority) {
+      try {
+        Methods.call(shutdownHookManagerClass, 
+            Methods.call(shutdownHookManagerClass, null, "get", null, null),
+            "addShutdownHook",
+            new Class[] { Runnable.class, int.class },
+            new Object[] { shutdownHookThread, priority });
+      } catch (Exception ex) {
+        throw new RuntimeException("we could not use ShutdownHookManager.addShutdownHook", ex);
+      }
+    }
+    
+    public boolean removeShutdownHook(Runnable shutdownHook) {
+      try {
+        return (Boolean)
+        Methods.call(shutdownHookManagerClass, 
+            Methods.call(shutdownHookManagerClass, null, "get", null, null),
+            "removeShutdownHook",
+            new Class[] { Runnable.class },
+            new Object[] { shutdownHook });
+      } catch (Exception ex) {
+        throw new RuntimeException("we could not use ShutdownHookManager", ex);
+      }
+    }
+  };
+
+}