You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hugegraph.apache.org by je...@apache.org on 2022/04/24 15:28:41 UTC
[incubator-hugegraph-commons] branch Whitebox-setInternalFinalState created (now 6b0d97e)
This is an automated email from the ASF dual-hosted git repository.
jermy pushed a change to branch Whitebox-setInternalFinalState
in repository https://gitbox.apache.org/repos/asf/incubator-hugegraph-commons.git
at 6b0d97e add Whitebox.setInternalFinalState()
This branch includes the following new commits:
new 6b0d97e add Whitebox.setInternalFinalState()
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
[incubator-hugegraph-commons] 01/01: add Whitebox.setInternalFinalState()
Posted by je...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
jermy pushed a commit to branch Whitebox-setInternalFinalState
in repository https://gitbox.apache.org/repos/asf/incubator-hugegraph-commons.git
commit 6b0d97eb4ee3c291beff944c3996f61172e009c7
Author: Zhangmei Li <li...@baidu.com>
AuthorDate: Sun Apr 24 22:59:40 2022 +0800
add Whitebox.setInternalFinalState()
Change-Id: I2e2fd25d95dc3033ac1fa332fe6ed56b3c259758
---
.../com/baidu/hugegraph/testutil/Whitebox.java | 48 +++++++++++++++++--
.../com/baidu/hugegraph/testutil/WhiteboxTest.java | 55 ++++++++++++++++++++++
2 files changed, 100 insertions(+), 3 deletions(-)
diff --git a/hugegraph-common/src/main/java/com/baidu/hugegraph/testutil/Whitebox.java b/hugegraph-common/src/main/java/com/baidu/hugegraph/testutil/Whitebox.java
index 0d7c7c4..b947314 100644
--- a/hugegraph-common/src/main/java/com/baidu/hugegraph/testutil/Whitebox.java
+++ b/hugegraph-common/src/main/java/com/baidu/hugegraph/testutil/Whitebox.java
@@ -22,6 +22,7 @@ package com.baidu.hugegraph.testutil;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Objects;
@@ -32,13 +33,18 @@ public class Whitebox {
public static final char SEPARATOR = '.';
- public static void setInternalState(Object target, String fieldName,
- Object value) {
+ public static void setInternalState(Object target,
+ String fieldName, Object value) {
assert target != null;
assert fieldName != null;
int sep = fieldName.lastIndexOf(SEPARATOR);
if (sep > 0) {
- target = getInternalState(target, fieldName.substring(0, sep));
+ String prefix = fieldName.substring(0, sep);
+ Object result = getInternalState(target, prefix);
+ E.checkArgument(result != null,
+ "Can't set value on null field: `%s.%s`",
+ target, prefix);
+ target = result;
fieldName = fieldName.substring(sep + 1);
}
@@ -80,6 +86,42 @@ public class Whitebox {
}
}
+ public static void setInternalFinalState(Object target,
+ String fieldName, Object value) {
+ Class<?> c = target instanceof Class<?> ?
+ (Class<?>) target : target.getClass();
+ try {
+ Field field = c.getDeclaredField(fieldName);
+
+ // Remove final like FieldUtils.removeFinalModifier()
+ Field modifiersField = Field.class.getDeclaredField("modifiers");
+ modifiersField.setAccessible(true);
+ int oldModifiers = field.getModifiers();
+ int nonFinal = oldModifiers & ~Modifier.FINAL;
+ modifiersField.setInt(field, nonFinal);
+
+ // Reset overrideFieldAccessor
+ Field overrideFAField = Field.class.getDeclaredField("overrideFieldAccessor");
+ overrideFAField.setAccessible(true);
+ if (overrideFAField.get(field) != null) {
+ setInternalState(field, "overrideFieldAccessor", null);
+ }
+
+ try {
+ field.setAccessible(true);
+ field.set(target, value);
+ } finally {
+ // Resume old modifiers (final)
+ modifiersField.setInt(field, oldModifiers);
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new RuntimeException(String.format(
+ "Can't set value of '%s' against object '%s'",
+ fieldName, target), e);
+ }
+ }
+
private static Field getFieldFromHierarchy(Class<?> clazz, String field) {
Field f = getField(clazz, field);
while (f == null && clazz != Object.class) {
diff --git a/hugegraph-common/src/test/java/com/baidu/hugegraph/testutil/WhiteboxTest.java b/hugegraph-common/src/test/java/com/baidu/hugegraph/testutil/WhiteboxTest.java
index 92ab1af..855c6ad 100644
--- a/hugegraph-common/src/test/java/com/baidu/hugegraph/testutil/WhiteboxTest.java
+++ b/hugegraph-common/src/test/java/com/baidu/hugegraph/testutil/WhiteboxTest.java
@@ -75,6 +75,7 @@ public class WhiteboxTest {
Whitebox.setInternalState(test1, "ivalue", 11);
Assert.assertEquals(11, Whitebox.getInternalState(test1, "ivalue"));
+ Assert.assertEquals(11, test1.ivalue);
Whitebox.setInternalState(test1, "test2.fvalue", 22f);
Assert.assertEquals(22f, Whitebox.getInternalState(test1,
@@ -97,6 +98,52 @@ public class WhiteboxTest {
});
}
+ @Test
+ public void testSetInternalFinalState() {
+ Test1 test1 = newTest();
+ Assert.assertEquals(1, test1.ivalueFinal);
+
+ Whitebox.setInternalState(test1, "ivalueFinal", 2);
+ Assert.assertEquals(2, Whitebox.getInternalState(test1, "ivalueFinal"));
+ // FIXME: seems don't take effect!!!
+ Assert.assertEquals(1, test1.ivalueFinal);
+
+ Whitebox.setInternalFinalState(test1, "ivalueFinal", 3);
+ Assert.assertEquals(3, Whitebox.getInternalState(test1, "ivalueFinal"));
+ // FIXME: seems don't take effect!!!
+ Assert.assertEquals(1, test1.ivalueFinal);
+ }
+
+ @Test
+ public void testSetInternalStaticFinalState() {
+// Assert.assertThrows(RuntimeException.class, () -> {
+// Whitebox.setInternalState(Test4.class, "staticFinalValue", 11);
+// }, e -> {
+// Assert.assertContains("Can't set value of 'staticFinalValue'",
+// e.getMessage());
+// });
+
+ Assert.assertEquals(1, Test4.staticFinalValue);
+ // Can only call at the first reflect time
+ Whitebox.setInternalFinalState(Test4.class, "staticFinalValue", 11);
+ Assert.assertEquals(11, Whitebox.getInternalState(Test4.class,
+ "staticFinalValue"));
+
+ Whitebox.setInternalFinalState(Test4.class, "staticFinalValue", 12);
+ Assert.assertEquals(12, Whitebox.getInternalState(Test4.class,
+ "staticFinalValue"));
+
+ // FIXME: seems don't take effect!!!
+ Assert.assertEquals(1, Test4.staticFinalValue);
+
+ Assert.assertThrows(RuntimeException.class, () -> {
+ Whitebox.setInternalState(Test4.class, "staticFinalValue", 1);
+ }, e -> {
+ Assert.assertContains("Can't set value of 'staticFinalValue'",
+ e.getMessage());
+ });
+ }
+
@Test
public void testInvokeStatic() {
Assert.assertEquals(1, Whitebox.invokeStatic(Test1.class, "svalue"));
@@ -159,7 +206,10 @@ public class WhiteboxTest {
private static class Test1 {
private static int staticValue = 1;
+
private int ivalue = 1;
+ private final int ivalueFinal = 1;
+
private Test2 test2;
private TestSubClass test4;
@@ -218,6 +268,11 @@ public class WhiteboxTest {
}
}
+ private static class Test4 {
+
+ private static final int staticFinalValue = 1;
+ }
+
@SuppressWarnings("unused")
private static class TestSubClass extends Test1 {