You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by zh...@apache.org on 2022/03/12 08:52:22 UTC

[hbase] branch master updated: HBASE-25465 Use javac --release option for supporting cross version compilation (#4164)

This is an automated email from the ASF dual-hosted git repository.

zhangduo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hbase.git


The following commit(s) were added to refs/heads/master by this push:
     new c248521  HBASE-25465 Use javac --release option for supporting cross version compilation (#4164)
c248521 is described below

commit c2485215dee14ae9888af235dda9826b83507456
Author: Duo Zhang <zh...@apache.org>
AuthorDate: Sat Mar 12 16:51:49 2022 +0800

    HBASE-25465 Use javac --release option for supporting cross version compilation (#4164)
    
    Signed-off-by: Andrew Purtell <ap...@apache.org>
---
 .../apache/hadoop/hbase/filter/FuzzyRowFilter.java |  13 +-
 hbase-common/pom.xml                               |   4 +
 .../apache/hadoop/hbase/io/ByteBuffAllocator.java  |   9 +-
 .../apache/hadoop/hbase/nio/SingleByteBuff.java    |  11 +-
 .../apache/hadoop/hbase/util/ByteBufferUtils.java  |  35 ++--
 .../java/org/apache/hadoop/hbase/util/Bytes.java   |  26 +--
 .../org/apache/hadoop/hbase/util/ClassSize.java    |  21 ++-
 .../org/apache/hadoop/hbase/util/UnsafeAccess.java | 208 +++++++++------------
 .../hadoop/hbase/util/UnsafeAvailChecker.java      | 190 -------------------
 .../hadoop/hbase/util/TestByteBufferUtils.java     |  14 +-
 .../org/apache/hadoop/hbase/util/TestBytes.java    |   3 +-
 .../hadoop/hbase/rest/TestRESTServerSSL.java       |  25 ++-
 .../org/apache/hadoop/hbase/HBaseServerBase.java   |   4 +-
 pom.xml                                            |  13 +-
 14 files changed, 187 insertions(+), 389 deletions(-)

diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/filter/FuzzyRowFilter.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/filter/FuzzyRowFilter.java
index 9f44fe8..71a827e 100644
--- a/hbase-client/src/main/java/org/apache/hadoop/hbase/filter/FuzzyRowFilter.java
+++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/filter/FuzzyRowFilter.java
@@ -23,19 +23,20 @@ import java.util.Comparator;
 import java.util.List;
 import java.util.Objects;
 import java.util.PriorityQueue;
-
 import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.CellComparator;
 import org.apache.hadoop.hbase.PrivateCellUtil;
-import org.apache.yetus.audience.InterfaceAudience;
 import org.apache.hadoop.hbase.exceptions.DeserializationException;
+import org.apache.hadoop.hbase.unsafe.HBasePlatformDependent;
+import org.apache.hadoop.hbase.util.Bytes;
+import org.apache.hadoop.hbase.util.Pair;
+import org.apache.yetus.audience.InterfaceAudience;
+
 import org.apache.hbase.thirdparty.com.google.protobuf.InvalidProtocolBufferException;
 import org.apache.hbase.thirdparty.com.google.protobuf.UnsafeByteOperations;
+
 import org.apache.hadoop.hbase.shaded.protobuf.generated.FilterProtos;
 import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.BytesBytesPair;
-import org.apache.hadoop.hbase.util.Bytes;
-import org.apache.hadoop.hbase.util.Pair;
-import org.apache.hadoop.hbase.util.UnsafeAvailChecker;
 
 /**
  * This is optimized version of a standard FuzzyRowFilter Filters data based on fuzzy row key.
@@ -57,7 +58,7 @@ import org.apache.hadoop.hbase.util.UnsafeAvailChecker;
  */
 @InterfaceAudience.Public
 public class FuzzyRowFilter extends FilterBase {
-  private static final boolean UNSAFE_UNALIGNED = UnsafeAvailChecker.unaligned();
+  private static final boolean UNSAFE_UNALIGNED = HBasePlatformDependent.unaligned();
   private List<Pair<byte[], byte[]>> fuzzyKeysData;
   private boolean done = false;
 
diff --git a/hbase-common/pom.xml b/hbase-common/pom.xml
index 95df377..70f3b75 100644
--- a/hbase-common/pom.xml
+++ b/hbase-common/pom.xml
@@ -168,6 +168,10 @@
       <artifactId>hbase-shaded-netty</artifactId>
     </dependency>
     <dependency>
+      <groupId>org.apache.hbase.thirdparty</groupId>
+      <artifactId>hbase-unsafe</artifactId>
+    </dependency>
+    <dependency>
       <groupId>org.slf4j</groupId>
       <artifactId>slf4j-api</artifactId>
     </dependency>
diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/io/ByteBuffAllocator.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/io/ByteBuffAllocator.java
index 81adedf..f4ce7c7 100644
--- a/hbase-common/src/main/java/org/apache/hadoop/hbase/io/ByteBuffAllocator.java
+++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/io/ByteBuffAllocator.java
@@ -30,10 +30,10 @@ import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.nio.ByteBuff;
 import org.apache.hadoop.hbase.nio.SingleByteBuff;
 import org.apache.hadoop.hbase.util.ReflectionUtils;
+import org.apache.hadoop.hbase.util.UnsafeAccess;
 import org.apache.yetus.audience.InterfaceAudience;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import sun.nio.ch.DirectBuffer;
 
 import org.apache.hbase.thirdparty.com.google.common.collect.Sets;
 
@@ -335,11 +335,8 @@ public class ByteBuffAllocator {
   public void clean() {
     while (!buffers.isEmpty()) {
       ByteBuffer b = buffers.poll();
-      if (b instanceof DirectBuffer) {
-        DirectBuffer db = (DirectBuffer) b;
-        if (db.cleaner() != null) {
-          db.cleaner().clean();
-        }
+      if (b.isDirect()) {
+        UnsafeAccess.freeDirectBuffer(b);
       }
     }
     this.usedBufCount.set(0);
diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/nio/SingleByteBuff.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/nio/SingleByteBuff.java
index 797bfdc..46c86a3 100644
--- a/hbase-common/src/main/java/org/apache/hadoop/hbase/nio/SingleByteBuff.java
+++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/nio/SingleByteBuff.java
@@ -23,16 +23,13 @@ import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.FileChannel;
 import java.nio.channels.ReadableByteChannel;
-
 import org.apache.hadoop.hbase.io.ByteBuffAllocator.Recycler;
+import org.apache.hadoop.hbase.unsafe.HBasePlatformDependent;
 import org.apache.hadoop.hbase.util.ByteBufferUtils;
 import org.apache.hadoop.hbase.util.ObjectIntPair;
 import org.apache.hadoop.hbase.util.UnsafeAccess;
-import org.apache.hadoop.hbase.util.UnsafeAvailChecker;
 import org.apache.yetus.audience.InterfaceAudience;
 
-import sun.nio.ch.DirectBuffer;
-
 /**
  * An implementation of ByteBuff where a single BB backs the BBI. This just acts as a wrapper over a
  * normal BB - offheap or onheap
@@ -40,8 +37,8 @@ import sun.nio.ch.DirectBuffer;
 @InterfaceAudience.Private
 public class SingleByteBuff extends ByteBuff {
 
-  private static final boolean UNSAFE_AVAIL = UnsafeAvailChecker.isAvailable();
-  private static final boolean UNSAFE_UNALIGNED = UnsafeAvailChecker.unaligned();
+  private static final boolean UNSAFE_AVAIL = HBasePlatformDependent.isUnsafeAvailable();
+  private static final boolean UNSAFE_UNALIGNED = HBasePlatformDependent.unaligned();
 
   // Underlying BB
   private final ByteBuffer buf;
@@ -65,7 +62,7 @@ public class SingleByteBuff extends ByteBuff {
       this.unsafeOffset = UnsafeAccess.BYTE_ARRAY_BASE_OFFSET + buf.arrayOffset();
       this.unsafeRef = buf.array();
     } else {
-      this.unsafeOffset = ((DirectBuffer) buf).address();
+      this.unsafeOffset = UnsafeAccess.directBufferAddress(buf);
     }
   }
 
diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ByteBufferUtils.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ByteBufferUtils.java
index eb0cfce..c735b1d 100644
--- a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ByteBufferUtils.java
+++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ByteBufferUtils.java
@@ -30,24 +30,23 @@ import java.util.Arrays;
 import org.apache.hadoop.hbase.io.ByteBufferWriter;
 import org.apache.hadoop.hbase.io.util.StreamUtils;
 import org.apache.hadoop.hbase.nio.ByteBuff;
+import org.apache.hadoop.hbase.unsafe.HBasePlatformDependent;
 import org.apache.hadoop.io.IOUtils;
 import org.apache.hadoop.io.WritableUtils;
 import org.apache.yetus.audience.InterfaceAudience;
-import sun.nio.ch.DirectBuffer;
 
 /**
  * Utility functions for working with byte buffers, such as reading/writing
  * variable-length long numbers.
  */
-@SuppressWarnings("restriction")
 @InterfaceAudience.Private
 public final class ByteBufferUtils {
   // "Compressed integer" serialization helper constants.
   public final static int VALUE_MASK = 0x7f;
   public final static int NEXT_BIT_SHIFT = 7;
   public final static int NEXT_BIT_MASK = 1 << 7;
-  final static boolean UNSAFE_AVAIL = UnsafeAvailChecker.isAvailable();
-  public final static boolean UNSAFE_UNALIGNED = UnsafeAvailChecker.unaligned();
+  final static boolean UNSAFE_AVAIL = HBasePlatformDependent.isUnsafeAvailable();
+  public final static boolean UNSAFE_UNALIGNED = HBasePlatformDependent.unaligned();
 
   private ByteBufferUtils() {
   }
@@ -78,11 +77,10 @@ public final class ByteBufferUtils {
 
     static Comparer getBestComparer() {
       try {
-        Class<?> theClass = Class.forName(UNSAFE_COMPARER_NAME);
+        Class<? extends Comparer> theClass =
+          Class.forName(UNSAFE_COMPARER_NAME).asSubclass(Comparer.class);
 
-        @SuppressWarnings("unchecked")
-        Comparer comparer = (Comparer) theClass.getConstructor().newInstance();
-        return comparer;
+        return theClass.getConstructor().newInstance();
       } catch (Throwable t) { // ensure we really catch *everything*
         return PureJavaComparer.INSTANCE;
       }
@@ -137,7 +135,7 @@ public final class ByteBufferUtils {
         long offset2Adj;
         Object refObj2 = null;
         if (buf2.isDirect()) {
-          offset2Adj = o2 + ((DirectBuffer)buf2).address();
+          offset2Adj = o2 + UnsafeAccess.directBufferAddress(buf2);
         } else {
           offset2Adj = o2 + buf2.arrayOffset() + UnsafeAccess.BYTE_ARRAY_BASE_OFFSET;
           refObj2 = buf2.array();
@@ -151,13 +149,13 @@ public final class ByteBufferUtils {
         long offset1Adj, offset2Adj;
         Object refObj1 = null, refObj2 = null;
         if (buf1.isDirect()) {
-          offset1Adj = o1 + ((DirectBuffer) buf1).address();
+          offset1Adj = o1 + UnsafeAccess.directBufferAddress(buf1);
         } else {
           offset1Adj = o1 + buf1.arrayOffset() + UnsafeAccess.BYTE_ARRAY_BASE_OFFSET;
           refObj1 = buf1.array();
         }
         if (buf2.isDirect()) {
-          offset2Adj = o2 + ((DirectBuffer) buf2).address();
+          offset2Adj = o2 + UnsafeAccess.directBufferAddress(buf2);
         } else {
           offset2Adj = o2 + buf2.arrayOffset() + UnsafeAccess.BYTE_ARRAY_BASE_OFFSET;
           refObj2 = buf2.array();
@@ -175,12 +173,11 @@ public final class ByteBufferUtils {
 
     static Converter getBestConverter() {
       try {
-        Class<?> theClass = Class.forName(UNSAFE_CONVERTER_NAME);
+        Class<? extends Converter> theClass =
+          Class.forName(UNSAFE_CONVERTER_NAME).asSubclass(Converter.class);
 
         // yes, UnsafeComparer does implement Comparer<byte[]>
-        @SuppressWarnings("unchecked")
-        Converter converter = (Converter) theClass.getConstructor().newInstance();
-        return converter;
+        return theClass.getConstructor().newInstance();
       } catch (Throwable t) { // ensure we really catch *everything*
         return PureJavaConverter.INSTANCE;
       }
@@ -922,8 +919,8 @@ public final class ByteBufferUtils {
      * 64-bit.
      */
     for (i = 0; i < strideLimit; i += stride) {
-      long lw = UnsafeAccess.theUnsafe.getLong(obj1, o1 + (long) i);
-      long rw = UnsafeAccess.theUnsafe.getLong(obj2, o2 + (long) i);
+      long lw = HBasePlatformDependent.getLong(obj1, o1 + (long) i);
+      long rw = HBasePlatformDependent.getLong(obj2, o2 + (long) i);
       if (lw != rw) {
         if (!UnsafeAccess.LITTLE_ENDIAN) {
           return ((lw + Long.MIN_VALUE) < (rw + Long.MIN_VALUE)) ? -1 : 1;
@@ -944,8 +941,8 @@ public final class ByteBufferUtils {
 
     // The epilogue to cover the last (minLength % stride) elements.
     for (; i < minLength; i++) {
-      int il = (UnsafeAccess.theUnsafe.getByte(obj1, o1 + i) & 0xFF);
-      int ir = (UnsafeAccess.theUnsafe.getByte(obj2, o2 + i) & 0xFF);
+      int il = (HBasePlatformDependent.getByte(obj1, o1 + i) & 0xFF);
+      int ir = (HBasePlatformDependent.getByte(obj2, o2 + i) & 0xFF);
       if (il != ir) {
         return il - ir;
       }
diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/Bytes.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/Bytes.java
index 0c96dcc..af68541 100644
--- a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/Bytes.java
+++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/Bytes.java
@@ -41,13 +41,13 @@ import java.util.Random;
 
 import org.apache.hadoop.hbase.Cell;
 import org.apache.hadoop.hbase.CellComparator;
+import org.apache.hadoop.hbase.unsafe.HBasePlatformDependent;
 import org.apache.hadoop.io.RawComparator;
 import org.apache.hadoop.io.WritableComparator;
 import org.apache.hadoop.io.WritableUtils;
 import org.apache.yetus.audience.InterfaceAudience;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import sun.misc.Unsafe;
 
 import org.apache.hbase.thirdparty.org.apache.commons.collections4.CollectionUtils;
 
@@ -56,7 +56,6 @@ import org.apache.hbase.thirdparty.org.apache.commons.collections4.CollectionUti
  * comparisons, hash code generation, manufacturing keys for HashMaps or
  * HashSets, and can be used as key in maps or trees.
  */
-@SuppressWarnings("restriction")
 @InterfaceAudience.Public
 @edu.umd.cs.findbugs.annotations.SuppressWarnings(
     value="EQ_CHECK_FOR_OPERAND_NOT_COMPATIBLE_WITH_THIS",
@@ -126,7 +125,7 @@ public class Bytes implements Comparable<Bytes> {
   // SizeOf which uses java.lang.instrument says 24 bytes. (3 longs?)
   public static final int ESTIMATED_HEAP_TAX = 16;
 
-  static final boolean UNSAFE_UNALIGNED = UnsafeAvailChecker.unaligned();
+  static final boolean UNSAFE_UNALIGNED = HBasePlatformDependent.unaligned();
 
   /**
    * Returns length of the byte array, returning 0 if the array is null.
@@ -1359,21 +1358,17 @@ public class Bytes implements Comparable<Bytes> {
 
     protected static final class UnsafeConverter extends Converter {
 
-      static final Unsafe theUnsafe;
-
       public UnsafeConverter() {}
 
       static {
-        if (UNSAFE_UNALIGNED) {
-          theUnsafe = UnsafeAccess.theUnsafe;
-        } else {
+        if (!UNSAFE_UNALIGNED) {
           // It doesn't matter what we throw;
           // it's swallowed in getBestComparer().
           throw new Error();
         }
 
         // sanity check - this should never fail
-        if (theUnsafe.arrayIndexScale(byte[].class) != 1) {
+        if (HBasePlatformDependent.arrayIndexScale(byte[].class) != 1) {
           throw new AssertionError();
         }
       }
@@ -1412,7 +1407,7 @@ public class Bytes implements Comparable<Bytes> {
 
   /**
    * Provides a lexicographical comparer implementation; either a Java
-   * implementation or a faster implementation based on {@link Unsafe}.
+   * implementation or a faster implementation based on {@code Unsafe}.
    *
    * <p>Uses reflection to gracefully fall back to the Java implementation if
    * {@code Unsafe} isn't available.
@@ -1469,18 +1464,15 @@ public class Bytes implements Comparable<Bytes> {
     enum UnsafeComparer implements Comparer<byte[]> {
       INSTANCE;
 
-      static final Unsafe theUnsafe;
       static {
-        if (UNSAFE_UNALIGNED) {
-          theUnsafe = UnsafeAccess.theUnsafe;
-        } else {
+        if (!UNSAFE_UNALIGNED) {
           // It doesn't matter what we throw;
           // it's swallowed in getBestComparer().
           throw new Error();
         }
 
         // sanity check - this should never fail
-        if (theUnsafe.arrayIndexScale(byte[].class) != 1) {
+        if (HBasePlatformDependent.arrayIndexScale(byte[].class) != 1) {
           throw new AssertionError();
         }
       }
@@ -1518,8 +1510,8 @@ public class Bytes implements Comparable<Bytes> {
          * than 4 bytes even on 32-bit. On the other hand, it is substantially faster on 64-bit.
          */
         for (i = 0; i < strideLimit; i += stride) {
-          long lw = theUnsafe.getLong(buffer1, offset1Adj + i);
-          long rw = theUnsafe.getLong(buffer2, offset2Adj + i);
+          long lw = HBasePlatformDependent.getLong(buffer1, offset1Adj + i);
+          long rw = HBasePlatformDependent.getLong(buffer2, offset2Adj + i);
           if (lw != rw) {
             if(!UnsafeAccess.LITTLE_ENDIAN) {
               return ((lw + Long.MIN_VALUE) < (rw + Long.MIN_VALUE)) ? -1 : 1;
diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ClassSize.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ClassSize.java
index 4e60056..9f6e21a 100644
--- a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ClassSize.java
+++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ClassSize.java
@@ -24,7 +24,7 @@ import java.lang.reflect.Field;
 import java.lang.reflect.Modifier;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentSkipListMap;
-
+import org.apache.hadoop.hbase.unsafe.HBasePlatformDependent;
 import org.apache.yetus.audience.InterfaceAudience;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -186,13 +186,19 @@ public class ClassSize {
       private byte a;
     }
 
+    private static final int ARRAY_OBJECT_INDEX_SCALE =
+      HBasePlatformDependent.arrayIndexScale(Object[].class);
+
+    private static final int ARRAY_BYTE_INDEX_SCALE =
+      HBasePlatformDependent.arrayIndexScale(byte[].class);
+
     public UnsafeLayout() {
     }
 
     @Override
     int headerSize() {
       try {
-        return (int) UnsafeAccess.theUnsafe.objectFieldOffset(
+        return (int) HBasePlatformDependent.objectFieldOffset(
           HeaderSize.class.getDeclaredField("a"));
       } catch (NoSuchFieldException | SecurityException e) {
         LOG.error(e.toString(), e);
@@ -202,21 +208,19 @@ public class ClassSize {
 
     @Override
     int arrayHeaderSize() {
-      return UnsafeAccess.theUnsafe.arrayBaseOffset(byte[].class);
+      return HBasePlatformDependent.arrayBaseOffset(byte[].class);
     }
 
     @Override
-    @SuppressWarnings("static-access")
     int oopSize() {
       // Unsafe.addressSize() returns 8, even with CompressedOops. This is how many bytes each
       // element is allocated in an Object[].
-      return UnsafeAccess.theUnsafe.ARRAY_OBJECT_INDEX_SCALE;
+      return ARRAY_OBJECT_INDEX_SCALE;
     }
 
     @Override
-    @SuppressWarnings("static-access")
     long sizeOfByteArray(int len) {
-      return align(ARRAY + len * UnsafeAccess.theUnsafe.ARRAY_BYTE_INDEX_SCALE);
+      return align(ARRAY + len * ARRAY_BYTE_INDEX_SCALE);
     }
   }
 
@@ -224,7 +228,8 @@ public class ClassSize {
     // Have a safeguard in case Unsafe estimate is wrong. This is static context, there is
     // no configuration, so we look at System property.
     String enabled = System.getProperty("hbase.memorylayout.use.unsafe");
-    if (UnsafeAvailChecker.isAvailable() && (enabled == null || Boolean.parseBoolean(enabled))) {
+    if (HBasePlatformDependent.isUnsafeAvailable() &&
+      (enabled == null || Boolean.parseBoolean(enabled))) {
       LOG.debug("Using Unsafe to estimate memory layout");
       return new UnsafeLayout();
     }
diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/UnsafeAccess.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/UnsafeAccess.java
index 9c4b1ec..ed40106 100644
--- a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/UnsafeAccess.java
+++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/UnsafeAccess.java
@@ -17,61 +17,37 @@
  */
 package org.apache.hadoop.hbase.util;
 
-import java.lang.reflect.Field;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
+import org.apache.hadoop.hbase.unsafe.HBasePlatformDependent;
 import org.apache.yetus.audience.InterfaceAudience;
 import org.apache.yetus.audience.InterfaceStability;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import sun.misc.Unsafe;
-import sun.nio.ch.DirectBuffer;
+import org.apache.hbase.thirdparty.io.netty.util.internal.PlatformDependent;
 
 @InterfaceAudience.Private
 @InterfaceStability.Evolving
 public final class UnsafeAccess {
 
-  private static final Logger LOG = LoggerFactory.getLogger(UnsafeAccess.class);
-
-  public static final Unsafe theUnsafe;
-
   /** The offset to the first element in a byte array. */
   public static final long BYTE_ARRAY_BASE_OFFSET;
 
-  public static final boolean LITTLE_ENDIAN = ByteOrder.nativeOrder()
-      .equals(ByteOrder.LITTLE_ENDIAN);
+  public static final boolean LITTLE_ENDIAN =
+    ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN);
 
   // This number limits the number of bytes to copy per call to Unsafe's
   // copyMemory method. A limit is imposed to allow for safepoint polling
   // during a large copy
   static final long UNSAFE_COPY_THRESHOLD = 1024L * 1024L;
   static {
-    theUnsafe = (Unsafe) AccessController.doPrivileged(new PrivilegedAction<Object>() {
-      @Override
-      public Object run() {
-        try {
-          Field f = Unsafe.class.getDeclaredField("theUnsafe");
-          f.setAccessible(true);
-          return f.get(null);
-        } catch (Throwable e) {
-          LOG.warn("sun.misc.Unsafe is not accessible", e);
-        }
-        return null;
-      }
-    });
-
-    if (theUnsafe != null) {
-      BYTE_ARRAY_BASE_OFFSET = theUnsafe.arrayBaseOffset(byte[].class);
-    } else{
+    if (HBasePlatformDependent.isUnsafeAvailable()) {
+      BYTE_ARRAY_BASE_OFFSET = HBasePlatformDependent.arrayBaseOffset(byte[].class);
+    } else {
       BYTE_ARRAY_BASE_OFFSET = -1;
     }
   }
 
-  private UnsafeAccess(){}
+  private UnsafeAccess() {
+  }
 
   // APIs to read primitive data from a byte[] using Unsafe way
   /**
@@ -82,9 +58,10 @@ public final class UnsafeAccess {
    */
   public static short toShort(byte[] bytes, int offset) {
     if (LITTLE_ENDIAN) {
-      return Short.reverseBytes(theUnsafe.getShort(bytes, offset + BYTE_ARRAY_BASE_OFFSET));
+      return Short
+        .reverseBytes(HBasePlatformDependent.getShort(bytes, offset + BYTE_ARRAY_BASE_OFFSET));
     } else {
-      return theUnsafe.getShort(bytes, offset + BYTE_ARRAY_BASE_OFFSET);
+      return HBasePlatformDependent.getShort(bytes, offset + BYTE_ARRAY_BASE_OFFSET);
     }
   }
 
@@ -96,9 +73,10 @@ public final class UnsafeAccess {
    */
   public static int toInt(byte[] bytes, int offset) {
     if (LITTLE_ENDIAN) {
-      return Integer.reverseBytes(theUnsafe.getInt(bytes, offset + BYTE_ARRAY_BASE_OFFSET));
+      return Integer
+        .reverseBytes(HBasePlatformDependent.getInt(bytes, offset + BYTE_ARRAY_BASE_OFFSET));
     } else {
-      return theUnsafe.getInt(bytes, offset + BYTE_ARRAY_BASE_OFFSET);
+      return HBasePlatformDependent.getInt(bytes, offset + BYTE_ARRAY_BASE_OFFSET);
     }
   }
 
@@ -110,9 +88,10 @@ public final class UnsafeAccess {
    */
   public static long toLong(byte[] bytes, int offset) {
     if (LITTLE_ENDIAN) {
-      return Long.reverseBytes(theUnsafe.getLong(bytes, offset + BYTE_ARRAY_BASE_OFFSET));
+      return Long
+        .reverseBytes(HBasePlatformDependent.getLong(bytes, offset + BYTE_ARRAY_BASE_OFFSET));
     } else {
-      return theUnsafe.getLong(bytes, offset + BYTE_ARRAY_BASE_OFFSET);
+      return HBasePlatformDependent.getLong(bytes, offset + BYTE_ARRAY_BASE_OFFSET);
     }
   }
 
@@ -128,7 +107,7 @@ public final class UnsafeAccess {
     if (LITTLE_ENDIAN) {
       val = Short.reverseBytes(val);
     }
-    theUnsafe.putShort(bytes, offset + BYTE_ARRAY_BASE_OFFSET, val);
+    HBasePlatformDependent.putShort(bytes, offset + BYTE_ARRAY_BASE_OFFSET, val);
     return offset + Bytes.SIZEOF_SHORT;
   }
 
@@ -143,7 +122,7 @@ public final class UnsafeAccess {
     if (LITTLE_ENDIAN) {
       val = Integer.reverseBytes(val);
     }
-    theUnsafe.putInt(bytes, offset + BYTE_ARRAY_BASE_OFFSET, val);
+    HBasePlatformDependent.putInt(bytes, offset + BYTE_ARRAY_BASE_OFFSET, val);
     return offset + Bytes.SIZEOF_INT;
   }
 
@@ -158,7 +137,7 @@ public final class UnsafeAccess {
     if (LITTLE_ENDIAN) {
       val = Long.reverseBytes(val);
     }
-    theUnsafe.putLong(bytes, offset + BYTE_ARRAY_BASE_OFFSET, val);
+    HBasePlatformDependent.putLong(bytes, offset + BYTE_ARRAY_BASE_OFFSET, val);
     return offset + Bytes.SIZEOF_LONG;
   }
 
@@ -166,9 +145,6 @@ public final class UnsafeAccess {
   /**
    * Reads a short value at the given buffer's offset considering it was written in big-endian
    * format.
-   *
-   * @param buf
-   * @param offset
    * @return short value at offset
    */
   public static short toShort(ByteBuffer buf, int offset) {
@@ -181,36 +157,30 @@ public final class UnsafeAccess {
   /**
    * Reads a short value at the given Object's offset considering it was written in big-endian
    * format.
-   * @param ref
-   * @param offset
    * @return short value at offset
    */
   public static short toShort(Object ref, long offset) {
     if (LITTLE_ENDIAN) {
-      return Short.reverseBytes(theUnsafe.getShort(ref, offset));
+      return Short.reverseBytes(HBasePlatformDependent.getShort(ref, offset));
     }
-    return theUnsafe.getShort(ref, offset);
+    return HBasePlatformDependent.getShort(ref, offset);
   }
 
   /**
    * Reads bytes at the given offset as a short value.
-   * @param buf
-   * @param offset
    * @return short value at offset
    */
-  static short getAsShort(ByteBuffer buf, int offset) {
+  private static short getAsShort(ByteBuffer buf, int offset) {
     if (buf.isDirect()) {
-      return theUnsafe.getShort(((DirectBuffer) buf).address() + offset);
+      return HBasePlatformDependent.getShort(directBufferAddress(buf) + offset);
     }
-    return theUnsafe.getShort(buf.array(), BYTE_ARRAY_BASE_OFFSET + buf.arrayOffset() + offset);
+    return HBasePlatformDependent.getShort(buf.array(),
+      BYTE_ARRAY_BASE_OFFSET + buf.arrayOffset() + offset);
   }
 
   /**
    * Reads an int value at the given buffer's offset considering it was written in big-endian
    * format.
-   *
-   * @param buf
-   * @param offset
    * @return int value at offset
    */
   public static int toInt(ByteBuffer buf, int offset) {
@@ -221,38 +191,33 @@ public final class UnsafeAccess {
   }
 
   /**
-   * Reads a int value at the given Object's offset considering it was written in big-endian
-   * format.
+   * Reads a int value at the given Object's offset considering it was written in big-endian format.
    * @param ref
    * @param offset
    * @return int value at offset
    */
   public static int toInt(Object ref, long offset) {
     if (LITTLE_ENDIAN) {
-      return Integer.reverseBytes(theUnsafe.getInt(ref, offset));
+      return Integer.reverseBytes(HBasePlatformDependent.getInt(ref, offset));
     }
-    return theUnsafe.getInt(ref, offset);
+    return HBasePlatformDependent.getInt(ref, offset);
   }
 
   /**
    * Reads bytes at the given offset as an int value.
-   * @param buf
-   * @param offset
    * @return int value at offset
    */
-  static int getAsInt(ByteBuffer buf, int offset) {
+  private static int getAsInt(ByteBuffer buf, int offset) {
     if (buf.isDirect()) {
-      return theUnsafe.getInt(((DirectBuffer) buf).address() + offset);
+      return HBasePlatformDependent.getInt(directBufferAddress(buf) + offset);
     }
-    return theUnsafe.getInt(buf.array(), BYTE_ARRAY_BASE_OFFSET + buf.arrayOffset() + offset);
+    return HBasePlatformDependent.getInt(buf.array(),
+      BYTE_ARRAY_BASE_OFFSET + buf.arrayOffset() + offset);
   }
 
   /**
    * Reads a long value at the given buffer's offset considering it was written in big-endian
    * format.
-   *
-   * @param buf
-   * @param offset
    * @return long value at offset
    */
   public static long toLong(ByteBuffer buf, int offset) {
@@ -265,28 +230,48 @@ public final class UnsafeAccess {
   /**
    * Reads a long value at the given Object's offset considering it was written in big-endian
    * format.
-   * @param ref
-   * @param offset
    * @return long value at offset
    */
   public static long toLong(Object ref, long offset) {
     if (LITTLE_ENDIAN) {
-      return Long.reverseBytes(theUnsafe.getLong(ref, offset));
+      return Long.reverseBytes(HBasePlatformDependent.getLong(ref, offset));
     }
-    return theUnsafe.getLong(ref, offset);
+    return HBasePlatformDependent.getLong(ref, offset);
   }
 
   /**
    * Reads bytes at the given offset as a long value.
-   * @param buf
-   * @param offset
    * @return long value at offset
    */
-  static long getAsLong(ByteBuffer buf, int offset) {
+  private static long getAsLong(ByteBuffer buf, int offset) {
     if (buf.isDirect()) {
-      return theUnsafe.getLong(((DirectBuffer) buf).address() + offset);
+      return HBasePlatformDependent.getLong(directBufferAddress(buf) + offset);
     }
-    return theUnsafe.getLong(buf.array(), BYTE_ARRAY_BASE_OFFSET + buf.arrayOffset() + offset);
+    return HBasePlatformDependent.getLong(buf.array(),
+      BYTE_ARRAY_BASE_OFFSET + buf.arrayOffset() + offset);
+  }
+
+  /**
+   * Returns the byte at the given offset
+   * @param buf the buffer to read
+   * @param offset the offset at which the byte has to be read
+   * @return the byte at the given offset
+   */
+  public static byte toByte(ByteBuffer buf, int offset) {
+    if (buf.isDirect()) {
+      return HBasePlatformDependent.getByte(directBufferAddress(buf) + offset);
+    } else {
+      return HBasePlatformDependent.getByte(buf.array(),
+        BYTE_ARRAY_BASE_OFFSET + buf.arrayOffset() + offset);
+    }
+  }
+
+  /**
+   * Returns the byte at the given offset of the object
+   * @return the byte at the given offset
+   */
+  public static byte toByte(Object ref, long offset) {
+    return HBasePlatformDependent.getByte(ref, offset);
   }
 
   /**
@@ -301,9 +286,10 @@ public final class UnsafeAccess {
       val = Integer.reverseBytes(val);
     }
     if (buf.isDirect()) {
-      theUnsafe.putInt(((DirectBuffer) buf).address() + offset, val);
+      HBasePlatformDependent.putInt(directBufferAddress(buf) + offset, val);
     } else {
-      theUnsafe.putInt(buf.array(), offset + buf.arrayOffset() + BYTE_ARRAY_BASE_OFFSET, val);
+      HBasePlatformDependent.putInt(buf.array(),
+        offset + buf.arrayOffset() + BYTE_ARRAY_BASE_OFFSET, val);
     }
     return offset + Bytes.SIZEOF_INT;
   }
@@ -321,7 +307,7 @@ public final class UnsafeAccess {
     long destAddress = destOffset;
     Object destBase = null;
     if (dest.isDirect()) {
-      destAddress = destAddress + ((DirectBuffer) dest).address();
+      destAddress = destAddress + directBufferAddress(dest);
     } else {
       destAddress = destAddress + BYTE_ARRAY_BASE_OFFSET + dest.arrayOffset();
       destBase = dest.array();
@@ -333,7 +319,7 @@ public final class UnsafeAccess {
   private static void unsafeCopy(Object src, long srcAddr, Object dst, long destAddr, long len) {
     while (len > 0) {
       long size = (len > UNSAFE_COPY_THRESHOLD) ? UNSAFE_COPY_THRESHOLD : len;
-      theUnsafe.copyMemory(src, srcAddr, dst, destAddr, size);
+      HBasePlatformDependent.copyMemory(src, srcAddr, dst, destAddr, size);
       len -= size;
       srcAddr += size;
       destAddr += size;
@@ -343,19 +329,17 @@ public final class UnsafeAccess {
   /**
    * Copies specified number of bytes from given offset of {@code src} ByteBuffer to the
    * {@code dest} array.
-   *
    * @param src source buffer
    * @param srcOffset offset into source buffer
    * @param dest destination array
    * @param destOffset offset into destination buffer
    * @param length length of data to copy
    */
-  public static void copy(ByteBuffer src, int srcOffset, byte[] dest, int destOffset,
-      int length) {
+  public static void copy(ByteBuffer src, int srcOffset, byte[] dest, int destOffset, int length) {
     long srcAddress = srcOffset;
     Object srcBase = null;
     if (src.isDirect()) {
-      srcAddress = srcAddress + ((DirectBuffer) src).address();
+      srcAddress = srcAddress + directBufferAddress(src);
     } else {
       srcAddress = srcAddress + BYTE_ARRAY_BASE_OFFSET + src.arrayOffset();
       srcBase = src.array();
@@ -367,7 +351,6 @@ public final class UnsafeAccess {
   /**
    * Copies specified number of bytes from given offset of {@code src} buffer into the {@code dest}
    * buffer.
-   *
    * @param src source buffer
    * @param srcOffset offset into source buffer
    * @param dest destination buffer
@@ -375,17 +358,17 @@ public final class UnsafeAccess {
    * @param length length of data to copy
    */
   public static void copy(ByteBuffer src, int srcOffset, ByteBuffer dest, int destOffset,
-      int length) {
+    int length) {
     long srcAddress, destAddress;
     Object srcBase = null, destBase = null;
     if (src.isDirect()) {
-      srcAddress = srcOffset + ((DirectBuffer) src).address();
+      srcAddress = srcOffset + directBufferAddress(src);
     } else {
-      srcAddress = (long) srcOffset +  src.arrayOffset() + BYTE_ARRAY_BASE_OFFSET;
+      srcAddress = (long) srcOffset + src.arrayOffset() + BYTE_ARRAY_BASE_OFFSET;
       srcBase = src.array();
     }
     if (dest.isDirect()) {
-      destAddress = destOffset + ((DirectBuffer) dest).address();
+      destAddress = destOffset + directBufferAddress(dest);
     } else {
       destAddress = destOffset + BYTE_ARRAY_BASE_OFFSET + dest.arrayOffset();
       destBase = dest.array();
@@ -406,9 +389,10 @@ public final class UnsafeAccess {
       val = Short.reverseBytes(val);
     }
     if (buf.isDirect()) {
-      theUnsafe.putShort(((DirectBuffer) buf).address() + offset, val);
+      HBasePlatformDependent.putShort(directBufferAddress(buf) + offset, val);
     } else {
-      theUnsafe.putShort(buf.array(), BYTE_ARRAY_BASE_OFFSET + buf.arrayOffset() + offset, val);
+      HBasePlatformDependent.putShort(buf.array(),
+        BYTE_ARRAY_BASE_OFFSET + buf.arrayOffset() + offset, val);
     }
     return offset + Bytes.SIZEOF_SHORT;
   }
@@ -425,12 +409,14 @@ public final class UnsafeAccess {
       val = Long.reverseBytes(val);
     }
     if (buf.isDirect()) {
-      theUnsafe.putLong(((DirectBuffer) buf).address() + offset, val);
+      HBasePlatformDependent.putLong(directBufferAddress(buf) + offset, val);
     } else {
-      theUnsafe.putLong(buf.array(), BYTE_ARRAY_BASE_OFFSET + buf.arrayOffset() + offset, val);
+      HBasePlatformDependent.putLong(buf.array(),
+        BYTE_ARRAY_BASE_OFFSET + buf.arrayOffset() + offset, val);
     }
     return offset + Bytes.SIZEOF_LONG;
   }
+
   /**
    * Put a byte value out to the specified BB position in big-endian format.
    * @param buf the byte buffer
@@ -440,36 +426,20 @@ public final class UnsafeAccess {
    */
   public static int putByte(ByteBuffer buf, int offset, byte b) {
     if (buf.isDirect()) {
-      theUnsafe.putByte(((DirectBuffer) buf).address() + offset, b);
+      HBasePlatformDependent.putByte(directBufferAddress(buf) + offset, b);
     } else {
-      theUnsafe.putByte(buf.array(),
-          BYTE_ARRAY_BASE_OFFSET + buf.arrayOffset() + offset, b);
+      HBasePlatformDependent.putByte(buf.array(),
+        BYTE_ARRAY_BASE_OFFSET + buf.arrayOffset() + offset, b);
     }
     return offset + 1;
   }
 
-  /**
-   * Returns the byte at the given offset
-   * @param buf the buffer to read
-   * @param offset the offset at which the byte has to be read
-   * @return the byte at the given offset
-   */
-  public static byte toByte(ByteBuffer buf, int offset) {
-    if (buf.isDirect()) {
-      return theUnsafe.getByte(((DirectBuffer) buf).address() + offset);
-    } else {
-      return theUnsafe.getByte(buf.array(), BYTE_ARRAY_BASE_OFFSET + buf.arrayOffset() + offset);
-    }
+  public static long directBufferAddress(ByteBuffer buf) {
+    return PlatformDependent.directBufferAddress(buf);
   }
 
-  /**
-   * Returns the byte at the given offset of the object
-   * @param ref
-   * @param offset
-   * @return the byte at the given offset
-   */
-  public static byte toByte(Object ref, long offset) {
-    return theUnsafe.getByte(ref, offset);
+  public static void freeDirectBuffer(ByteBuffer buffer) {
+    // here we just use the method in netty
+    PlatformDependent.freeDirectBuffer(buffer);
   }
-
 }
diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/UnsafeAvailChecker.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/UnsafeAvailChecker.java
deleted file mode 100644
index 1213c3c..0000000
--- a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/UnsafeAvailChecker.java
+++ /dev/null
@@ -1,190 +0,0 @@
-/**
- * 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.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
-import org.apache.yetus.audience.InterfaceAudience;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@InterfaceAudience.Private
-public class UnsafeAvailChecker {
-
-  private static final String CLASS_NAME = "sun.misc.Unsafe";
-  private static final Logger LOG = LoggerFactory.getLogger(UnsafeAvailChecker.class);
-  private static boolean avail = false;
-  private static boolean unaligned = false;
-
-  static {
-    avail = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
-      @Override
-      public Boolean run() {
-        try {
-          Class<?> clazz = Class.forName(CLASS_NAME);
-          Field f = clazz.getDeclaredField("theUnsafe");
-          f.setAccessible(true);
-          Object theUnsafe = f.get(null);
-          if (theUnsafe == null) {
-            LOG.warn("Could not get static instance from sun.misc.Unsafe");
-            return false;
-          }
-          // Check for availability of all methods used by UnsafeAccess
-          Method m;
-          try {
-            m = clazz.getDeclaredMethod("arrayBaseOffset", Class.class);
-            if (m == null) {
-              LOG.warn("sun.misc.Unsafe is missing arrayBaseOffset(Class)");
-              return false;
-            }
-            m = clazz.getDeclaredMethod("copyMemory", Object.class, long.class, Object.class,
-              long.class, long.class);
-            if (m == null) {
-              LOG.warn("sun.misc.Unsafe is missing copyMemory(Object,long,Object,long,long)");
-              return false;
-            }
-            m = clazz.getDeclaredMethod("getByte", Object.class, long.class);
-            if (m == null) {
-              LOG.warn("sun.misc.Unsafe is missing getByte(Object,long)");
-              return false;
-            }
-            m = clazz.getDeclaredMethod("getShort", long.class);
-            if (m == null) {
-              LOG.warn("sun.misc.Unsafe is missing getShort(long)");
-              return false;
-            }
-            m = clazz.getDeclaredMethod("getShort", Object.class, long.class);
-            if (m == null) {
-              LOG.warn("sun.misc.Unsafe is missing getShort(Object,long)");
-              return false;
-            }
-            m = clazz.getDeclaredMethod("getInt", long.class);
-            if (m == null) {
-              LOG.warn("sun.misc.Unsafe is missing getInt(long)");
-              return false;
-            }
-            m = clazz.getDeclaredMethod("getInt", Object.class, long.class);
-            if (m == null) {
-              LOG.warn("sun.misc.Unsafe is missing getInt(Object,long)");
-              return false;
-            }
-            m = clazz.getDeclaredMethod("getLong", long.class);
-            if (m == null) {
-              LOG.warn("sun.misc.Unsafe is missing getLong(long)");
-              return false;
-            }
-            m = clazz.getDeclaredMethod("getLong", Object.class, long.class);
-            if (m == null) {
-              LOG.warn("sun.misc.Unsafe is missing getLong(Object,long)");
-              return false;
-            }
-            m = clazz.getDeclaredMethod("putByte", long.class, byte.class);
-            if (m == null) {
-              LOG.warn("sun.misc.Unsafe is missing putByte(long,byte)");
-              return false;
-            }
-            m = clazz.getDeclaredMethod("putByte", Object.class, long.class, byte.class);
-            if (m == null) {
-              LOG.warn("sun.misc.Unsafe is missing putByte(Object,long,byte)");
-              return false;
-            }
-            m = clazz.getDeclaredMethod("putShort", long.class, short.class);
-            if (m == null) {
-              LOG.warn("sun.misc.Unsafe is missing putShort(long,short)");
-              return false;
-            }
-            m = clazz.getDeclaredMethod("putShort", Object.class, long.class, short.class);
-            if (m == null) {
-              LOG.warn("sun.misc.Unsafe is missing putShort(Object,long,short)");
-              return false;
-            }
-            m = clazz.getDeclaredMethod("putInt", long.class, int.class);
-            if (m == null) {
-              LOG.warn("sun.misc.Unsafe is missing putInt(long,int)");
-              return false;
-            }
-            m = clazz.getDeclaredMethod("putInt", Object.class, long.class, int.class);
-            if (m == null) {
-              LOG.warn("sun.misc.Unsafe is missing putInt(Object,long,int)");
-              return false;
-            }
-            m = clazz.getDeclaredMethod("putLong", long.class, long.class);
-            if (m == null) {
-              LOG.warn("sun.misc.Unsafe is missing putLong(long,long)");
-              return false;
-            }
-            m = clazz.getDeclaredMethod("putLong", Object.class, long.class, long.class);
-            if (m == null) {
-              LOG.warn("sun.misc.Unsafe is missing putLong(Object,long,long)");
-              return false;
-            }
-            // theUnsafe is accessible and all methods are available
-            return true;
-          } catch (Throwable e) {
-            LOG.warn("sun.misc.Unsafe is missing one or more required methods", e);
-          }
-        } catch (Throwable e) {
-          LOG.warn("sun.misc.Unsafe is not available/accessible", e);
-        }
-        return false;
-      }
-    });
-    // When Unsafe itself is not available/accessible consider unaligned as false.
-    if (avail) {
-      String arch = System.getProperty("os.arch");
-      if ("ppc64".equals(arch) || "ppc64le".equals(arch) || "aarch64".equals(arch)) {
-        // java.nio.Bits.unaligned() wrongly returns false on ppc (JDK-8165231),
-        unaligned = true;
-      } else {
-        try {
-          // Using java.nio.Bits#unaligned() to check for unaligned-access capability
-          Class<?> clazz = Class.forName("java.nio.Bits");
-          Method m = clazz.getDeclaredMethod("unaligned");
-          m.setAccessible(true);
-          unaligned = (Boolean) m.invoke(null);
-        } catch (Exception e) {
-          LOG.warn("java.nio.Bits#unaligned() check failed."
-              + "Unsafe based read/write of primitive types won't be used", e);
-        }
-      }
-    }
-  }
-
-  /**
-   * @return true when running JVM is having sun's Unsafe package available in it and it is
-   *         accessible.
-   */
-  public static boolean isAvailable() {
-    return avail;
-  }
-
-  /**
-   * @return true when running JVM is having sun's Unsafe package available in it and underlying
-   *         system having unaligned-access capability.
-   */
-  public static boolean unaligned() {
-    return unaligned;
-  }
-
-  private UnsafeAvailChecker() {
-    // private constructor to avoid instantiation
-  }
-}
diff --git a/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestByteBufferUtils.java b/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestByteBufferUtils.java
index 4777ee6..dcfede9 100644
--- a/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestByteBufferUtils.java
+++ b/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestByteBufferUtils.java
@@ -22,6 +22,7 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
+
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.DataInputStream;
@@ -48,6 +49,7 @@ import org.apache.hadoop.hbase.HBaseCommonTestingUtil;
 import org.apache.hadoop.hbase.HConstants;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.testclassification.MiscTests;
+import org.apache.hadoop.hbase.unsafe.HBasePlatformDependent;
 import org.apache.hadoop.io.WritableUtils;
 import org.junit.AfterClass;
 import org.junit.Before;
@@ -105,14 +107,14 @@ public class TestByteBufferUtils {
   }
 
   static void detectAvailabilityOfUnsafe() throws Exception {
-    if (ByteBufferUtils.UNSAFE_AVAIL != UnsafeAvailChecker.isAvailable()) {
-      setUnsafe(UNSAFE_AVAIL_NAME, UnsafeAvailChecker.isAvailable());
+    if (ByteBufferUtils.UNSAFE_AVAIL != HBasePlatformDependent.isUnsafeAvailable()) {
+      setUnsafe(UNSAFE_AVAIL_NAME, HBasePlatformDependent.isUnsafeAvailable());
     }
-    if (ByteBufferUtils.UNSAFE_UNALIGNED != UnsafeAvailChecker.unaligned()) {
-      setUnsafe(UNSAFE_UNALIGNED_NAME, UnsafeAvailChecker.unaligned());
+    if (ByteBufferUtils.UNSAFE_UNALIGNED != HBasePlatformDependent.unaligned()) {
+      setUnsafe(UNSAFE_UNALIGNED_NAME, HBasePlatformDependent.unaligned());
     }
-    assertEquals(ByteBufferUtils.UNSAFE_AVAIL, UnsafeAvailChecker.isAvailable());
-    assertEquals(ByteBufferUtils.UNSAFE_UNALIGNED, UnsafeAvailChecker.unaligned());
+    assertEquals(ByteBufferUtils.UNSAFE_AVAIL, HBasePlatformDependent.isUnsafeAvailable());
+    assertEquals(ByteBufferUtils.UNSAFE_UNALIGNED, HBasePlatformDependent.unaligned());
   }
 
   public TestByteBufferUtils(boolean useUnsafeIfPossible) throws Exception {
diff --git a/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestBytes.java b/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestBytes.java
index 80e2c35..11be830 100644
--- a/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestBytes.java
+++ b/hbase-common/src/test/java/org/apache/hadoop/hbase/util/TestBytes.java
@@ -43,6 +43,7 @@ import java.util.concurrent.ThreadLocalRandom;
 import org.apache.hadoop.hbase.HBaseClassTestRule;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.testclassification.MiscTests;
+import org.apache.hadoop.hbase.unsafe.HBasePlatformDependent;
 import org.apache.hadoop.io.WritableUtils;
 import org.junit.Assert;
 import org.junit.ClassRule;
@@ -96,7 +97,7 @@ public class TestBytes {
         assertEquals(Bytes.toShort(bytes, 0, bytes.length), n);
       }
     } finally {
-      setUnsafe(UnsafeAvailChecker.unaligned());
+      setUnsafe(HBasePlatformDependent.unaligned());
     }
   }
 
diff --git a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestRESTServerSSL.java b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestRESTServerSSL.java
index 48e00d1..4201c32 100644
--- a/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestRESTServerSSL.java
+++ b/hbase-rest/src/test/java/org/apache/hadoop/hbase/rest/TestRESTServerSSL.java
@@ -19,6 +19,7 @@ package org.apache.hadoop.hbase.rest;
 
 import static org.junit.Assert.assertEquals;
 import java.io.File;
+import java.lang.reflect.Method;
 import java.security.KeyPair;
 import java.security.cert.X509Certificate;
 import java.util.Optional;
@@ -38,7 +39,8 @@ import org.junit.BeforeClass;
 import org.junit.ClassRule;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
-import sun.security.x509.AlgorithmId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 @Category({ RestTests.class, MediumTests.class})
 public class TestRESTServerSSL {
@@ -47,6 +49,8 @@ public class TestRESTServerSSL {
   public static final HBaseClassTestRule CLASS_RULE =
       HBaseClassTestRule.forClass(TestRESTServerSSL.class);
 
+  private static final Logger LOG = LoggerFactory.getLogger(TestRESTServerSSL.class);
+
   private static final String KEY_STORE_PASSWORD = "myKSPassword";
   private static final String TRUST_STORE_PASSWORD = "myTSPassword";
 
@@ -56,12 +60,23 @@ public class TestRESTServerSSL {
   private static File keyDir;
   private Configuration conf;
 
+  // Workaround for jdk8 292 bug. See https://github.com/bcgit/bc-java/issues/941
+  // Below is a workaround described in above URL. Issue fingered first in comments in
+  // HBASE-25920 Support Hadoop 3.3.1
+  private static void initializeAlgorithmId() {
+    try {
+      Class<?> algoId = Class.forName("sun.security.x509.AlgorithmId");
+      Method method = algoId.getMethod("get", String.class);
+      method.setAccessible(true);
+      method.invoke(null, "PBEWithSHA1AndDESede");
+    } catch (Exception e) {
+      LOG.warn("failed to initialize AlgorithmId", e);
+    }
+  }
+
   @BeforeClass
   public static void beforeClass() throws Exception {
-    // Workaround for jdk8 252 bug. See https://github.com/bcgit/bc-java/issues/941
-    // Below is a workaround described in above URL. Issue fingered first in comments in
-    // HBASE-25920 Support Hadoop 3.3.1
-    AlgorithmId.get("PBEWithSHA1AndDESede");
+    initializeAlgorithmId();
     keyDir = initKeystoreDir();
     KeyPair keyPair = KeyStoreTestUtil.generateKeyPair("RSA");
     X509Certificate serverCertificate = KeyStoreTestUtil.generateCertificate(
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/HBaseServerBase.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/HBaseServerBase.java
index fec496b..c28ea29 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/HBaseServerBase.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/HBaseServerBase.java
@@ -56,6 +56,7 @@ import org.apache.hadoop.hbase.security.User;
 import org.apache.hadoop.hbase.security.UserProvider;
 import org.apache.hadoop.hbase.security.access.AccessChecker;
 import org.apache.hadoop.hbase.security.access.ZKPermissionWatcher;
+import org.apache.hadoop.hbase.unsafe.HBasePlatformDependent;
 import org.apache.hadoop.hbase.util.Addressing;
 import org.apache.hadoop.hbase.util.CommonFSUtils;
 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
@@ -69,7 +70,6 @@ import org.apache.hadoop.hbase.zookeeper.ZKWatcher;
 import org.apache.yetus.audience.InterfaceAudience;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import sun.misc.Signal;
 
 /**
  * Base class for hbase services, such as master or region server.
@@ -179,7 +179,7 @@ public abstract class HBaseServerBase<R extends HBaseRpcServicesBase<?>> extends
    */
   private static void setupWindows(final Configuration conf, ConfigurationManager cm) {
     if (!SystemUtils.IS_OS_WINDOWS) {
-      Signal.handle(new Signal("HUP"), signal -> {
+      HBasePlatformDependent.handle("HUP", (number, name) -> {
         conf.reloadConfiguration();
         cm.notifyAllObservers(conf);
       });
diff --git a/pom.xml b/pom.xml
index cbe9b31..bbd5426 100755
--- a/pom.xml
+++ b/pom.xml
@@ -1732,6 +1732,7 @@
     </maven.build.timestamp.format>
     <buildDate>${maven.build.timestamp}</buildDate>
     <compileSource>1.8</compileSource>
+    <releaseTarget>8</releaseTarget>
     <!-- Build dependencies -->
     <maven.min.version>3.0.4</maven.min.version>
     <java.min.version>${compileSource}</java.min.version>
@@ -1761,8 +1762,8 @@
     <httpclient.version>4.5.3</httpclient.version>
     <httpcore.version>4.4.13</httpcore.version>
     <metrics-core.version>3.2.6</metrics-core.version>
-    <jackson.version>2.10.1</jackson.version>
-    <jackson.databind.version>2.10.1</jackson.databind.version>
+    <jackson.version>2.13.1</jackson.version>
+    <jackson.databind.version>2.13.1</jackson.databind.version>
     <jaxb-api.version>2.3.1</jaxb-api.version>
     <servlet.api.version>3.1.0</servlet.api.version>
     <wx.rs.api.version>2.1.1</wx.rs.api.version>
@@ -1826,7 +1827,7 @@
     <snappy.version>1.1.8.4</snappy.version>
     <xz.version>1.9</xz.version>
     <zstd-jni.version>1.5.0-4</zstd-jni.version>
-    <hbase-thirdparty.version>4.0.1</hbase-thirdparty.version>
+    <hbase-thirdparty.version>4.1.0</hbase-thirdparty.version>
     <!-- Intraproject jar naming properties -->
     <!-- TODO this is pretty ugly, but works for the moment.
       Modules are pretty heavy-weight things, so doing this work isn't too bad. -->
@@ -2662,6 +2663,11 @@
         <version>${hbase-thirdparty.version}</version>
       </dependency>
       <dependency>
+        <groupId>org.apache.hbase.thirdparty</groupId>
+        <artifactId>hbase-unsafe</artifactId>
+        <version>${hbase-thirdparty.version}</version>
+      </dependency>
+      <dependency>
         <groupId>com.sun.xml.ws</groupId>
           <artifactId>jaxws-ri</artifactId>
         <version>2.3.2</version>
@@ -2731,6 +2737,7 @@
         <jdk>[1.11,)</jdk>
       </activation>
       <properties>
+        <maven.compiler.release>${releaseTarget}</maven.compiler.release>
         <!-- TODO: replicate logic for windows support -->
         <argLine>--add-opens=java.base/jdk.internal.ref=ALL-UNNAMED ${hbase-surefire.argLine}</argLine>
         <!-- We need a minimum HDFS version of 3.2.0 for HADOOP-12760 -->