This is an automated email from the ASF dual-hosted git repository.
crazyhzm pushed a commit to branch 3.3
in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/3.3 by this push:
new b18eeb7077 [OSPP 2023] JSON Compatibility Check (#12776)
b18eeb7077 is described below
commit b18eeb7077ee34fe793ad1919410bffcad5daab2
Author: hjyp <[email protected]>
AuthorDate: Fri Aug 4 10:42:38 2023 +0800
[OSPP 2023] JSON Compatibility Check (#12776)
* Initialize
* update code style
* delete redundant file
* Change position
* delete redundant import
* Add JsonCompatibilityUtils
* Delete unused import
* change funcs
* Add test case
* update color class
* add license
* fix style
---
.../dubbo/common/utils/JsonCompatibilityUtil.java | 185 ++++++++++
.../common/utils/JsonCompatibilityUtilTest.java | 384 +++++++++++++++++++++
.../dubbo/common/utils/json/AbstractObject.java | 22 ++
.../org/apache/dubbo/common/utils/json/Color.java | 51 +++
.../apache/dubbo/common/utils/json/Printer.java | 21 ++
.../org/apache/dubbo/common/utils/json/Range.java | 36 ++
.../apache/dubbo/common/utils/json/Service.java | 151 ++++++++
.../apache/dubbo/common/utils/json/Student.java | 45 +++
.../apache/dubbo/common/utils/json/Teacher.java | 53 +++
9 files changed, 948 insertions(+)
diff --git
a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/JsonCompatibilityUtil.java
b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/JsonCompatibilityUtil.java
new file mode 100644
index 0000000000..61f4bd5ad3
--- /dev/null
+++
b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/JsonCompatibilityUtil.java
@@ -0,0 +1,185 @@
+/*
+ * 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.dubbo.common.utils;
+
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.TypeVariable;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+
+public class JsonCompatibilityUtil {
+
+ private static final Logger logger =
LoggerFactory.getLogger(JsonCompatibilityUtil.class);
+
+ private static final Set<String> unsupportedClasses = new
HashSet<>(Arrays.asList("java.util.Optional", "java.util.Calendar",
"java.util.Iterator", "java.io.InputStream", "java.io.OutputStream"));
+
+
+ /**
+ * Determine whether a Class can be serialized by JSON.
+ * @param clazz Incoming Class.
+ * @return If a Class can be serialized by JSON, return true;
+ * else return false.
+ */
+ public static boolean checkClassCompatibility(Class<?> clazz) {
+ Method[] methods = clazz.getDeclaredMethods();
+
+ boolean result;
+
+ for (Method method : methods) {
+ result = checkMethodCompatibility(method);
+ if (!result) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+
+ /**
+ * Determine whether a Method can be serialized by JSON.
+ * @param method Incoming Method.
+ * @return If a Method can be serialized by JSON, return true;
+ * else return false.
+ */
+ public static boolean checkMethodCompatibility(Method method) {
+
+ boolean result;
+
+ Type[] types = method.getGenericParameterTypes();
+ List<Type> typeList = new ArrayList<>(Arrays.asList(types));
+ Type returnType = method.getGenericReturnType();
+ typeList.add(returnType);
+ for (Type type : typeList) {
+ result = checkType(type);
+ if (!result) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+
+ /**
+ * Get unsupported methods.
+ * @param clazz
+ * @return If there are unsupported methods, return them by List;
+ * else return null.
+ */
+ public static List<String> getUnsupportedMethods(Class<?> clazz) {
+ ArrayList<String> unsupportedMethods = new ArrayList<>();
+
+ Method[] methods = clazz.getDeclaredMethods();
+
+ for (Method method : methods) {
+ if (!checkMethodCompatibility(method)) {
+ unsupportedMethods.add(method.getName());
+ }
+ }
+
+ return unsupportedMethods.size() > 0 ? unsupportedMethods : null;
+ }
+
+
+ /**
+ * Determine whether a Type can be serialized by JSON.
+ * @param classType Incoming Type.
+ * @return If a Type can be serialized by JSON, return true;
+ * else return false.
+ */
+ private static boolean checkType(Type classType) {
+
+ boolean result;
+
+ if (classType instanceof TypeVariable) {
+ return true;
+ }
+
+ if (classType instanceof ParameterizedType) {
+
+ Type[] types = ((ParameterizedType)
classType).getActualTypeArguments();
+ List<Type> typeList = new ArrayList<>(Arrays.asList(types));
+ classType = ((ParameterizedType) classType).getRawType();
+ typeList.add(classType);
+ for (Type type : typeList) {
+ result = checkType(type);
+ if (!result) {
+ return false;
+ }
+ }
+ } else if (classType instanceof GenericArrayType) {
+ Type componentType = ((GenericArrayType)
classType).getGenericComponentType();
+ result = checkType(componentType);
+ return result;
+ } else if (classType instanceof Class<?> ) {
+ Class<?> clazz = (Class<?>) classType;
+
+ String className = clazz.getName();
+
+ if (clazz.isArray()) {
+ Type componentType = clazz.getComponentType();
+ result = checkType(componentType);
+ return result;
+ } else if (clazz.isPrimitive()) {
+ // deal with case of basic byte
+ return !unsupportedClasses.contains(className);
+ } else if (className.startsWith("java") ||
className.startsWith("javax")) {
+ return !unsupportedClasses.contains(className);
+ } else {
+ // deal with case of interface
+ if (clazz.isInterface()) {
+ return false;
+ }
+ // deal with case of abstract
+ if (Modifier.isAbstract(clazz.getModifiers())) {
+ return false;
+ }
+ if (clazz.isEnum()) {
+ return true;
+ }
+ // deal with case of record
+// if (clazz.isRecord()) {
+// return false;
+// }
+ // deal with field one by one
+ for (Field field : clazz.getDeclaredFields()) {
+ Type type = field.getGenericType();
+ Class<?> fieldClass = field.getType();
+ result = checkType(type);
+ if (!result) {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+ }
+
+}
diff --git
a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/JsonCompatibilityUtilTest.java
b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/JsonCompatibilityUtilTest.java
new file mode 100644
index 0000000000..965f73f9d2
--- /dev/null
+++
b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/JsonCompatibilityUtilTest.java
@@ -0,0 +1,384 @@
+/*
+ * 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.dubbo.common.utils;
+
+import org.apache.dubbo.common.utils.json.Service;
+
+import org.junit.jupiter.api.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.List;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class JsonCompatibilityUtilTest {
+
+ private static Class<?> service = Service.class;
+
+ private static final Logger logger =
LoggerFactory.getLogger(JsonCompatibilityUtil.class);
+
+ @Test
+ public void testCheckClassCompatibility() {
+ boolean res = JsonCompatibilityUtil.checkClassCompatibility(service);
+ assertFalse(res);
+ }
+
+ @Test
+ public void testGetUnsupportedMethods() {
+ List<String> res =
JsonCompatibilityUtil.getUnsupportedMethods(service);
+ assert res != null;
+ logger.info(res.toString());
+ assert (res.size() != 0);
+ }
+
+ @Test
+ public void testInt() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testInt"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testIntArr() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testIntArr"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testInteger() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testInteger"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testIntegerArr() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testIntegerArr"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testIntegerList() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testIntegerList"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testShort() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testShort"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testShortArr() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testShortArr"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testSShort() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testSShort"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testSShortArr() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testSShortArr"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testShortList() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testShortList"));
+ assertTrue(res);
+ }
+
+
+ @Test
+ public void testByte() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testByte"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testByteArr() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testByteArr"));
+ assertTrue(res);
+ }
+
+
+ @Test
+ public void testBByte() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testBByte"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testBByteArr() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testBByteArr"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testByteList() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testByteList"));
+ assertTrue(res);
+ }
+
+
+ @Test
+ public void testFloat() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testFloat"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testFloatArr() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testFloatArr"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testFFloat() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testFFloat"));
+ assertTrue(res);
+ }
+
+
+ @Test
+ public void testFloatArray() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testFloatArray"));
+ assertTrue(res);
+ }
+
+
+ @Test
+ public void testFloatList() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testFloatList"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testBoolean() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testBoolean"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testBooleanArr() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testBooleanArr"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testBBoolean() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testBBoolean"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testBooleanArray() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testBooleanArray"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testBooleanList() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testBooleanList"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testChar() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testChar"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testCharArr() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testCharArr"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testCharacter() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testCharacter"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testCharacterArr() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testCharacterArr"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testCharacterList() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testCharacterList"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testCharacterListArr() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testCharacterListArr"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testString() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testString"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testStringArr() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testStringArr"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testStringList() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testStringList"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testStringListArr() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testStringListArr"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testDate() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testDate"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testCalendar() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testCalendar"));
+ assertFalse(res);
+ }
+
+ @Test
+ public void testLocalTime() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testLocalTime"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testLocalDate() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testLocalDate"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testLocalDateTime() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testLocalDateTime"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testZoneDateTime() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testZoneDateTime"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testMap() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testMap"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testSet() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testSet"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testOptionalEmpty() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testOptionalEmpty"));
+ assertFalse(res);
+ }
+
+ @Test
+ public void testOptionalInteger() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testOptionalInteger"));
+ assertFalse(res);
+ }
+
+ @Test
+ public void testOptionalString() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testOptionalString"));
+ assertFalse(res);
+ }
+
+ @Test
+ public void testEnum() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testEnum"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testRecord() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testRecord"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testInterface() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testInterface"));
+ assertFalse(res);
+ }
+
+ @Test
+ public void testObject() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testObject"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testObjectList() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testObjectList"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testTemplate() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testTemplate"));
+ assertTrue(res);
+ }
+
+ @Test
+ public void testStream() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testStream"));
+ assertFalse(res);
+ }
+
+ @Test
+ public void testIterator() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testIterator"));
+ assertFalse(res);
+ }
+
+ @Test
+ public void testAbstract() throws NoSuchMethodException {
+ boolean res =
JsonCompatibilityUtil.checkMethodCompatibility(service.getDeclaredMethod("testAbstract"));
+ assertFalse(res);
+ }
+}
diff --git
a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/json/AbstractObject.java
b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/json/AbstractObject.java
new file mode 100644
index 0000000000..e363cb077f
--- /dev/null
+++
b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/json/AbstractObject.java
@@ -0,0 +1,22 @@
+/*
+ * 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.dubbo.common.utils.json;
+
+public abstract class AbstractObject {
+
+ public abstract String sayHello();
+}
diff --git
a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/json/Color.java
b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/json/Color.java
new file mode 100644
index 0000000000..bae247de99
--- /dev/null
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/json/Color.java
@@ -0,0 +1,51 @@
+/*
+ * 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.dubbo.common.utils.json;
+
+public enum Color {
+ RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
+
+ private String name;
+ private int index;
+
+ private Color(String name, int index) {
+ this.name = name;
+ this.index = index;
+ }
+
+ public static String getName(int index) {
+ for (Color c : Color.values()) {
+ if (c.getIndex() == index) {
+ return c.name;
+ }
+ }
+ return null;
+ }
+
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+ public int getIndex() {
+ return index;
+ }
+ public void setIndex(int index) {
+ this.index = index;
+ }
+}
diff --git
a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/json/Printer.java
b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/json/Printer.java
new file mode 100644
index 0000000000..b1958e0276
--- /dev/null
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/json/Printer.java
@@ -0,0 +1,21 @@
+/*
+ * 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.dubbo.common.utils.json;
+
+public interface Printer {
+ String print();
+}
diff --git
a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/json/Range.java
b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/json/Range.java
new file mode 100644
index 0000000000..77725bf3a6
--- /dev/null
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/json/Range.java
@@ -0,0 +1,36 @@
+/*
+ * 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.dubbo.common.utils.json;
+
+//public record Range(Integer left, Integer right) {
+// public Integer sum() {
+// return left + right;
+// }
+//}
+
+public class Range {
+ private Integer left;
+ private Integer right;
+
+ public Range(Integer left, Integer right) {
+ this.left = left;
+ this.right =right;
+ }
+ public Integer sum() {
+ return left + right;
+ }
+}
diff --git
a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/json/Service.java
b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/json/Service.java
new file mode 100644
index 0000000000..b963e6d40b
--- /dev/null
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/json/Service.java
@@ -0,0 +1,151 @@
+/*
+ * 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.dubbo.common.utils.json;
+
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.ZonedDateTime;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+
+public interface Service {
+ String sayHi(String name);
+
+ List<String> testList();
+
+ int testInt();
+
+ int[] testIntArr();
+
+ Integer testInteger();
+
+ Integer[] testIntegerArr();
+
+ List<Integer> testIntegerList();
+
+ short testShort();
+
+ short[] testShortArr();
+
+ Short testSShort();
+
+ Short[] testSShortArr();
+
+ List<Short> testShortList();
+
+ byte testByte();
+
+ byte[] testByteArr();
+
+ Byte testBByte();
+
+ Byte[] testBByteArr();
+
+ ArrayList<Byte> testByteList();
+
+ float testFloat();
+
+ float[] testFloatArr();
+
+ Float testFFloat();
+
+ Float[] testFloatArray();
+
+ List<Float> testFloatList();
+
+ boolean testBoolean();
+
+ boolean[] testBooleanArr();
+
+ Boolean testBBoolean();
+
+ Boolean[] testBooleanArray();
+
+ List<Boolean> testBooleanList();
+
+ char testChar();
+
+ char[] testCharArr();
+
+ Character testCharacter();
+
+ Character[] testCharacterArr();
+
+ List<Character> testCharacterList();
+
+ List<Character[]> testCharacterListArr();
+
+ String testString();
+
+ String[] testStringArr();
+
+ List<String> testStringList();
+
+ List<String[]> testStringListArr();
+
+ String testNull();
+
+ Date testDate();
+
+ Calendar testCalendar();
+
+ LocalTime testLocalTime();
+
+ LocalDate testLocalDate();
+
+ LocalDateTime testLocalDateTime();
+
+ ZonedDateTime testZoneDateTime();
+
+ Map<Integer, String> testMap();
+
+ Set<Integer> testSet();
+
+ Optional<Integer> testOptionalEmpty();
+
+ Optional<Integer> testOptionalInteger();
+
+ Optional<String> testOptionalString();
+
+ Color testEnum();
+
+ Range testRecord();
+
+ Printer testInterface();
+
+ Teacher testObject();
+
+ List<Teacher> testObjectList();
+
+ Student<Integer> testTemplate();
+
+ InputStream testStream() throws FileNotFoundException;
+
+ Iterator<String> testIterator();
+
+ AbstractObject testAbstract();
+
+}
diff --git
a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/json/Student.java
b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/json/Student.java
new file mode 100644
index 0000000000..992f24dd7e
--- /dev/null
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/json/Student.java
@@ -0,0 +1,45 @@
+/*
+ * 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.dubbo.common.utils.json;
+
+import java.io.Serializable;
+import java.util.List;
+
+public class Student<W> implements Serializable {
+ private Integer type;
+
+ private List<String> names;
+
+ private List<W> namesT;
+
+ private W age;
+
+ private String name;
+
+ public Student(Integer type, String name) {
+ this.type = type;
+ this.name = name;
+ }
+
+ @Override
+ public String toString() {
+ return "Student{" +
+ "type=" + type +
+ ", name='" + name + '\'' +
+ '}';
+ }
+}
diff --git
a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/json/Teacher.java
b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/json/Teacher.java
new file mode 100644
index 0000000000..5a95e17ba0
--- /dev/null
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/json/Teacher.java
@@ -0,0 +1,53 @@
+/*
+ * 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.dubbo.common.utils.json;
+
+import java.io.Serializable;
+
+public class Teacher implements Serializable {
+ private String name;
+ private Integer age;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Integer getAge() {
+ return age;
+ }
+
+ public void setAge(Integer age) {
+ this.age = age;
+ }
+
+ public Teacher(String name, Integer age) {
+ this.name = name;
+ this.age = age;
+ }
+
+ @Override
+ public String toString() {
+ return "Teacher{" +
+ "name='" + name + '\'' +
+ ", age=" + age +
+ '}';
+ }
+}