View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.util;
19  
20  import java.io.IOException;
21  
22  /**
23   * This class provides ShutdownHookManager shims for HBase to interact with the Hadoop 1.0.x and the
24   * Hadoop 2.0+ series.
25   * 
26   * NOTE: No testing done against 0.22.x, or 0.21.x.
27   */
28  abstract public class ShutdownHookManager {
29    private static ShutdownHookManager instance;
30  
31    static Class shutdownHookManagerClass = null;
32    static {
33      try {
34        // This class exists in hadoop 2.0+ but not in Hadoop 20.x/1.x
35        shutdownHookManagerClass = Class.forName("org.apache.hadoop.util.ShutdownHookManager");
36        instance = new ShutdownHookManagerV2();
37      } catch (Exception e) {
38        instance = new ShutdownHookManagerV1();
39      }
40    }
41  
42    abstract public void addShutdownHook(Thread shutdownHook, int priority);
43    
44    abstract public boolean removeShutdownHook(Runnable shutdownHook);
45      
46    public static void affixShutdownHook(Thread shutdownHook, int priority) {
47      instance.addShutdownHook(shutdownHook, priority);
48    }
49    
50    public static boolean deleteShutdownHook(Runnable shutdownHook) {
51      return instance.removeShutdownHook(shutdownHook);
52    }
53  
54    private static class ShutdownHookManagerV1 extends ShutdownHookManager {
55      // priority is ignored in hadoop versions earlier than 2.0
56      public void addShutdownHook(Thread shutdownHookThread, int priority) {      
57        Runtime.getRuntime().addShutdownHook(shutdownHookThread);
58      }
59      
60      public boolean removeShutdownHook(Runnable shutdownHook) {
61        Thread shutdownHookThread = null;
62        if (!(shutdownHook instanceof Thread)) {
63          shutdownHookThread = new Thread(shutdownHook);
64        } else shutdownHookThread = (Thread) shutdownHook;
65        
66        return Runtime.getRuntime().removeShutdownHook(shutdownHookThread);
67      }
68    };
69  
70    private static class ShutdownHookManagerV2 extends ShutdownHookManager {
71      public void addShutdownHook(Thread shutdownHookThread, int priority) {
72        try {
73          Methods.call(shutdownHookManagerClass, 
74              Methods.call(shutdownHookManagerClass, null, "get", null, null),
75              "addShutdownHook",
76              new Class[] { Runnable.class, int.class },
77              new Object[] { shutdownHookThread, priority });
78        } catch (Exception ex) {
79          throw new RuntimeException("we could not use ShutdownHookManager.addShutdownHook", ex);
80        }
81      }
82      
83      public boolean removeShutdownHook(Runnable shutdownHook) {
84        try {
85          return (Boolean)
86          Methods.call(shutdownHookManagerClass, 
87              Methods.call(shutdownHookManagerClass, null, "get", null, null),
88              "removeShutdownHook",
89              new Class[] { Runnable.class },
90              new Object[] { shutdownHook });
91        } catch (Exception ex) {
92          throw new RuntimeException("we could not use ShutdownHookManager", ex);
93        }
94      }
95    };
96  
97  }