From bfee537c944df7817f2889710c33ac4f4c7debbc Mon Sep 17 00:00:00 2001 From: Wei-Chiu Chuang Date: Wed, 7 Jul 2021 01:00:57 -0700 Subject: [PATCH] HBASE-25516 [JDK17] reflective access Field.class.getDeclaredField("modifiers") not supported (#3443) Signed-off-by: Duo Zhang Signed-off-by: Michael Stack (cherry picked from commit 29cd782d25bee0c7d59d3773e4aaf1cc8f0dccd9) --- .../hadoop/hbase/util/ReflectionUtils.java | 35 +++++++++++++++++++ .../hbase/util/TestByteBufferUtils.java | 2 +- .../apache/hadoop/hbase/util/TestBytes.java | 3 +- .../hbase/rsgroup/TestRSGroupsKillRS.java | 3 +- .../apache/hadoop/hbase/fs/HFileSystem.java | 2 +- .../hadoop/hbase/HBaseTestingUtility.java | 3 +- 6 files changed, 43 insertions(+), 5 deletions(-) diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ReflectionUtils.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ReflectionUtils.java index 025c64a05fa..a0311b1392d 100644 --- a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ReflectionUtils.java +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ReflectionUtils.java @@ -25,6 +25,7 @@ import java.lang.management.ManagementFactory; import java.lang.management.ThreadInfo; import java.lang.management.ThreadMXBean; import java.lang.reflect.Constructor; +import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.nio.charset.Charset; @@ -212,4 +213,38 @@ public class ReflectionUtils { return parameterTypes; } + public static Field getModifiersField() throws IllegalAccessException, NoSuchFieldException { + // this is copied from https://github.com/powermock/powermock/pull/1010/files to work around + // JDK 12+ + Field modifiersField = null; + try { + modifiersField = Field.class.getDeclaredField("modifiers"); + } catch (NoSuchFieldException e) { + try { + Method getDeclaredFields0 = + Class.class.getDeclaredMethod("getDeclaredFields0", boolean.class); + boolean accessibleBeforeSet = getDeclaredFields0.isAccessible(); + getDeclaredFields0.setAccessible(true); + Field[] fields = (Field[]) getDeclaredFields0.invoke(Field.class, false); + getDeclaredFields0.setAccessible(accessibleBeforeSet); + for (Field field : fields) { + if ("modifiers".equals(field.getName())) { + modifiersField = field; + break; + } + } + if (modifiersField == null) { + throw e; + } + } catch (NoSuchMethodException ex) { + e.addSuppressed(ex); + throw e; + } catch (InvocationTargetException ex) { + e.addSuppressed(ex); + throw e; + } + } + return modifiersField; + } + } 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 815cb9d6b63..6edd59c7eb5 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 @@ -84,7 +84,7 @@ public class TestByteBufferUtils { private static void setUnsafe(String fieldName, boolean value) throws Exception { Field field = ByteBufferUtils.class.getDeclaredField(fieldName); field.setAccessible(true); - Field modifiersField = Field.class.getDeclaredField("modifiers"); + Field modifiersField = ReflectionUtils.getModifiersField(); modifiersField.setAccessible(true); int oldModifiers = field.getModifiers(); modifiersField.setInt(field, oldModifiers & ~Modifier.FINAL); 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 8560863dae9..eb6f840bf09 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 @@ -51,7 +51,8 @@ public class TestBytes extends TestCase { private static void setUnsafe(boolean value) throws Exception { Field field = Bytes.class.getDeclaredField("UNSAFE_UNALIGNED"); field.setAccessible(true); - Field modifiersField = Field.class.getDeclaredField("modifiers"); + + Field modifiersField = ReflectionUtils.getModifiersField(); modifiersField.setAccessible(true); int oldModifiers = field.getModifiers(); modifiersField.setInt(field, oldModifiers & ~Modifier.FINAL); diff --git a/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupsKillRS.java b/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupsKillRS.java index 01fa82e1ca4..60bb702127c 100644 --- a/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupsKillRS.java +++ b/hbase-rsgroup/src/test/java/org/apache/hadoop/hbase/rsgroup/TestRSGroupsKillRS.java @@ -44,6 +44,7 @@ import org.apache.hadoop.hbase.net.Address; import org.apache.hadoop.hbase.testclassification.LargeTests; import org.apache.hadoop.hbase.util.Bytes; import org.apache.hadoop.hbase.util.JVMClusterUtil; +import org.apache.hadoop.hbase.util.ReflectionUtils; import org.apache.hadoop.hbase.util.VersionInfo; import org.junit.After; import org.junit.AfterClass; @@ -273,7 +274,7 @@ public class TestRSGroupsKillRS extends TestRSGroupsBase { private static void setFinalStatic(Field field, Object newValue) throws Exception { field.setAccessible(true); - Field modifiersField = Field.class.getDeclaredField("modifiers"); + Field modifiersField = ReflectionUtils.getModifiersField(); modifiersField.setAccessible(true); modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); field.set(null, newValue); diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/fs/HFileSystem.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/fs/HFileSystem.java index 03df1e94229..f02419ca90f 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/fs/HFileSystem.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/fs/HFileSystem.java @@ -321,7 +321,7 @@ public class HFileSystem extends FilterFileSystem { try { Field nf = DFSClient.class.getDeclaredField("namenode"); nf.setAccessible(true); - Field modifiersField = Field.class.getDeclaredField("modifiers"); + Field modifiersField = ReflectionUtils.getModifiersField(); modifiersField.setAccessible(true); modifiersField.setInt(nf, nf.getModifiers() & ~Modifier.FINAL); diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/HBaseTestingUtility.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/HBaseTestingUtility.java index cd6573017a2..7930e43f386 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/HBaseTestingUtility.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/HBaseTestingUtility.java @@ -129,6 +129,7 @@ import org.apache.hadoop.hbase.util.JVMClusterUtil; import org.apache.hadoop.hbase.util.JVMClusterUtil.MasterThread; import org.apache.hadoop.hbase.util.JVMClusterUtil.RegionServerThread; import org.apache.hadoop.hbase.util.Pair; +import org.apache.hadoop.hbase.util.ReflectionUtils; import org.apache.hadoop.hbase.util.RegionSplitter; import org.apache.hadoop.hbase.util.RegionSplitter.SplitAlgorithm; import org.apache.hadoop.hbase.util.RetryCounter; @@ -2668,7 +2669,7 @@ public class HBaseTestingUtility extends HBaseZKTestingUtility { logDirField = TaskLog.class.getDeclaredField("LOG_DIR"); logDirField.setAccessible(true); - Field modifiersField = Field.class.getDeclaredField("modifiers"); + Field modifiersField = ReflectionUtils.getModifiersField(); modifiersField.setAccessible(true); modifiersField.setInt(logDirField, logDirField.getModifiers() & ~Modifier.FINAL);