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.lang.reflect.Field;
21  import java.lang.reflect.Method;
22  import java.security.AccessController;
23  import java.security.PrivilegedAction;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  import org.apache.hadoop.hbase.classification.InterfaceAudience;
28  
29  @InterfaceAudience.Private
30  public class UnsafeAvailChecker {
31  
32    private static final String CLASS_NAME = "sun.misc.Unsafe";
33    private static final Log LOG = LogFactory.getLog(UnsafeAvailChecker.class);
34    private static boolean avail = false;
35    private static boolean unaligned = false;
36  
37    static {
38      avail = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
39        @Override
40        public Boolean run() {
41          try {
42            Class<?> clazz = Class.forName(CLASS_NAME);
43            Field f = clazz.getDeclaredField("theUnsafe");
44            f.setAccessible(true);
45            return f.get(null) != null;
46          } catch (Throwable e) {
47            LOG.warn("sun.misc.Unsafe is not available/accessible", e);
48          }
49          return false;
50        }
51      });
52      // When Unsafe itself is not available/accessible consider unaligned as false.
53      if (avail) {
54        try {
55          // Using java.nio.Bits#unaligned() to check for unaligned-access capability
56          Class<?> clazz = Class.forName("java.nio.Bits");
57          Method m = clazz.getDeclaredMethod("unaligned");
58          m.setAccessible(true);
59          unaligned = (Boolean) m.invoke(null);
60        } catch (Exception e) {
61          LOG.warn("java.nio.Bits#unaligned() check failed."
62              + "Unsafe based read/write of primitive types won't be used", e);
63        }
64      }
65    }
66  
67    /**
68     * @return true when running JVM is having sun's Unsafe package available in it and it is
69     *         accessible.
70     */
71    public static boolean isAvailable() {
72      return avail;
73    }
74  
75    /**
76     * @return true when running JVM is having sun's Unsafe package available in it and underlying
77     *         system having unaligned-access capability.
78     */
79    public static boolean unaligned() {
80      return unaligned;
81    }
82  
83    private UnsafeAvailChecker() {
84      // private constructor to avoid instantiation
85    }
86  }