HBASE-25516 [JDK17] reflective access Field.class.getDeclaredField("modifiers") not supported (#3443)

Signed-off-by: Duo Zhang <zhangduo@apache.org>
Signed-off-by: Michael Stack <stack@apache.org>
This commit is contained in:
Wei-Chiu Chuang 2021-07-07 01:00:57 -07:00 committed by GitHub
parent 7e5a0dbebf
commit 29cd782d25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 45 additions and 5 deletions

View File

@ -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;
@ -228,4 +229,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;
}
}

View File

@ -82,7 +82,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);

View File

@ -24,6 +24,8 @@ import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
@ -49,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);

View File

@ -335,7 +335,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);

View File

@ -126,6 +126,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;
@ -2695,7 +2696,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);

View File

@ -47,6 +47,7 @@ import org.apache.hadoop.hbase.testclassification.MediumTests;
import org.apache.hadoop.hbase.testclassification.RSGroupTests;
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;
@ -282,7 +283,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);