You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by li...@apache.org on 2022/06/16 06:54:37 UTC

[dubbo] branch 3.0 updated: [3.0] Exact json utils (#10156)

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

liujun pushed a commit to branch 3.0
in repository https://gitbox.apache.org/repos/asf/dubbo.git


The following commit(s) were added to refs/heads/3.0 by this push:
     new 675cd4bb13 [3.0] Exact json utils (#10156)
675cd4bb13 is described below

commit 675cd4bb13481c3f1c9f33d18503d084a7bcc132
Author: Albumen Kevin <jh...@gmail.com>
AuthorDate: Thu Jun 16 14:54:31 2022 +0800

    [3.0] Exact json utils (#10156)
---
 .../cluster/configurator/parser/ConfigParser.java  |  30 ++---
 .../cluster/loadbalance/LoadBalanceBaseTest.java   |   4 +-
 .../config/configcenter/DynamicConfiguration.java  |  18 +--
 .../configcenter/TreePathDynamicConfiguration.java |  12 --
 .../configcenter/nop/NopDynamicConfiguration.java  |  12 --
 .../wrapper/CompositeDynamicConfiguration.java     |   7 --
 .../dubbo/common/constants/CommonConstants.java    |   3 +-
 .../org/apache/dubbo/common/json/GsonUtils.java    |  81 ++++++++++++
 .../{utils/JsonUtils.java => json/JSON.java}       |  17 +--
 .../dubbo/common/json/impl/FastJsonImpl.java       |  51 ++++++++
 .../apache/dubbo/common/json/impl/GsonImpl.java    |  67 ++++++++++
 .../reporter/FrameworkStatusReportService.java     |  10 +-
 .../org/apache/dubbo/common/utils/IOUtils.java     |  23 +++-
 .../org/apache/dubbo/common/utils/JsonUtils.java   |  67 +++++++++-
 .../org/apache/dubbo/common/utils/StringUtils.java |  30 +++--
 .../definition/ServiceDefinitionBuilder.java       |   6 +-
 .../AbstractDynamicConfigurationTest.java          |  11 +-
 .../file/FileSystemDynamicConfigurationTest.java   |  26 ++--
 .../apache/dubbo/common/json/GsonUtilsTest.java    |  93 ++++++++++++++
 .../reporter/FrameworkStatusReportServiceTest.java |   9 +-
 .../apache/dubbo/common/utils/JsonUtilsTest.java   | 138 +++++++++++++++++++++
 .../dubbo/metadata/definition/MetadataTest.java    |  19 +--
 .../apache/dubbo/generic/GenericServiceTest.java   |  12 +-
 ...dataServiceURLParamsMetadataCustomizerTest.java |   7 +-
 .../support/apollo/EmbeddedApolloJunit5.java       |  16 +--
 .../support/nacos/NacosDynamicConfiguration.java   |  89 +------------
 .../nacos/NacosDynamicConfigurationTest.java       |  25 ++--
 .../ZookeeperDynamicConfigurationTest.java         |  37 +++---
 .../dubbo/demo/consumer/GenericApplication.java    |   7 +-
 dubbo-metadata/dubbo-metadata-api/pom.xml          |   5 -
 .../dubbo/metadata/AbstractCacheManager.java       |   2 +-
 .../apache/dubbo/metadata/MappingCacheManager.java |   9 +-
 .../org/apache/dubbo/metadata/MetadataInfo.java    |   2 +-
 .../report/support/AbstractMetadataReport.java     |  22 ++--
 .../rest/ClassPathServiceRestMetadataReader.java   |  20 +--
 .../dubbo/metadata/rest/RequestMetadata.java       |   7 +-
 .../apache/dubbo/metadata/MetadataInfoTest.java    |   7 +-
 .../support/AbstractMetadataReportFactoryTest.java |   6 +-
 .../report/support/AbstractMetadataReportTest.java |  11 +-
 .../JAXRSServiceRestMetadataResolverTest.java      |  13 +-
 .../SpringMvcServiceRestMetadataResolverTest.java  |  13 +-
 dubbo-metadata/dubbo-metadata-processor/pom.xml    |  13 --
 ...rviceDefinitionMetadataAnnotationProcessor.java |   5 +-
 .../rest/ServiceRestMetadataStorage.java           |  26 ++--
 .../metadata/store/nacos/NacosMetadataReport.java  |   2 +-
 .../store/redis/RedisMetadataReportTest.java       |  27 ++--
 .../store/zookeeper/ZookeeperMetadataReport.java   |   2 +-
 .../zookeeper/ZookeeperMetadataReportTest.java     |  11 +-
 dubbo-monitor/dubbo-monitor-default/pom.xml        |   6 -
 .../apache/dubbo/monitor/dubbo/MetricsFilter.java  |  22 ++--
 .../dubbo/monitor/dubbo/MetricsFilterTest.java     |  33 ++---
 .../dubbo/qos/command/impl/InvokeTelnet.java       |   6 +-
 .../registry/client/DefaultServiceInstance.java    |  23 ++--
 .../metadata/ServiceInstanceMetadataUtils.java     |  12 +-
 .../SpringCloudMetadataServiceURLBuilder.java      |   5 +-
 .../StandardMetadataServiceURLBuilder.java         |   3 +-
 .../client/metadata/store/MetaCacheManager.java    |   2 +-
 .../ServiceInstancesChangedListenerTest.java       |  13 +-
 .../ProtocolPortsMetadataCustomizerTest.java       |   6 +-
 .../metadata/store/MetaCacheManagerTest.java       |   4 +-
 dubbo-rpc/dubbo-rpc-api/pom.xml                    |   7 +-
 .../org/apache/dubbo/rpc/filter/GenericFilter.java | 109 ++++++++--------
 .../apache/dubbo/rpc/support/AccessLogData.java    |  31 ++---
 .../org/apache/dubbo/rpc/support/MockInvoker.java  |  22 ++--
 .../rpc/protocol/dubbo/filter/TraceFilter.java     |  13 +-
 65 files changed, 859 insertions(+), 588 deletions(-)

diff --git a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/parser/ConfigParser.java b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/parser/ConfigParser.java
index 3427fadab1..d0c855db93 100644
--- a/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/parser/ConfigParser.java
+++ b/dubbo-cluster/src/main/java/org/apache/dubbo/rpc/cluster/configurator/parser/ConfigParser.java
@@ -18,12 +18,11 @@ package org.apache.dubbo.rpc.cluster.configurator.parser;
 
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.utils.CollectionUtils;
+import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.rpc.cluster.configurator.parser.model.ConfigItem;
 import org.apache.dubbo.rpc.cluster.configurator.parser.model.ConfiguratorConfig;
 
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONValidator;
 import org.yaml.snakeyaml.Yaml;
 import org.yaml.snakeyaml.constructor.SafeConstructor;
 
@@ -43,8 +42,9 @@ public class ConfigParser {
 
     public static List<URL> parseConfigurators(String rawConfig) {
         // compatible url JsonArray, such as [ "override://xxx", "override://xxx" ]
-        if (isJsonArray(rawConfig)) {
-            return parseJsonArray(rawConfig);
+        List<URL> compatibleUrls = parseJsonArray(rawConfig);
+        if (CollectionUtils.isNotEmpty(compatibleUrls)) {
+            return compatibleUrls;
         }
 
         List<URL> urls = new ArrayList<>();
@@ -64,9 +64,13 @@ public class ConfigParser {
 
     private static List<URL> parseJsonArray(String rawConfig) {
         List<URL> urls = new ArrayList<>();
-        List<String> list = JSON.parseArray(rawConfig, String.class);
-        if (!CollectionUtils.isEmpty(list)) {
-            list.forEach(u -> urls.add(URL.valueOf(u)));
+        try {
+            List<String> list = JsonUtils.getJson().toJavaList(rawConfig, String.class);
+            if (!CollectionUtils.isEmpty(list)) {
+                list.forEach(u -> urls.add(URL.valueOf(u)));
+            }
+        } catch (Throwable t) {
+            return null;
         }
         return urls;
     }
@@ -148,7 +152,7 @@ public class ConfigParser {
         Map<String, String> parameters = item.getParameters();
         if (CollectionUtils.isEmptyMap(parameters)) {
             throw new IllegalStateException("Invalid configurator rule, please specify at least one parameter " +
-                    "you want to change in the rule.");
+                "you want to change in the rule.");
         }
 
         parameters.forEach((k, v) -> {
@@ -214,14 +218,4 @@ public class ConfigParser {
         }
         return addresses;
     }
-
-    private static boolean isJsonArray(String rawConfig) {
-        try {
-            JSONValidator validator = JSONValidator.from(rawConfig);
-            return validator.validate() && validator.getType() == JSONValidator.Type.Array;
-        } catch (Exception e) {
-            // ignore exception and return false
-        }
-        return false;
-    }
 }
diff --git a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/loadbalance/LoadBalanceBaseTest.java b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/loadbalance/LoadBalanceBaseTest.java
index f9ab3ea6df..0331873a11 100644
--- a/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/loadbalance/LoadBalanceBaseTest.java
+++ b/dubbo-cluster/src/test/java/org/apache/dubbo/rpc/cluster/loadbalance/LoadBalanceBaseTest.java
@@ -18,13 +18,13 @@ package org.apache.dubbo.rpc.cluster.loadbalance;
 
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.extension.ExtensionLoader;
+import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.RpcInvocation;
 import org.apache.dubbo.rpc.RpcStatus;
 import org.apache.dubbo.rpc.cluster.LoadBalance;
 
-import com.alibaba.fastjson.JSON;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
@@ -201,7 +201,7 @@ public class LoadBalanceBaseTest {
 
         @Override
         public String toString() {
-            return JSON.toJSONString(this);
+            return JsonUtils.getJson().toJson(this);
         }
     }
 
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/DynamicConfiguration.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/DynamicConfiguration.java
index 0e5ebd19e7..fcd08eb2b3 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/DynamicConfiguration.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/DynamicConfiguration.java
@@ -19,10 +19,6 @@ package org.apache.dubbo.common.config.configcenter;
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.config.Configuration;
 
-import java.util.Collections;
-import java.util.Set;
-import java.util.SortedSet;
-
 
 /**
  * Dynamic Configuration
@@ -98,6 +94,7 @@ public interface DynamicConfiguration extends Configuration, AutoCloseable {
 
     /**
      * get configItem which contains content and stat info.
+     *
      * @param key
      * @param group
      * @return
@@ -165,6 +162,7 @@ public interface DynamicConfiguration extends Configuration, AutoCloseable {
 
     /**
      * publish config mapped to this given key and given group with stat.
+     *
      * @param key
      * @param group
      * @param content
@@ -176,18 +174,6 @@ public interface DynamicConfiguration extends Configuration, AutoCloseable {
         return false;
     }
 
-    /**
-     * Get the config keys by the specified group
-     *
-     * @param group the specified group
-     * @return the read-only non-null sorted {@link Set set} of config keys
-     * @throws UnsupportedOperationException If the under layer does not support
-     * @since 2.7.5
-     */
-    default SortedSet<String> getConfigKeys(String group) throws UnsupportedOperationException {
-        return Collections.emptySortedSet();
-    }
-
     /**
      * Get the default group for the operations
      *
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/TreePathDynamicConfiguration.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/TreePathDynamicConfiguration.java
index 2c8a294645..d311a908f5 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/TreePathDynamicConfiguration.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/TreePathDynamicConfiguration.java
@@ -21,14 +21,9 @@ import org.apache.dubbo.common.config.configcenter.file.FileSystemDynamicConfigu
 import org.apache.dubbo.common.utils.StringUtils;
 
 import java.util.Collection;
-import java.util.SortedSet;
-import java.util.TreeSet;
 
-import static java.util.Collections.emptySortedSet;
-import static java.util.Collections.unmodifiableSortedSet;
 import static org.apache.dubbo.common.constants.CommonConstants.CONFIG_NAMESPACE_KEY;
 import static org.apache.dubbo.common.constants.CommonConstants.PATH_SEPARATOR;
-import static org.apache.dubbo.common.utils.CollectionUtils.isEmpty;
 import static org.apache.dubbo.common.utils.PathUtils.buildPath;
 import static org.apache.dubbo.common.utils.PathUtils.normalize;
 
@@ -108,13 +103,6 @@ public abstract class TreePathDynamicConfiguration extends AbstractDynamicConfig
         doRemoveListener(pathKey, listener);
     }
 
-    @Override
-    public final SortedSet<String> getConfigKeys(String group) throws UnsupportedOperationException {
-        String groupPath = buildGroupPath(group);
-        Collection<String> configKeys = doGetConfigKeys(groupPath);
-        return isEmpty(configKeys) ? emptySortedSet() : unmodifiableSortedSet(new TreeSet<>(configKeys));
-    }
-
     protected abstract boolean doPublishConfig(String pathKey, String content) throws Exception;
 
     protected abstract String doGetConfig(String pathKey) throws Exception;
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/nop/NopDynamicConfiguration.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/nop/NopDynamicConfiguration.java
index 026399976e..0f08705189 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/nop/NopDynamicConfiguration.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/nop/NopDynamicConfiguration.java
@@ -20,10 +20,6 @@ import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.config.configcenter.ConfigurationListener;
 import org.apache.dubbo.common.config.configcenter.DynamicConfiguration;
 
-import java.util.SortedSet;
-
-import static java.util.Collections.emptySortedSet;
-
 /**
  * The default extension of {@link DynamicConfiguration}. If user does not specify a config center, or specifies one
  * that is not a valid extension, it will default to this one.
@@ -64,14 +60,6 @@ public class NopDynamicConfiguration implements DynamicConfiguration {
         return true;
     }
 
-    /**
-     * @since 2.7.5
-     */
-    @Override
-    public SortedSet<String> getConfigKeys(String group) {
-        return emptySortedSet();
-    }
-
     @Override
     public void close() throws Exception {
         // no-op
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/wrapper/CompositeDynamicConfiguration.java b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/wrapper/CompositeDynamicConfiguration.java
index a345ad4e0a..908bfa8d41 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/wrapper/CompositeDynamicConfiguration.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/config/configcenter/wrapper/CompositeDynamicConfiguration.java
@@ -23,7 +23,6 @@ import org.apache.dubbo.common.logger.LoggerFactory;
 
 import java.util.HashSet;
 import java.util.Set;
-import java.util.SortedSet;
 import java.util.function.Consumer;
 import java.util.function.Function;
 
@@ -85,12 +84,6 @@ public class CompositeDynamicConfiguration implements DynamicConfiguration {
         return publishedAll;
     }
 
-    @Override
-    @SuppressWarnings("unchecked")
-    public SortedSet<String> getConfigKeys(String group) throws UnsupportedOperationException {
-        return (SortedSet<String>) iterateConfigOperation(configuration -> configuration.getConfigKeys(group));
-    }
-
     @Override
     public void close() throws Exception {
         for (DynamicConfiguration configuration : configurations) {
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
index 1cc2cd1fe1..d74d57dd2d 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/constants/CommonConstants.java
@@ -540,7 +540,8 @@ public interface CommonConstants {
 
     String IGNORE_LISTEN_SHUTDOWN_HOOK = "dubbo.shutdownHook.listenIgnore";
 
-
     String OPTIMIZER_KEY = "optimizer";
 
+    String PREFER_JSON_FRAMEWORK_NAME = "dubbo.json-framework.prefer";
+
 }
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/json/GsonUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/json/GsonUtils.java
new file mode 100644
index 0000000000..7416aa5628
--- /dev/null
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/json/GsonUtils.java
@@ -0,0 +1,81 @@
+/*
+ * 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.json;
+
+import org.apache.dubbo.common.utils.ClassUtils;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonSyntaxException;
+import com.google.gson.reflect.TypeToken;
+
+import java.lang.reflect.Type;
+
+import static org.apache.dubbo.common.constants.CommonConstants.GENERIC_SERIALIZATION_GSON;
+
+public class GsonUtils {
+    // weak reference of com.google.gson.Gson, prevent throw exception when init
+    private static volatile Object gsonCache = null;
+
+    private static volatile Boolean supportGson;
+
+    private static boolean isSupportGson() {
+        if (supportGson == null) {
+            synchronized (GsonUtils.class) {
+                if (supportGson == null) {
+                    try {
+                        Class<?> aClass = ClassUtils.forName("com.google.gson.Gson");
+                        supportGson = aClass != null;
+                    } catch (Throwable t) {
+                        supportGson = false;
+                    }
+                }
+            }
+        }
+        return supportGson;
+    }
+
+    public static Object fromJson(String json, Type originType) throws RuntimeException {
+        if (!isSupportGson()) {
+            throw new RuntimeException("Gson is not supported. Please import Gson in JVM env.");
+        }
+        Type type = TypeToken.get(originType).getType();
+        try {
+            return getGson().fromJson(json, type);
+        } catch (JsonSyntaxException ex) {
+            throw new RuntimeException(String.format("Generic serialization [%s] Json syntax exception thrown when parsing (message:%s type:%s) error:%s", GENERIC_SERIALIZATION_GSON, json, type.toString(), ex.getMessage()));
+        }
+    }
+
+    private static Gson getGson() {
+        if (gsonCache == null || !(gsonCache instanceof Gson)) {
+            synchronized (GsonUtils.class) {
+                if (gsonCache == null || !(gsonCache instanceof Gson)) {
+                    gsonCache = new Gson();
+                }
+            }
+        }
+        return (Gson) gsonCache;
+    }
+
+    /**
+     * @deprecated for uts only
+     */
+    @Deprecated
+    protected static void setSupportGson(Boolean supportGson) {
+        GsonUtils.supportGson = supportGson;
+    }
+}
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/JsonUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/json/JSON.java
similarity index 74%
copy from dubbo-common/src/main/java/org/apache/dubbo/common/utils/JsonUtils.java
copy to dubbo-common/src/main/java/org/apache/dubbo/common/json/JSON.java
index 754858064f..5d6094c2b8 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/JsonUtils.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/json/JSON.java
@@ -14,14 +14,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.common.utils;
+package org.apache.dubbo.common.json;
 
-import com.google.gson.Gson;
+import java.lang.reflect.Type;
+import java.util.List;
 
-public class JsonUtils {
-    private static final Gson gson = new Gson();
+public interface JSON {
+    boolean isSupport();
 
-    public static Gson getGson() {
-        return gson;
-    }
+    <T> T toJavaObject(String json, Type type);
+
+    <T> List<T> toJavaList(String json, Class<T> clazz);
+
+    String toJson(Object obj);
 }
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/FastJsonImpl.java b/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/FastJsonImpl.java
new file mode 100644
index 0000000000..b05fd7cd99
--- /dev/null
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/FastJsonImpl.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.json.impl;
+
+import org.apache.dubbo.common.json.JSON;
+import org.apache.dubbo.common.utils.ClassUtils;
+
+import java.lang.reflect.Type;
+import java.util.List;
+
+public class FastJsonImpl implements JSON {
+
+    @Override
+    public boolean isSupport() {
+        try {
+            Class<?> aClass = ClassUtils.forName("com.alibaba.fastjson.JSON");
+            return aClass != null;
+        } catch (Throwable t) {
+            return false;
+        }
+    }
+
+    @Override
+    public <T> T toJavaObject(String json, Type type) {
+        return com.alibaba.fastjson.JSON.parseObject(json, type);
+    }
+
+    @Override
+    public <T> List<T> toJavaList(String json, Class<T> clazz) {
+        return com.alibaba.fastjson.JSON.parseArray(json, clazz);
+    }
+
+    @Override
+    public String toJson(Object obj) {
+        return com.alibaba.fastjson.JSON.toJSONString(obj);
+    }
+}
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/GsonImpl.java b/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/GsonImpl.java
new file mode 100644
index 0000000000..f202793e13
--- /dev/null
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/json/impl/GsonImpl.java
@@ -0,0 +1,67 @@
+/*
+ * 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.json.impl;
+
+import org.apache.dubbo.common.json.JSON;
+import org.apache.dubbo.common.utils.ClassUtils;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+
+import java.lang.reflect.Type;
+import java.util.List;
+
+public class GsonImpl implements JSON {
+    // weak reference of com.google.gson.Gson, prevent throw exception when init
+    private volatile Object gsonCache = null;
+
+    @Override
+    public boolean isSupport() {
+        try {
+            Class<?> aClass = ClassUtils.forName("com.google.gson.Gson");
+            return aClass != null;
+        } catch (Throwable t) {
+            return false;
+        }
+    }
+
+    @Override
+    public <T> T toJavaObject(String json, Type type) {
+        return getGson().fromJson(json, type);
+    }
+
+    @Override
+    public <T> List<T> toJavaList(String json, Class<T> clazz) {
+        return getGson().fromJson(json, TypeToken.getParameterized(List.class, clazz).getType());
+    }
+
+    @Override
+    public String toJson(Object obj) {
+        return getGson().toJson(obj);
+    }
+
+    private Gson getGson() {
+        if (gsonCache == null || !(gsonCache instanceof Gson)) {
+            synchronized (this) {
+                if (gsonCache == null || !(gsonCache instanceof Gson)) {
+                    gsonCache = new Gson();
+                }
+            }
+        }
+        return (Gson) gsonCache;
+    }
+}
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/status/reporter/FrameworkStatusReportService.java b/dubbo-common/src/main/java/org/apache/dubbo/common/status/reporter/FrameworkStatusReportService.java
index fa22a466d6..ef0a74959b 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/status/reporter/FrameworkStatusReportService.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/status/reporter/FrameworkStatusReportService.java
@@ -19,11 +19,10 @@ package org.apache.dubbo.common.status.reporter;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.common.utils.CollectionUtils;
+import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 import org.apache.dubbo.rpc.model.ScopeModelAware;
 
-import com.google.gson.Gson;
-
 import java.util.HashMap;
 import java.util.Set;
 
@@ -36,7 +35,6 @@ public class FrameworkStatusReportService implements ScopeModelAware {
 
     private ApplicationModel applicationModel;
     private Set<FrameworkStatusReporter> reporters;
-    private Gson gson = new Gson();
 
     @Override
     public void setApplicationModel(ApplicationModel applicationModel) {
@@ -77,7 +75,7 @@ public class FrameworkStatusReportService implements ScopeModelAware {
         HashMap<String, String> registration = new HashMap<>();
         registration.put("application", applicationModel.getApplicationName());
         registration.put("status", status);
-        return gson.toJson(registration);
+        return JsonUtils.getJson().toJson(registration);
     }
 
     public String createConsumptionReport(String interfaceName, String version, String group, String status) {
@@ -88,7 +86,7 @@ public class FrameworkStatusReportService implements ScopeModelAware {
         migrationStatus.put("version", version);
         migrationStatus.put("group", group);
         migrationStatus.put("status", status);
-        return gson.toJson(migrationStatus);
+        return JsonUtils.getJson().toJson(migrationStatus);
     }
 
     public String createMigrationStepReport(String interfaceName, String version, String group, String originStep, String newStep, String success) {
@@ -101,6 +99,6 @@ public class FrameworkStatusReportService implements ScopeModelAware {
         migrationStatus.put("originStep", originStep);
         migrationStatus.put("newStep", newStep);
         migrationStatus.put("success", success);
-        return gson.toJson(migrationStatus);
+        return JsonUtils.getJson().toJson(migrationStatus);
     }
 }
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/IOUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/IOUtils.java
index 658be6f1cb..deab7d2c56 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/IOUtils.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/IOUtils.java
@@ -188,6 +188,18 @@ public class IOUtils {
         }
     }
 
+    public static String read(InputStream is, String encoding) throws IOException {
+        StringBuilder stringBuilder = new StringBuilder();
+        InputStreamReader inputStreamReader = new InputStreamReader(is, encoding);
+        char[] buf = new char[1024];
+        int len;
+        while ((len = inputStreamReader.read(buf)) != -1) {
+            stringBuilder.append(buf, 0, len);
+        }
+        inputStreamReader.close();
+        return stringBuilder.toString();
+    }
+
     /**
      * write lines.
      *
@@ -235,6 +247,7 @@ public class IOUtils {
 
     /**
      * use like spring code
+     *
      * @param resourceLocation
      * @return
      */
@@ -247,22 +260,20 @@ public class IOUtils {
             if (url == null) {
                 String description = "class path resource [" + path + "]";
                 throw new FileNotFoundException(description +
-                        " cannot be resolved to URL because it does not exist");
+                    " cannot be resolved to URL because it does not exist");
             }
             return url;
         }
         try {
             // try URL
             return new URL(resourceLocation);
-        }
-        catch (MalformedURLException ex) {
+        } catch (MalformedURLException ex) {
             // no URL -> treat as file path
             try {
                 return new File(resourceLocation).toURI().toURL();
-            }
-            catch (MalformedURLException ex2) {
+            } catch (MalformedURLException ex2) {
                 throw new FileNotFoundException("Resource location [" + resourceLocation +
-                        "] is neither a URL not a well-formed file path");
+                    "] is neither a URL not a well-formed file path");
             }
         }
     }
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/JsonUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/JsonUtils.java
index 754858064f..57235b9be0 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/JsonUtils.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/JsonUtils.java
@@ -16,12 +16,71 @@
  */
 package org.apache.dubbo.common.utils;
 
-import com.google.gson.Gson;
+import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.common.json.JSON;
+import org.apache.dubbo.common.json.impl.FastJsonImpl;
+import org.apache.dubbo.common.json.impl.GsonImpl;
+
+import java.util.Arrays;
+import java.util.List;
 
 public class JsonUtils {
-    private static final Gson gson = new Gson();
+    private static volatile JSON json;
+
+    public static JSON getJson() {
+        if (json == null) {
+            synchronized (JsonUtils.class) {
+                if (json == null) {
+                    String preferJsonFrameworkName = System.getProperty(CommonConstants.PREFER_JSON_FRAMEWORK_NAME);
+                    if (StringUtils.isNotEmpty(preferJsonFrameworkName)) {
+                        try {
+                            JSON instance = null;
+                            switch (preferJsonFrameworkName) {
+                                case "fastjson":
+                                    instance = new FastJsonImpl();
+                                    break;
+                                case "gson":
+                                    instance = new GsonImpl();
+                                    break;
+                            }
+                            if (instance != null && instance.isSupport()) {
+                                json = instance;
+                            }
+                        } catch (Throwable ignore) {
+
+                        }
+                    }
+                    if (json == null) {
+                        List<Class<? extends JSON>> jsonClasses = Arrays.asList(
+                            FastJsonImpl.class,
+                            GsonImpl.class);
+                        for (Class<? extends JSON> jsonClass : jsonClasses) {
+                            try {
+                                JSON instance = jsonClass.getConstructor().newInstance();
+                                if (instance.isSupport()) {
+                                    json = instance;
+                                    break;
+                                }
+                            } catch (Throwable ignore) {
+
+                            }
+                        }
+                    }
+                    if (json == null) {
+                        throw new IllegalStateException("Dubbo unable to find out any json framework (e.g. fastjson, gson) from jvm env. " +
+                            "Please import at least one json framework.");
+                    }
+                }
+            }
+        }
+        return json;
+    }
 
-    public static Gson getGson() {
-        return gson;
+    /**
+     * @deprecated for uts only
+     */
+    @Deprecated
+    protected static void setJson(JSON json) {
+        JsonUtils.json = json;
     }
 }
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/StringUtils.java b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/StringUtils.java
index f51fcbbf93..8d7100760c 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/StringUtils.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/StringUtils.java
@@ -20,8 +20,6 @@ import org.apache.dubbo.common.io.UnsafeStringWriter;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
 
-import com.alibaba.fastjson.JSON;
-
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -437,6 +435,7 @@ public final class StringUtils {
 
     /**
      * Check the cs String whether contains non whitespace characters.
+     *
      * @param cs
      * @return
      */
@@ -774,9 +773,9 @@ public final class StringUtils {
         }
 
         return unmodifiableSet(values
-                .stream()
-                .map(String::trim)
-                .collect(LinkedHashSet::new, Set::add, Set::addAll));
+            .stream()
+            .map(String::trim)
+            .collect(LinkedHashSet::new, Set::add, Set::addAll));
     }
 
     /**
@@ -965,20 +964,20 @@ public final class StringUtils {
         if (str == null) {
             return false;
         }
-        return str.chars().allMatch(ch -> (ch == separator) || isWord((char)ch) );
+        return str.chars().allMatch(ch -> (ch == separator) || isWord((char) ch));
     }
 
     private static boolean isWord(String str) {
         if (str == null) {
             return false;
         }
-        return str.chars().allMatch(ch -> isWord((char)ch));
+        return str.chars().allMatch(ch -> isWord((char) ch));
     }
 
     private static boolean isWord(char ch) {
         if ((ch >= 'A' && ch <= 'Z') ||
-                (ch >= 'a' && ch <= 'z') ||
-                (ch >= '0' && ch <= '9')) {
+            (ch >= 'a' && ch <= 'z') ||
+            (ch >= '0' && ch <= '9')) {
             return true;
         }
         return false;
@@ -988,6 +987,7 @@ public final class StringUtils {
      * Convert snake_case or SNAKE_CASE to kebab-case.
      * <p>
      * NOTE: Return itself if it's not a snake case.
+     *
      * @param snakeName
      * @param split
      * @return
@@ -1006,6 +1006,7 @@ public final class StringUtils {
 
     /**
      * Convert camelCase or snake_case/SNAKE_CASE to kebab-case
+     *
      * @param str
      * @param split
      * @return
@@ -1028,7 +1029,7 @@ public final class StringUtils {
                 buf.append(arg);
             } else {
                 try {
-                    buf.append(JSON.toJSONString(arg));
+                    buf.append(JsonUtils.getJson().toJson(arg));
                 } catch (Exception e) {
                     logger.warn(e.getMessage(), e);
                     buf.append(arg);
@@ -1155,6 +1156,7 @@ public final class StringUtils {
 
     /**
      * Decode parameters string to map
+     *
      * @param rawParameters format like '[{a:b},{c:d}]'
      * @return
      */
@@ -1182,6 +1184,7 @@ public final class StringUtils {
 
     /**
      * Encode parameters map to string, like '[{a:b},{c:d}]'
+     *
      * @param params
      * @return
      */
@@ -1192,7 +1195,7 @@ public final class StringUtils {
 
         StringBuilder sb = new StringBuilder();
         sb.append('[');
-        params.forEach((key,value) -> {
+        params.forEach((key, value) -> {
             // {key:value},
             if (hasText(value)) {
                 sb.append('{').append(key).append(':').append(value).append("},");
@@ -1200,7 +1203,7 @@ public final class StringUtils {
         });
         // delete last separator ','
         if (sb.charAt(sb.length() - 1) == ',') {
-            sb.deleteCharAt(sb.length()-1);
+            sb.deleteCharAt(sb.length() - 1);
         }
         sb.append(']');
         return sb.toString();
@@ -1221,7 +1224,7 @@ public final class StringUtils {
         int lo = decodeHexNibble(s.charAt(pos + 1));
         if (hi == -1 || lo == -1) {
             throw new IllegalArgumentException(String.format(
-                    "invalid hex byte '%s' at index %d of '%s'", s.subSequence(pos, pos + 2), pos, s));
+                "invalid hex byte '%s' at index %d of '%s'", s.subSequence(pos, pos + 2), pos, s));
         }
         return (byte) ((hi << 4) + lo);
     }
@@ -1241,6 +1244,7 @@ public final class StringUtils {
 
     /**
      * Test str whether starts with the prefix ignore case.
+     *
      * @param str
      * @param prefix
      * @return
diff --git a/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/ServiceDefinitionBuilder.java b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/ServiceDefinitionBuilder.java
index cfdec7256c..1bfafb5c80 100755
--- a/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/ServiceDefinitionBuilder.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/metadata/definition/ServiceDefinitionBuilder.java
@@ -16,14 +16,13 @@
  */
 package org.apache.dubbo.metadata.definition;
 
+import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
 import org.apache.dubbo.metadata.definition.model.MethodDefinition;
 import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
 import org.apache.dubbo.metadata.definition.model.TypeDefinition;
 import org.apache.dubbo.metadata.definition.util.ClassUtils;
 
-import com.google.gson.Gson;
-
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
@@ -115,8 +114,7 @@ public final class ServiceDefinitionBuilder {
      */
     public static String schema(final Class<?> clazz) {
         ServiceDefinition sd = build(clazz);
-        Gson gson = new Gson();
-        return gson.toJson(sd);
+        return JsonUtils.getJson().toJson(sd);
     }
 
     private ServiceDefinitionBuilder() {
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/config/configcenter/AbstractDynamicConfigurationTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/config/configcenter/AbstractDynamicConfigurationTest.java
index 7605a3c618..c758aaac90 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/config/configcenter/AbstractDynamicConfigurationTest.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/config/configcenter/AbstractDynamicConfigurationTest.java
@@ -38,7 +38,6 @@ import static org.apache.dubbo.common.config.configcenter.DynamicConfiguration.D
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertTrue;
 
 /**
  * {@link AbstractDynamicConfiguration} Test
@@ -126,11 +125,11 @@ public class AbstractDynamicConfigurationTest {
         assertFalse(configuration.publishConfig(null, null));
         assertFalse(configuration.publishConfig(null, null, null));
     }
-
-    @Test
-    public void testGetConfigKeys() {
-        assertTrue(configuration.getConfigKeys(null).isEmpty());
-    }
+//
+//    @Test
+//    public void testGetConfigKeys() {
+//        assertTrue(configuration.getConfigKeys(null).isEmpty());
+//    }
 
     @Test
     public void testGetConfig() {
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/config/configcenter/file/FileSystemDynamicConfigurationTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/config/configcenter/file/FileSystemDynamicConfigurationTest.java
index e7ecd4f53b..2fd6516ea5 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/config/configcenter/file/FileSystemDynamicConfigurationTest.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/config/configcenter/file/FileSystemDynamicConfigurationTest.java
@@ -28,11 +28,9 @@ import org.junit.jupiter.api.Test;
 
 import java.io.File;
 import java.io.IOException;
-import java.util.TreeSet;
 import java.util.concurrent.ThreadPoolExecutor;
 import java.util.concurrent.atomic.AtomicBoolean;
 
-import static java.util.Arrays.asList;
 import static org.apache.dubbo.common.URL.valueOf;
 import static org.apache.dubbo.common.config.configcenter.DynamicConfiguration.DEFAULT_GROUP;
 import static org.apache.dubbo.common.config.configcenter.file.FileSystemDynamicConfiguration.CONFIG_CENTER_DIR_PARAM_NAME;
@@ -173,16 +171,16 @@ public class FileSystemDynamicConfigurationTest {
         assertFalse(configuration.configFile(KEY, DEFAULT_GROUP).exists());
 
     }
-
-    @Test
-    public void testGetConfigKeys() throws Exception {
-
-        assertTrue(configuration.publishConfig("A", DEFAULT_GROUP, "A"));
-
-        assertTrue(configuration.publishConfig("B", DEFAULT_GROUP, "B"));
-
-        assertTrue(configuration.publishConfig("C", DEFAULT_GROUP, "C"));
-
-        assertEquals(new TreeSet(asList("A", "B", "C")), configuration.getConfigKeys(DEFAULT_GROUP));
-    }
+//
+//    @Test
+//    public void testGetConfigKeys() throws Exception {
+//
+//        assertTrue(configuration.publishConfig("A", DEFAULT_GROUP, "A"));
+//
+//        assertTrue(configuration.publishConfig("B", DEFAULT_GROUP, "B"));
+//
+//        assertTrue(configuration.publishConfig("C", DEFAULT_GROUP, "C"));
+//
+//        assertEquals(new TreeSet(asList("A", "B", "C")), configuration.getConfigKeys(DEFAULT_GROUP));
+//    }
 }
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/json/GsonUtilsTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/json/GsonUtilsTest.java
new file mode 100644
index 0000000000..e6a3e1d6cd
--- /dev/null
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/json/GsonUtilsTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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.json;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+
+public class GsonUtilsTest {
+    @Test
+    public void test1() {
+        Object user = GsonUtils.fromJson("{'name':'Tom','age':24}", User.class);
+        Assertions.assertInstanceOf(User.class, user);
+        Assertions.assertEquals("Tom", ((User) user).getName());
+        Assertions.assertEquals(24, ((User) user).getAge());
+
+        try {
+            GsonUtils.fromJson("{'name':'Tom','age':}", User.class);
+            Assertions.fail();
+        } catch (RuntimeException ex) {
+            Assertions.assertEquals("Generic serialization [gson] Json syntax exception thrown when parsing (message:{'name':'Tom','age':} type:class org.apache.dubbo.common.json.GsonUtilsTest$User) error:com.google.gson.stream.MalformedJsonException: Expected value at line 1 column 21 path $.age", ex.getMessage());
+        }
+    }
+
+    @Test
+    public void test2() {
+        ClassLoader originClassLoader = Thread.currentThread().getContextClassLoader();
+        AtomicReference<List<String>> removedPackages = new AtomicReference<>(Collections.emptyList());
+        ClassLoader newClassLoader = new ClassLoader(originClassLoader) {
+            @Override
+            public Class<?> loadClass(String name) throws ClassNotFoundException {
+                for (String removedPackage : removedPackages.get()) {
+                    if (name.startsWith(removedPackage)) {
+                        throw new ClassNotFoundException("Test");
+                    }
+                }
+                return super.loadClass(name);
+            }
+        };
+        Thread.currentThread().setContextClassLoader(newClassLoader);
+
+        // TCCL not found gson
+        removedPackages.set(Collections.singletonList("com.google.gson"));
+        GsonUtils.setSupportGson(null);
+        try {
+            GsonUtils.fromJson("{'name':'Tom','age':24}", User.class);
+            Assertions.fail();
+        } catch (RuntimeException ex) {
+            Assertions.assertEquals("Gson is not supported. Please import Gson in JVM env.", ex.getMessage());
+        }
+
+        Thread.currentThread().setContextClassLoader(originClassLoader);
+        GsonUtils.setSupportGson(null);
+    }
+
+    private static class User {
+        String name;
+        int age;
+
+        public String getName() {
+            return name;
+        }
+
+        public void setName(String name) {
+            this.name = name;
+        }
+
+        public int getAge() {
+            return age;
+        }
+
+        public void setAge(int age) {
+            this.age = age;
+        }
+    }
+}
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/status/reporter/FrameworkStatusReportServiceTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/status/reporter/FrameworkStatusReportServiceTest.java
index 12696dac9e..14c8465132 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/common/status/reporter/FrameworkStatusReportServiceTest.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/status/reporter/FrameworkStatusReportServiceTest.java
@@ -17,11 +17,11 @@
 package org.apache.dubbo.common.status.reporter;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.config.ApplicationConfig;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 import org.apache.dubbo.rpc.model.FrameworkModel;
 
-import com.google.gson.Gson;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.mockito.Mockito;
@@ -74,15 +74,14 @@ public class FrameworkStatusReportServiceTest {
         Assertions.assertEquals(reportContent.size(), 3);
 
         // verify registrationStatus
-        Gson gson = new Gson();
         Object registrationStatus = reportContent.get(REGISTRATION_STATUS);
-        Map<String, String> registrationMap = gson.fromJson(String.valueOf(registrationStatus), Map.class);
+        Map<String, String> registrationMap = JsonUtils.getJson().toJavaObject(String.valueOf(registrationStatus), Map.class);
         Assertions.assertEquals(registrationMap.get("application"), "APP");
         Assertions.assertEquals(registrationMap.get("status"), "instance");
 
         // verify addressConsumptionStatus
         Object addressConsumptionStatus = reportContent.get(ADDRESS_CONSUMPTION_STATUS);
-        Map<String, String> consumptionMap = gson.fromJson(String.valueOf(addressConsumptionStatus), Map.class);
+        Map<String, String> consumptionMap = JsonUtils.getJson().toJavaObject(String.valueOf(addressConsumptionStatus), Map.class);
         Assertions.assertEquals(consumptionMap.get("application"), "APP");
         Assertions.assertEquals(consumptionMap.get("service"), "Test");
         Assertions.assertEquals(consumptionMap.get("status"), "status");
@@ -92,7 +91,7 @@ public class FrameworkStatusReportServiceTest {
 
         // verify migrationStepStatus
         Object migrationStepStatus = reportContent.get(MIGRATION_STEP_STATUS);
-        Map<String, String> migrationStepStatusMap = gson.fromJson(String.valueOf(migrationStepStatus), Map.class);
+        Map<String, String> migrationStepStatusMap = JsonUtils.getJson().toJavaObject(String.valueOf(migrationStepStatus), Map.class);
         Assertions.assertEquals(migrationStepStatusMap.get("originStep"), "FORCE_INTERFACE");
         Assertions.assertEquals(migrationStepStatusMap.get("application"), "APP");
         Assertions.assertEquals(migrationStepStatusMap.get("service"), "Test");
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/common/utils/JsonUtilsTest.java b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/JsonUtilsTest.java
new file mode 100644
index 0000000000..a04683c8d8
--- /dev/null
+++ b/dubbo-common/src/test/java/org/apache/dubbo/common/utils/JsonUtilsTest.java
@@ -0,0 +1,138 @@
+/*
+ * 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.json.impl.FastJsonImpl;
+import org.apache.dubbo.common.json.impl.GsonImpl;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
+
+public class JsonUtilsTest {
+    @Test
+    public void testGetJson1() {
+        Assertions.assertNotNull(JsonUtils.getJson());
+        Assertions.assertEquals(JsonUtils.getJson(), JsonUtils.getJson());
+
+        Map<String, String> map = new HashMap<>();
+        map.put("a", "a");
+        Assertions.assertEquals("{\"a\":\"a\"}", JsonUtils.getJson().toJson(map));
+        Assertions.assertEquals(map, JsonUtils.getJson().toJavaObject("{\"a\":\"a\"}", Map.class));
+        Assertions.assertEquals(Collections.singletonList(map), JsonUtils.getJson().toJavaList("[{\"a\":\"a\"}]", Map.class));
+
+        // prefer use fastjson
+        JsonUtils.setJson(null);
+        System.setProperty("dubbo.json-framework.prefer", "fastjson");
+        Assertions.assertEquals("{\"a\":\"a\"}", JsonUtils.getJson().toJson(map));
+        Assertions.assertEquals(map, JsonUtils.getJson().toJavaObject("{\"a\":\"a\"}", Map.class));
+        Assertions.assertEquals(Collections.singletonList(map), JsonUtils.getJson().toJavaList("[{\"a\":\"a\"}]", Map.class));
+        System.clearProperty("dubbo.json-framework.prefer");
+
+        // prefer use gson
+        JsonUtils.setJson(null);
+        System.setProperty("dubbo.json-framework.prefer", "gson");
+        Assertions.assertEquals("{\"a\":\"a\"}", JsonUtils.getJson().toJson(map));
+        Assertions.assertEquals(map, JsonUtils.getJson().toJavaObject("{\"a\":\"a\"}", Map.class));
+        Assertions.assertEquals(Collections.singletonList(map), JsonUtils.getJson().toJavaList("[{\"a\":\"a\"}]", Map.class));
+        System.clearProperty("dubbo.json-framework.prefer");
+
+        JsonUtils.setJson(null);
+    }
+
+    @Test
+    public void testGetJson2() {
+        ClassLoader originClassLoader = Thread.currentThread().getContextClassLoader();
+        AtomicReference<List<String>> removedPackages = new AtomicReference<>(Collections.emptyList());
+        ClassLoader newClassLoader = new ClassLoader(originClassLoader) {
+            @Override
+            public Class<?> loadClass(String name) throws ClassNotFoundException {
+                for (String removedPackage : removedPackages.get()) {
+                    if (name.startsWith(removedPackage)) {
+                        throw new ClassNotFoundException("Test");
+                    }
+                }
+                return super.loadClass(name);
+            }
+        };
+        Thread.currentThread().setContextClassLoader(newClassLoader);
+
+        // default use fastjson
+        JsonUtils.setJson(null);
+        removedPackages.set(Collections.emptyList());
+        Assertions.assertInstanceOf(FastJsonImpl.class, JsonUtils.getJson());
+
+        // prefer use fastjson
+        JsonUtils.setJson(null);
+        removedPackages.set(Collections.emptyList());
+        System.setProperty("dubbo.json-framework.prefer", "fastjson");
+        Assertions.assertInstanceOf(FastJsonImpl.class, JsonUtils.getJson());
+        System.clearProperty("dubbo.json-framework.prefer");
+
+        // prefer use gson
+        JsonUtils.setJson(null);
+        removedPackages.set(Collections.emptyList());
+        System.setProperty("dubbo.json-framework.prefer", "gson");
+        Assertions.assertInstanceOf(GsonImpl.class, JsonUtils.getJson());
+        System.clearProperty("dubbo.json-framework.prefer");
+
+        // prefer use not found
+        JsonUtils.setJson(null);
+        removedPackages.set(Collections.emptyList());
+        System.setProperty("dubbo.json-framework.prefer", "notfound");
+        Assertions.assertInstanceOf(FastJsonImpl.class, JsonUtils.getJson());
+        System.clearProperty("dubbo.json-framework.prefer");
+
+        JsonUtils.setJson(null);
+        // TCCL not found fastjson
+        removedPackages.set(Collections.singletonList("com.alibaba.fastjson"));
+        Assertions.assertInstanceOf(GsonImpl.class, JsonUtils.getJson());
+
+        JsonUtils.setJson(null);
+        // TCCL not found gson
+        removedPackages.set(Collections.singletonList("com.google.gson"));
+        Assertions.assertInstanceOf(FastJsonImpl.class, JsonUtils.getJson());
+
+        JsonUtils.setJson(null);
+        // TCCL not found fastjson, prefer use fastjson
+        removedPackages.set(Collections.singletonList("com.alibaba.fastjson"));
+        System.setProperty("dubbo.json-framework.prefer", "fastjson");
+        Assertions.assertInstanceOf(GsonImpl.class, JsonUtils.getJson());
+        System.clearProperty("dubbo.json-framework.prefer");
+
+        JsonUtils.setJson(null);
+        // TCCL not found gson, prefer use gson
+        removedPackages.set(Collections.singletonList("com.google.gson"));
+        System.setProperty("dubbo.json-framework.prefer", "gson");
+        Assertions.assertInstanceOf(FastJsonImpl.class, JsonUtils.getJson());
+        System.clearProperty("dubbo.json-framework.prefer");
+
+        JsonUtils.setJson(null);
+        // TCCL not found fastjson, gson
+        removedPackages.set(Arrays.asList("com.alibaba.fastjson", "com.google.gson"));
+        Assertions.assertThrows(IllegalStateException.class, JsonUtils::getJson);
+
+        Thread.currentThread().setContextClassLoader(originClassLoader);
+        JsonUtils.setJson(null);
+    }
+}
diff --git a/dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/MetadataTest.java b/dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/MetadataTest.java
index ee59c62aa1..26106de36c 100644
--- a/dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/MetadataTest.java
+++ b/dubbo-common/src/test/java/org/apache/dubbo/metadata/definition/MetadataTest.java
@@ -16,6 +16,7 @@
  */
 package org.apache.dubbo.metadata.definition;
 
+import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.metadata.definition.common.ClassExtendsMap;
 import org.apache.dubbo.metadata.definition.common.ColorEnum;
 import org.apache.dubbo.metadata.definition.common.OuterClass;
@@ -25,7 +26,6 @@ import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
 import org.apache.dubbo.metadata.definition.model.TypeDefinition;
 import org.apache.dubbo.rpc.model.FrameworkModel;
 
-import com.google.gson.Gson;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
@@ -49,13 +49,13 @@ public class MetadataTest {
     public void testInnerClassType() {
         TypeDefinitionBuilder builder = new TypeDefinitionBuilder();
         TypeDefinition td = builder.build(OuterClass.InnerClass.class, OuterClass.InnerClass.class);
-        System.out.println(">> testInnerClassType: " + new Gson().toJson(td));
+        System.out.println(">> testInnerClassType: " + JsonUtils.getJson().toJson(td));
 
         Assertions.assertEquals("org.apache.dubbo.metadata.definition.common.OuterClass.InnerClass", td.getType());
         Assertions.assertEquals(1, td.getProperties().size());
         Assertions.assertNotNull(td.getProperties().get("name"));
         ServiceDefinition sd = MetadataUtils.generateMetadata(TestService.class);
-        System.out.println(">> testInnerClassType: " + new Gson().toJson(sd));
+        System.out.println(">> testInnerClassType: " + JsonUtils.getJson().toJson(sd));
 
         Assertions.assertEquals(TestService.class.getName(), sd.getCanonicalName());
         Assertions.assertEquals(TestService.class.getMethods().length, sd.getMethods().size());
@@ -70,12 +70,13 @@ public class MetadataTest {
     }
 
     /**
+     *
      */
     @Test
     public void testRawMap() {
         TypeDefinitionBuilder builder = new TypeDefinitionBuilder();
         TypeDefinition td = builder.build(ResultWithRawCollections.class, ResultWithRawCollections.class);
-        System.out.println(">> testRawMap: " + new Gson().toJson(td));
+        System.out.println(">> testRawMap: " + JsonUtils.getJson().toJson(td));
 
         Assertions.assertEquals("org.apache.dubbo.metadata.definition.common.ResultWithRawCollections", td.getType());
         Assertions.assertEquals(2, td.getProperties().size());
@@ -83,7 +84,7 @@ public class MetadataTest {
         Assertions.assertEquals("java.util.List", td.getProperties().get("list"));
 
         ServiceDefinition sd = MetadataUtils.generateMetadata(TestService.class);
-        System.out.println(">> testRawMap: " + new Gson().toJson(sd));
+        System.out.println(">> testRawMap: " + JsonUtils.getJson().toJson(sd));
 
         Assertions.assertEquals(TestService.class.getName(), sd.getCanonicalName());
         Assertions.assertEquals(TestService.class.getMethods().length, sd.getMethods().size());
@@ -101,7 +102,7 @@ public class MetadataTest {
     public void testEnum() {
         TypeDefinitionBuilder builder = new TypeDefinitionBuilder();
         TypeDefinition td = builder.build(ColorEnum.class, ColorEnum.class);
-        System.out.println(">> testEnum: " + new Gson().toJson(td));
+        System.out.println(">> testEnum: " + JsonUtils.getJson().toJson(td));
 
         Assertions.assertEquals("org.apache.dubbo.metadata.definition.common.ColorEnum", td.getType());
         Assertions.assertEquals(3, td.getEnums().size());
@@ -110,7 +111,7 @@ public class MetadataTest {
         Assertions.assertTrue(td.getEnums().contains("BLUE"));
 
         ServiceDefinition sd = MetadataUtils.generateMetadata(TestService.class);
-        System.out.println(">> testEnum: " + new Gson().toJson(sd));
+        System.out.println(">> testEnum: " + JsonUtils.getJson().toJson(sd));
 
         Assertions.assertEquals(TestService.class.getName(), sd.getCanonicalName());
         Assertions.assertEquals(TestService.class.getMethods().length, sd.getMethods().size());
@@ -128,13 +129,13 @@ public class MetadataTest {
     public void testExtendsMap() {
         TypeDefinitionBuilder builder = new TypeDefinitionBuilder();
         TypeDefinition td = builder.build(ClassExtendsMap.class, ClassExtendsMap.class);
-        System.out.println(">> testExtendsMap: " + new Gson().toJson(td));
+        System.out.println(">> testExtendsMap: " + JsonUtils.getJson().toJson(td));
 
         Assertions.assertEquals("org.apache.dubbo.metadata.definition.common.ClassExtendsMap", td.getType());
         Assertions.assertEquals(0, td.getProperties().size());
 
         ServiceDefinition sd = MetadataUtils.generateMetadata(TestService.class);
-        System.out.println(">> testExtendsMap: " + new Gson().toJson(sd));
+        System.out.println(">> testExtendsMap: " + JsonUtils.getJson().toJson(sd));
 
         Assertions.assertEquals(TestService.class.getName(), sd.getCanonicalName());
         Assertions.assertEquals(TestService.class.getMethods().length, sd.getMethods().size());
diff --git a/dubbo-compatible/src/test/java/org/apache/dubbo/generic/GenericServiceTest.java b/dubbo-compatible/src/test/java/org/apache/dubbo/generic/GenericServiceTest.java
index cf2a320041..a89b563ab9 100644
--- a/dubbo-compatible/src/test/java/org/apache/dubbo/generic/GenericServiceTest.java
+++ b/dubbo-compatible/src/test/java/org/apache/dubbo/generic/GenericServiceTest.java
@@ -20,6 +20,7 @@ package org.apache.dubbo.generic;
 
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.extension.ExtensionLoader;
+import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 import org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
 import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
@@ -35,7 +36,6 @@ import org.apache.dubbo.service.DemoService;
 import org.apache.dubbo.service.DemoServiceImpl;
 
 import com.alibaba.dubbo.config.ReferenceConfig;
-import com.alibaba.fastjson.JSON;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
@@ -99,8 +99,8 @@ public class GenericServiceTest {
     @Test
     public void testGenericCompatible() {
         DubboBootstrap.getInstance()
-                .application("test-app")
-                .initialize();
+            .application("test-app")
+            .initialize();
 
         DemoService server = new DemoServiceImpl();
         ProxyFactory proxyFactory = ExtensionLoader.getExtensionLoader(ProxyFactory.class).getAdaptiveExtension();
@@ -182,7 +182,7 @@ public class GenericServiceTest {
 
         GenericService client = proxyFactory.getProxy(invoker, true);
         Object result = client.$invoke("findComplexObject", new String[]{"java.lang.String", "int", "long", "java.lang.String[]", "java.util.List", "org.apache.dubbo.service.ComplexObject$TestEnum"},
-                new Object[]{var1, var2, l, var3, var4, testEnum});
+            new Object[]{var1, var2, l, var3, var4, testEnum});
         Assertions.assertNotNull(result);
         ComplexObject r = map2bean((Map) result);
         Assertions.assertEquals(r, createComplexObject(var1, var2, l, var3, var4, testEnum));
@@ -272,11 +272,11 @@ public class GenericServiceTest {
     }
 
     Map<String, Object> bean2Map(ComplexObject complexObject) {
-        return JSON.parseObject(JSON.toJSONString(complexObject), Map.class);
+        return JsonUtils.getJson().toJavaObject(JsonUtils.getJson().toJson(complexObject), Map.class);
     }
 
     ComplexObject map2bean(Map<String, Object> map) {
-        return JSON.parseObject(JSON.toJSONString(map), ComplexObject.class);
+        return JsonUtils.getJson().toJavaObject(JsonUtils.getJson().toJson(map), ComplexObject.class);
     }
 
     ComplexObject createComplexObject(String var1, int var2, long l, String[] var3, List<Integer> var4, ComplexObject.TestEnum testEnum) {
diff --git a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/metadata/MetadataServiceURLParamsMetadataCustomizerTest.java b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/metadata/MetadataServiceURLParamsMetadataCustomizerTest.java
index d3fe734c82..e3552fe011 100644
--- a/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/metadata/MetadataServiceURLParamsMetadataCustomizerTest.java
+++ b/dubbo-config/dubbo-config-api/src/test/java/org/apache/dubbo/config/metadata/MetadataServiceURLParamsMetadataCustomizerTest.java
@@ -17,6 +17,7 @@
 package org.apache.dubbo.config.metadata;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.config.ApplicationConfig;
 import org.apache.dubbo.config.ProtocolConfig;
 import org.apache.dubbo.config.RegistryConfig;
@@ -27,8 +28,6 @@ import org.apache.dubbo.config.provider.impl.DemoServiceImpl;
 import org.apache.dubbo.registry.client.DefaultServiceInstance;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 
-import com.google.gson.Gson;
-import com.google.gson.reflect.TypeToken;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
@@ -48,7 +47,6 @@ import static org.apache.dubbo.common.constants.CommonConstants.VERSION_KEY;
 import static org.apache.dubbo.registry.client.metadata.ServiceInstanceMetadataUtils.METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME;
 
 public class MetadataServiceURLParamsMetadataCustomizerTest {
-    private static final Gson gson = new Gson();
 
     public DefaultServiceInstance instance;
     private URL metadataServiceURL = URL.valueOf("dubbo://10.225.12.124:20880/org.apache.dubbo.metadata.MetadataService" +
@@ -97,8 +95,7 @@ public class MetadataServiceURLParamsMetadataCustomizerTest {
         String val = instance.getMetadata().get(METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME);
         Assertions.assertNotNull(val);
 
-        Map<String, String> map = gson.fromJson(val, new TypeToken<Map<String, String>>() {
-        }.getType());
+        Map<String, String> map = JsonUtils.getJson().toJavaObject(val, Map.class);
         Assertions.assertEquals(map.get(PORT_KEY), String.valueOf(metadataServiceURL.getPort()));
         Assertions.assertEquals(map.get(PROTOCOL_KEY), metadataServiceURL.getProtocol());
         Assertions.assertEquals(map.get(VERSION_KEY), metadataServiceURL.getVersion());
diff --git a/dubbo-configcenter/dubbo-configcenter-apollo/src/test/java/org/apache/dubbo/configcenter/support/apollo/EmbeddedApolloJunit5.java b/dubbo-configcenter/dubbo-configcenter-apollo/src/test/java/org/apache/dubbo/configcenter/support/apollo/EmbeddedApolloJunit5.java
index 389d7c9b44..5b93b14971 100644
--- a/dubbo-configcenter/dubbo-configcenter-apollo/src/test/java/org/apache/dubbo/configcenter/support/apollo/EmbeddedApolloJunit5.java
+++ b/dubbo-configcenter/dubbo-configcenter-apollo/src/test/java/org/apache/dubbo/configcenter/support/apollo/EmbeddedApolloJunit5.java
@@ -17,6 +17,8 @@
 
 package org.apache.dubbo.configcenter.support.apollo;
 
+import org.apache.dubbo.common.utils.JsonUtils;
+
 import com.ctrip.framework.apollo.build.ApolloInjector;
 import com.ctrip.framework.apollo.core.dto.ApolloConfig;
 import com.ctrip.framework.apollo.core.dto.ApolloConfigNotification;
@@ -24,8 +26,6 @@ import com.ctrip.framework.apollo.core.utils.ResourceUtils;
 import com.ctrip.framework.apollo.internals.ConfigServiceLocator;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
-import com.google.gson.Gson;
-import com.google.gson.reflect.TypeToken;
 import okhttp3.mockwebserver.Dispatcher;
 import okhttp3.mockwebserver.MockResponse;
 import okhttp3.mockwebserver.MockWebServer;
@@ -37,7 +37,6 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.lang.reflect.Method;
-import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
@@ -46,13 +45,10 @@ import java.util.Set;
 
 public class EmbeddedApolloJunit5 implements BeforeAllCallback, AfterAllCallback {
     private static final Logger logger = LoggerFactory.getLogger(EmbeddedApolloJunit5.class);
-    private static final Type notificationType = new TypeToken<List<ApolloConfigNotification>>() {
-    }.getType();
 
     private static Method CONFIG_SERVICE_LOCATOR_CLEAR;
     private static ConfigServiceLocator CONFIG_SERVICE_LOCATOR;
 
-    private static final Gson GSON = new Gson();
     private final Map<String, Map<String, String>> addedOrModifiedPropertiesOfNamespace = Maps.newConcurrentMap();
     private final Map<String, Set<String>> deletedKeysOfNamespace = Maps.newConcurrentMap();
 
@@ -90,17 +86,17 @@ public class EmbeddedApolloJunit5 implements BeforeAllCallback, AfterAllCallback
 
         Map<String, String> mergedConfigurations = mergeOverriddenProperties(namespace, configurations);
         apolloConfig.setConfigurations(mergedConfigurations);
-        return GSON.toJson(apolloConfig);
+        return JsonUtils.getJson().toJson(apolloConfig);
     }
 
     private String mockLongPollBody(String notificationsStr) {
-        List<ApolloConfigNotification> oldNotifications = GSON.fromJson(notificationsStr, notificationType);
+        List<ApolloConfigNotification> oldNotifications = JsonUtils.getJson().toJavaList(notificationsStr, ApolloConfigNotification.class);
         List<ApolloConfigNotification> newNotifications = new ArrayList<>();
         for (ApolloConfigNotification notification : oldNotifications) {
             newNotifications
-                    .add(new ApolloConfigNotification(notification.getNamespaceName(), notification.getNotificationId() + 1));
+                .add(new ApolloConfigNotification(notification.getNamespaceName(), notification.getNotificationId() + 1));
         }
-        return GSON.toJson(newNotifications);
+        return JsonUtils.getJson().toJson(newNotifications);
     }
 
     /**
diff --git a/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java b/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java
index 666098a9e7..e2e7d2aafd 100644
--- a/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java
+++ b/dubbo-configcenter/dubbo-configcenter-nacos/src/main/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfiguration.java
@@ -28,38 +28,25 @@ import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.common.utils.MD5Utils;
 import org.apache.dubbo.common.utils.StringUtils;
 
-import com.alibaba.fastjson.JSON;
-import com.alibaba.fastjson.JSONArray;
-import com.alibaba.fastjson.JSONObject;
 import com.alibaba.nacos.api.NacosFactory;
 import com.alibaba.nacos.api.PropertyKeyConst;
 import com.alibaba.nacos.api.config.ConfigService;
 import com.alibaba.nacos.api.config.listener.AbstractSharedListener;
 import com.alibaba.nacos.api.exception.NacosException;
-import com.alibaba.nacos.client.config.http.HttpAgent;
-import com.alibaba.nacos.common.http.HttpRestResult;
 
-import java.lang.reflect.Field;
-import java.util.HashMap;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArraySet;
 import java.util.concurrent.Executor;
-import java.util.stream.Stream;
 
-import static com.alibaba.nacos.api.PropertyKeyConst.ENCODE;
 import static com.alibaba.nacos.api.PropertyKeyConst.PASSWORD;
 import static com.alibaba.nacos.api.PropertyKeyConst.SERVER_ADDR;
 import static com.alibaba.nacos.api.PropertyKeyConst.USERNAME;
-import static java.util.Collections.emptyMap;
 import static org.apache.dubbo.common.constants.RemotingConstants.BACKUP_KEY;
 import static org.apache.dubbo.common.utils.StringConstantFieldValuePredicate.of;
 import static org.apache.dubbo.common.utils.StringUtils.HYPHEN_CHAR;
-import static org.apache.dubbo.common.utils.StringUtils.SLASH_CHAR;
 
 /**
  * The nacos implementation of {@link DynamicConfiguration}
@@ -81,8 +68,6 @@ public class NacosDynamicConfiguration implements DynamicConfiguration {
      */
     private final NacosConfigServiceWrapper configService;
 
-    private HttpAgent httpAgent;
-
     /**
      * The map store the key to {@link NacosConfigListener} mapping
      */
@@ -93,7 +78,6 @@ public class NacosDynamicConfiguration implements DynamicConfiguration {
     NacosDynamicConfiguration(URL url) {
         this.nacosProperties = buildNacosProperties(url);
         this.configService = buildConfigService(url);
-        this.httpAgent = getHttpAgent(configService.getConfigService());
         watchListenerMap = new ConcurrentHashMap<>();
     }
 
@@ -110,18 +94,6 @@ public class NacosDynamicConfiguration implements DynamicConfiguration {
         return new NacosConfigServiceWrapper(configService);
     }
 
-    private HttpAgent getHttpAgent(ConfigService configService) {
-        HttpAgent agent = null;
-        try {
-            Field field = configService.getClass().getDeclaredField("agent");
-            field.setAccessible(true);
-            agent = (HttpAgent) field.get(configService);
-        } catch (Exception e) {
-            throw new IllegalStateException(e);
-        }
-        return agent;
-    }
-
     private Properties buildNacosProperties(URL url) {
         Properties properties = new Properties();
         setServerAddr(url, properties);
@@ -131,9 +103,9 @@ public class NacosDynamicConfiguration implements DynamicConfiguration {
 
     private void setServerAddr(URL url, Properties properties) {
         StringBuilder serverAddrBuilder =
-                new StringBuilder(url.getHost()) // Host
-                        .append(':')
-                        .append(url.getPort()); // Port
+            new StringBuilder(url.getHost()) // Host
+                .append(':')
+                .append(url.getPort()); // Port
 
         // Append backup parameter as other servers
         String backup = url.getParameter(BACKUP_KEY);
@@ -149,10 +121,10 @@ public class NacosDynamicConfiguration implements DynamicConfiguration {
         Map<String, String> parameters = url.getParameters(of(PropertyKeyConst.class));
         // Put all parameters
         properties.putAll(parameters);
-        if (StringUtils.isNotEmpty(url.getUsername())){
+        if (StringUtils.isNotEmpty(url.getUsername())) {
             properties.put(USERNAME, url.getUsername());
         }
-        if (StringUtils.isNotEmpty(url.getPassword())){
+        if (StringUtils.isNotEmpty(url.getPassword())) {
             properties.put(PASSWORD, url.getPassword());
         }
     }
@@ -195,7 +167,7 @@ public class NacosDynamicConfiguration implements DynamicConfiguration {
     public void addListener(String key, String group, ConfigurationListener listener) {
         String listenerKey = buildListenerKey(key, group);
         NacosConfigListener nacosConfigListener =
-                watchListenerMap.computeIfAbsent(listenerKey, k -> createTargetListener(key, group));
+            watchListenerMap.computeIfAbsent(listenerKey, k -> createTargetListener(key, group));
         nacosConfigListener.addListener(listener);
         try {
             configService.addListener(key, group, nacosConfigListener);
@@ -276,41 +248,6 @@ public class NacosDynamicConfiguration implements DynamicConfiguration {
         return DEFAULT_TIMEOUT;
     }
 
-    /**
-     * TODO Nacos does not support atomic update of the value mapped to a key.
-     *
-     * @param group the specified group
-     * @return
-     */
-    @Override
-    public SortedSet<String> getConfigKeys(String group) {
-        // TODO use Nacos Client API to replace HTTP Open API
-        SortedSet<String> keys = new TreeSet<>();
-        try {
-
-            Map<String, String> paramsValues = new HashMap<>();
-            paramsValues.put("search", "accurate");
-            paramsValues.put("dataId", "");
-            paramsValues.put("group", group.replace(SLASH_CHAR, HYPHEN_CHAR));
-            paramsValues.put("pageNo", "1");
-            paramsValues.put("pageSize", String.valueOf(Integer.MAX_VALUE));
-
-            String encoding = getProperty(ENCODE, "UTF-8");
-
-            HttpRestResult<String> result = httpAgent.httpGet(GET_CONFIG_KEYS_PATH, emptyMap(), paramsValues, encoding, 5 * 1000);
-            Stream<String> keysStream = toKeysStream(result.getData());
-            if (keysStream != null) {
-                keysStream.forEach(keys::add);
-            }
-        } catch (Exception e) {
-            if (logger.isErrorEnabled()) {
-                logger.error(e.getMessage(), e);
-            }
-        }
-        return keys;
-    }
-
-
     @Override
     public boolean removeConfig(String key, String group) {
         boolean removed = false;
@@ -324,20 +261,6 @@ public class NacosDynamicConfiguration implements DynamicConfiguration {
         return removed;
     }
 
-    private Stream<String> toKeysStream(String content) {
-        JSONObject jsonObject = JSON.parseObject(content);
-        if (jsonObject == null) {
-            return null;
-        }
-        JSONArray pageItems = jsonObject.getJSONArray("pageItems");
-        if (pageItems == null) {
-            return null;
-        }
-        return pageItems.stream()
-                .map(object -> (JSONObject) object)
-                .map(json -> json.getString("dataId"));
-    }
-
     private String getProperty(String name, String defaultValue) {
         return nacosProperties.getProperty(name, defaultValue);
     }
diff --git a/dubbo-configcenter/dubbo-configcenter-nacos/src/test/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfigurationTest.java b/dubbo-configcenter/dubbo-configcenter-nacos/src/test/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfigurationTest.java
index afafc1c750..4079a7d1cd 100644
--- a/dubbo-configcenter/dubbo-configcenter-nacos/src/test/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfigurationTest.java
+++ b/dubbo-configcenter/dubbo-configcenter-nacos/src/test/java/org/apache/dubbo/configcenter/support/nacos/NacosDynamicConfigurationTest.java
@@ -33,7 +33,6 @@ import org.junit.jupiter.api.Test;
 
 import java.util.HashMap;
 import java.util.Map;
-import java.util.SortedSet;
 import java.util.concurrent.CountDownLatch;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -102,18 +101,18 @@ public class NacosDynamicConfigurationTest {
         Assertions.assertEquals("new value2", listener4.getValue());
 
     }
-
-    @Test
-    public void testGetConfigKeys() {
-
-        put("key1", "a");
-        put("key2", "b");
-
-        SortedSet<String> keys = config.getConfigKeys(DynamicConfiguration.DEFAULT_GROUP);
-
-        Assertions.assertFalse(keys.isEmpty());
-
-    }
+//
+//    @Test
+//    public void testGetConfigKeys() {
+//
+//        put("key1", "a");
+//        put("key2", "b");
+//
+//        SortedSet<String> keys = config.getConfigKeys(DynamicConfiguration.DEFAULT_GROUP);
+//
+//        Assertions.assertFalse(keys.isEmpty());
+//
+//    }
 
     private void put(String key, String value) {
         put(key, DynamicConfiguration.DEFAULT_GROUP, value);
diff --git a/dubbo-configcenter/dubbo-configcenter-zookeeper/src/test/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfigurationTest.java b/dubbo-configcenter/dubbo-configcenter-zookeeper/src/test/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfigurationTest.java
index 23c5ca4d98..b5faadbd40 100644
--- a/dubbo-configcenter/dubbo-configcenter-zookeeper/src/test/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfigurationTest.java
+++ b/dubbo-configcenter/dubbo-configcenter-zookeeper/src/test/java/org/apache/dubbo/configcenter/support/zookeeper/ZookeeperDynamicConfigurationTest.java
@@ -35,11 +35,8 @@ import org.mockito.Mockito;
 
 import java.util.HashMap;
 import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
 import java.util.concurrent.CountDownLatch;
 
-import static java.util.Arrays.asList;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -166,22 +163,22 @@ public class ZookeeperDynamicConfigurationTest {
         assertFalse(configuration.publishConfigCas(key, group, "newtest2", configItem.getTicket()));
         assertEquals("newtest", configuration.getConfigItem(key, group).getContent());
     }
-
-    @Test
-    public void testGetConfigKeysAndContents() {
-
-        String group = "mapping";
-        String key = "org.apache.dubbo.service.UserService";
-        String content = "app1";
-
-        String key2 = "org.apache.dubbo.service.UserService2";
-
-        assertTrue(configuration.publishConfig(key, group, content));
-        assertTrue(configuration.publishConfig(key2, group, content));
-
-        Set<String> configKeys = configuration.getConfigKeys(group);
-
-        assertEquals(new TreeSet(asList(key, key2)), configKeys);
-    }
+//
+//    @Test
+//    public void testGetConfigKeysAndContents() {
+//
+//        String group = "mapping";
+//        String key = "org.apache.dubbo.service.UserService";
+//        String content = "app1";
+//
+//        String key2 = "org.apache.dubbo.service.UserService2";
+//
+//        assertTrue(configuration.publishConfig(key, group, content));
+//        assertTrue(configuration.publishConfig(key2, group, content));
+//
+//        Set<String> configKeys = configuration.getConfigKeys(group);
+//
+//        assertEquals(new TreeSet(asList(key, key2)), configKeys);
+//    }
 
 }
diff --git a/dubbo-demo/dubbo-demo-generic-call/src/main/java/org/apache/dubbo/demo/consumer/GenericApplication.java b/dubbo-demo/dubbo-demo-generic-call/src/main/java/org/apache/dubbo/demo/consumer/GenericApplication.java
index 610d2f1e9e..b7845f92ac 100644
--- a/dubbo-demo/dubbo-demo-generic-call/src/main/java/org/apache/dubbo/demo/consumer/GenericApplication.java
+++ b/dubbo-demo/dubbo-demo-generic-call/src/main/java/org/apache/dubbo/demo/consumer/GenericApplication.java
@@ -17,16 +17,15 @@
 package org.apache.dubbo.demo.consumer;
 
 import org.apache.dubbo.common.constants.CommonConstants;
+import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.config.ApplicationConfig;
 import org.apache.dubbo.config.MetadataReportConfig;
+import org.apache.dubbo.config.ProtocolConfig;
 import org.apache.dubbo.config.ReferenceConfig;
 import org.apache.dubbo.config.RegistryConfig;
-import org.apache.dubbo.config.ProtocolConfig;
 import org.apache.dubbo.config.bootstrap.DubboBootstrap;
 import org.apache.dubbo.rpc.service.GenericService;
 
-import com.google.gson.Gson;
-
 public class GenericApplication {
 
     public static void main(String[] args) {
@@ -42,7 +41,7 @@ public class GenericApplication {
 
         if (args.length > 0 && CommonConstants.GENERIC_SERIALIZATION_GSON.equals(args[0])) {
             reference.setGeneric(CommonConstants.GENERIC_SERIALIZATION_GSON);
-            param = new Gson().toJson(param + " gson");
+            param = JsonUtils.getJson().toJson(param + " gson");
         } else {
             reference.setGeneric("true");
         }
diff --git a/dubbo-metadata/dubbo-metadata-api/pom.xml b/dubbo-metadata/dubbo-metadata-api/pom.xml
index ecfd6bc19f..67e4dd8ff0 100644
--- a/dubbo-metadata/dubbo-metadata-api/pom.xml
+++ b/dubbo-metadata/dubbo-metadata-api/pom.xml
@@ -45,11 +45,6 @@
             <version>${project.parent.version}</version>
         </dependency>
 
-        <dependency>
-            <groupId>com.google.code.gson</groupId>
-            <artifactId>gson</artifactId>
-        </dependency>
-
         <!-- Test dependencies -->
         <dependency>
             <groupId>org.apache.dubbo</groupId>
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/AbstractCacheManager.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/AbstractCacheManager.java
index da05839f82..6f0277731f 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/AbstractCacheManager.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/AbstractCacheManager.java
@@ -138,7 +138,7 @@ public abstract class AbstractCacheManager<V> implements Disposable {
             cache.lock();
             try {
                 for (Map.Entry<String, V> entry : cache.entrySet()) {
-                    properties.put(entry.getKey(), JsonUtils.getGson().toJson(entry.getValue()));
+                    properties.put(entry.getKey(), JsonUtils.getJson().toJson(entry.getValue()));
                 }
             } finally {
                 cache.releaseLock();
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MappingCacheManager.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MappingCacheManager.java
index fd66737913..e5c04035d2 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MappingCacheManager.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MappingCacheManager.java
@@ -20,12 +20,9 @@ import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.rpc.model.ScopeModel;
 
-import com.google.gson.reflect.TypeToken;
-
-import java.lang.reflect.Type;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
-import java.util.TreeSet;
 import java.util.concurrent.ScheduledExecutorService;
 
 /**
@@ -34,8 +31,6 @@ import java.util.concurrent.ScheduledExecutorService;
 public class MappingCacheManager extends AbstractCacheManager<Set<String>> {
     private static final String DEFAULT_FILE_NAME = ".mapping";
     private static final int DEFAULT_ENTRY_SIZE = 10000;
-    private static final Type founderSetType = new TypeToken<TreeSet<String>>() {
-    }.getType();
 
     public static MappingCacheManager getInstance(ScopeModel scopeModel) {
         return scopeModel.getBeanFactory().getOrRegisterBean(MappingCacheManager.class);
@@ -64,7 +59,7 @@ public class MappingCacheManager extends AbstractCacheManager<Set<String>> {
 
     @Override
     protected Set<String> toValueType(String value) {
-        return JsonUtils.getGson().fromJson(value, founderSetType);
+        return new HashSet<>(JsonUtils.getJson().toJavaList(value, String.class));
     }
 
     @Override
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataInfo.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataInfo.java
index 443ac497d3..2735b931ee 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataInfo.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/MetadataInfo.java
@@ -187,7 +187,7 @@ public class MetadataInfo implements Serializable {
                     logger.info(String.format("metadata revision changed: %s -> %s, app: %s, services: %d", this.revision, tempRevision, this.app, this.services.size()));
                 }
                 this.revision = tempRevision;
-                this.rawMetadataInfo = JsonUtils.getGson().toJson(this);
+                this.rawMetadataInfo = JsonUtils.getJson().toJson(this);
             }
         }
         return revision;
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReport.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReport.java
index e8d8f68259..1e2d26c61e 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReport.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReport.java
@@ -21,6 +21,7 @@ import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.common.utils.CollectionUtils;
 import org.apache.dubbo.common.utils.ConfigUtils;
+import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.common.utils.NamedThreadFactory;
 import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
 import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
@@ -30,16 +31,12 @@ import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
 import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
 import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
 
-import com.google.gson.Gson;
-import com.google.gson.reflect.TypeToken;
-
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.RandomAccessFile;
-import java.lang.reflect.Type;
 import java.nio.channels.FileChannel;
 import java.nio.channels.FileLock;
 import java.util.ArrayList;
@@ -49,7 +46,6 @@ import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
-import java.util.SortedSet;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -165,7 +161,7 @@ public abstract class AbstractMetadataReport implements MetadataReport {
                 lockfile.createNewFile();
             }
             try (RandomAccessFile raf = new RandomAccessFile(lockfile, "rw");
-                FileChannel channel = raf.getChannel()) {
+                 FileChannel channel = raf.getChannel()) {
                 FileLock lock = channel.tryLock();
                 if (lock == null) {
                     throw new IOException("Can not lock the metadataReport cache file " + file.getAbsolutePath() + ", ignore and retry later, maybe multi java process use the file, please config: dubbo.metadata.file=xxx.properties");
@@ -278,8 +274,7 @@ public abstract class AbstractMetadataReport implements MetadataReport {
             }
             allMetadataReports.put(providerMetadataIdentifier, serviceDefinition);
             failedReports.remove(providerMetadataIdentifier);
-            Gson gson = new Gson();
-            String data = gson.toJson(serviceDefinition);
+            String data = JsonUtils.getJson().toJson(serviceDefinition);
             doStoreProviderMetadata(providerMetadataIdentifier, data);
             saveProperties(providerMetadataIdentifier, data, true, !syncReport);
         } catch (Exception e) {
@@ -307,8 +302,7 @@ public abstract class AbstractMetadataReport implements MetadataReport {
             allMetadataReports.put(consumerMetadataIdentifier, serviceParameterMap);
             failedReports.remove(consumerMetadataIdentifier);
 
-            Gson gson = new Gson();
-            String data = gson.toJson(serviceParameterMap);
+            String data = JsonUtils.getJson().toJson(serviceParameterMap);
             doStoreConsumerMetadata(consumerMetadataIdentifier, data);
             saveProperties(consumerMetadataIdentifier, data, true, !syncReport);
         } catch (Exception e) {
@@ -360,9 +354,9 @@ public abstract class AbstractMetadataReport implements MetadataReport {
     @Override
     public void saveSubscribedData(SubscriberMetadataIdentifier subscriberMetadataIdentifier, Set<String> urls) {
         if (syncReport) {
-            doSaveSubscriberData(subscriberMetadataIdentifier, new Gson().toJson(urls));
+            doSaveSubscriberData(subscriberMetadataIdentifier, JsonUtils.getJson().toJson(urls));
         } else {
-            reportCacheExecutor.execute(() -> doSaveSubscriberData(subscriberMetadataIdentifier, new Gson().toJson(urls)));
+            reportCacheExecutor.execute(() -> doSaveSubscriberData(subscriberMetadataIdentifier, JsonUtils.getJson().toJson(urls)));
         }
     }
 
@@ -370,9 +364,7 @@ public abstract class AbstractMetadataReport implements MetadataReport {
     @Override
     public List<String> getSubscribedURLs(SubscriberMetadataIdentifier subscriberMetadataIdentifier) {
         String content = doGetSubscribedURLs(subscriberMetadataIdentifier);
-        Type setType = new TypeToken<SortedSet<String>>() {
-        }.getType();
-        return new Gson().fromJson(content, setType);
+        return JsonUtils.getJson().toJavaList(content, String.class);
     }
 
     String getProtocol(URL url) {
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ClassPathServiceRestMetadataReader.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ClassPathServiceRestMetadataReader.java
index f8b9514fa8..9530df23f0 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ClassPathServiceRestMetadataReader.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/ClassPathServiceRestMetadataReader.java
@@ -16,13 +16,10 @@
  */
 package org.apache.dubbo.metadata.rest;
 
-import com.google.gson.Gson;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonParser;
+import org.apache.dubbo.common.utils.IOUtils;
+import org.apache.dubbo.common.utils.JsonUtils;
 
 import java.io.InputStream;
-import java.io.InputStreamReader;
 import java.net.URL;
 import java.util.Enumeration;
 import java.util.LinkedList;
@@ -60,20 +57,11 @@ public class ClassPathServiceRestMetadataReader implements ServiceRestMetadataRe
 
         execute(() -> {
             Enumeration<URL> resources = classLoader.getResources(serviceRestMetadataJsonResourcePath);
-            Gson gson = new Gson();
             while (resources.hasMoreElements()) {
                 URL resource = resources.nextElement();
                 InputStream inputStream = resource.openStream();
-                JsonParser parser = new JsonParser();
-                JsonElement jsonElement = parser.parse(new InputStreamReader(inputStream, METADATA_ENCODING));
-                if (jsonElement.isJsonArray()) {
-                    JsonArray jsonArray = jsonElement.getAsJsonArray();
-                    for (int i = 0; i < jsonArray.size(); i++) {
-                        JsonElement childJsonElement = jsonArray.get(i);
-                        ServiceRestMetadata serviceRestMetadata = gson.fromJson(childJsonElement, ServiceRestMetadata.class);
-                        serviceRestMetadataList.add(serviceRestMetadata);
-                    }
-                }
+                String json = IOUtils.read(inputStream, METADATA_ENCODING);
+                serviceRestMetadataList.addAll(JsonUtils.getJson().toJavaList(json, ServiceRestMetadata.class));
             }
         });
 
diff --git a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/RequestMetadata.java b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/RequestMetadata.java
index dd797ca875..9a9983e4e8 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/RequestMetadata.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/main/java/org/apache/dubbo/metadata/rest/RequestMetadata.java
@@ -21,6 +21,7 @@ import org.apache.dubbo.common.utils.CollectionUtils;
 
 import java.io.Serializable;
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
@@ -140,11 +141,11 @@ public class RequestMetadata implements Serializable {
     }
 
     public Set<String> getParamNames() {
-        return params.keySet();
+        return new HashSet<>(params.keySet());
     }
 
     public Set<String> getHeaderNames() {
-        return headers.keySet();
+        return new HashSet<>(headers.keySet());
     }
 
 //    public List<MediaType> getConsumeMediaTypes() {
@@ -182,7 +183,7 @@ public class RequestMetadata implements Serializable {
         if (headers != null && !headers.isEmpty()) {
             Map<String, List<String>> httpHeaders = new LinkedHashMap<>();
             // Add all headers
-            addAll(headers, httpHeaders);
+            addAll(httpHeaders, headers);
             // Handles "Content-Type" and "Accept" headers if present
 //            mediaTypes(httpHeaders, HttpHeaders.CONTENT_TYPE, this.consumes);
 //            mediaTypes(httpHeaders, HttpHeaders.ACCEPT, this.produces);
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/MetadataInfoTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/MetadataInfoTest.java
index dde0d85142..358e66856b 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/MetadataInfoTest.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/MetadataInfoTest.java
@@ -17,8 +17,8 @@
 package org.apache.dubbo.metadata;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.JsonUtils;
 
-import com.google.gson.Gson;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
@@ -152,14 +152,13 @@ public class MetadataInfoTest {
 
         // export normal url again
         metadataInfo.addService(url);
-        Gson gson = new Gson();
-        System.out.println(gson.toJson(metadataInfo));
+        System.out.println(JsonUtils.getJson().toJson(metadataInfo));
 
         MetadataInfo metadataInfo2 = new MetadataInfo("demo");
         // export normal url again
         metadataInfo2.addService(url);
         metadataInfo2.addService(url2);
-        System.out.println(gson.toJson(metadataInfo2));
+        System.out.println(JsonUtils.getJson().toJson(metadataInfo2));
 
     }
 }
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportFactoryTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportFactoryTest.java
index 5ec5f2bf3d..99e5cb114b 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportFactoryTest.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportFactoryTest.java
@@ -17,6 +17,7 @@
 package org.apache.dubbo.metadata.report.support;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.common.utils.NetUtils;
 import org.apache.dubbo.metadata.MappingListener;
 import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
@@ -25,7 +26,6 @@ import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
 import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
 import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
 
-import com.alibaba.fastjson.JSON;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 
@@ -46,7 +46,7 @@ public class AbstractMetadataReportFactoryTest {
 
                 @Override
                 public void storeProviderMetadata(MetadataIdentifier providerMetadataIdentifier, ServiceDefinition serviceDefinition) {
-                    store.put(providerMetadataIdentifier.getIdentifierKey(), JSON.toJSONString(serviceDefinition));
+                    store.put(providerMetadataIdentifier.getIdentifierKey(), JsonUtils.getJson().toJson(serviceDefinition));
                 }
 
                 @Override
@@ -101,7 +101,7 @@ public class AbstractMetadataReportFactoryTest {
 
                 @Override
                 public void storeConsumerMetadata(MetadataIdentifier consumerMetadataIdentifier, Map serviceParameterMap) {
-                    store.put(consumerMetadataIdentifier.getIdentifierKey(), JSON.toJSONString(serviceParameterMap));
+                    store.put(consumerMetadataIdentifier.getIdentifierKey(), JsonUtils.getJson().toJson(serviceParameterMap));
                 }
 
                 Map<String, String> store = new ConcurrentHashMap<>();
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportTest.java
index 624a97fedd..99a0c44178 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportTest.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/report/support/AbstractMetadataReportTest.java
@@ -18,6 +18,7 @@
 package org.apache.dubbo.metadata.report.support;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.common.utils.NetUtils;
 import org.apache.dubbo.config.ApplicationConfig;
 import org.apache.dubbo.metadata.MappingListener;
@@ -29,7 +30,6 @@ import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
 import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 
-import com.google.gson.Gson;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
@@ -237,18 +237,15 @@ public class AbstractMetadataReportTest {
         assertEquals(3, abstractMetadataReport.store.size());
 
         String v = abstractMetadataReport.store.get(providerMetadataIdentifier1.getUniqueKey(KeyTypeEnum.UNIQUE_KEY));
-        Gson gson = new Gson();
-        FullServiceDefinition data = gson.fromJson(v, FullServiceDefinition.class);
+        FullServiceDefinition data = JsonUtils.getJson().toJavaObject(v, FullServiceDefinition.class);
         checkParam(data.getParameters(), application, version);
 
         String v2 = abstractMetadataReport.store.get(providerMetadataIdentifier2.getUniqueKey(KeyTypeEnum.UNIQUE_KEY));
-        gson = new Gson();
-        data = gson.fromJson(v2, FullServiceDefinition.class);
+        data = JsonUtils.getJson().toJavaObject(v2, FullServiceDefinition.class);
         checkParam(data.getParameters(), application, version + "_2");
 
         String v3 = abstractMetadataReport.store.get(consumerMetadataIdentifier.getUniqueKey(KeyTypeEnum.UNIQUE_KEY));
-        gson = new Gson();
-        Map v3Map = gson.fromJson(v3, Map.class);
+        Map v3Map = JsonUtils.getJson().toJavaObject(v3, Map.class);
         checkParam(v3Map, application, version + "_3");
     }
 
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/jaxrs/JAXRSServiceRestMetadataResolverTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/jaxrs/JAXRSServiceRestMetadataResolverTest.java
index 53c5428867..1ebaf3a86a 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/jaxrs/JAXRSServiceRestMetadataResolverTest.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/jaxrs/JAXRSServiceRestMetadataResolverTest.java
@@ -16,9 +16,9 @@
  */
 package org.apache.dubbo.metadata.rest.jaxrs;
 
+import org.apache.dubbo.common.utils.CollectionUtils;
 import org.apache.dubbo.metadata.rest.ClassPathServiceRestMetadataReader;
 import org.apache.dubbo.metadata.rest.DefaultRestService;
-import org.apache.dubbo.metadata.rest.RestMethodMetadata;
 import org.apache.dubbo.metadata.rest.RestService;
 import org.apache.dubbo.metadata.rest.ServiceRestMetadata;
 import org.apache.dubbo.metadata.rest.SpringRestService;
@@ -26,7 +26,6 @@ import org.apache.dubbo.metadata.rest.StandardRestService;
 
 import org.junit.jupiter.api.Test;
 
-import java.util.LinkedList;
 import java.util.List;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -65,15 +64,7 @@ public class JAXRSServiceRestMetadataResolverTest {
         ServiceRestMetadata expectedServiceRestMetadata = serviceRestMetadataList.get(0);
         ServiceRestMetadata serviceRestMetadata = instance.resolve(StandardRestService.class);
 
-
-        List<RestMethodMetadata> meta1 = new LinkedList<>(expectedServiceRestMetadata.getMeta());
-        List<RestMethodMetadata> meta2 = new LinkedList<>(serviceRestMetadata.getMeta());
-
-        for (int i = 0; i < meta1.size(); i++) {
-            RestMethodMetadata restMethodMetadata = meta1.get(i);
-            RestMethodMetadata restMethodMetadata2 = meta2.get(i);
-            assertEquals(restMethodMetadata, restMethodMetadata2);
-        }
+        assertTrue(CollectionUtils.equals(expectedServiceRestMetadata.getMeta(), serviceRestMetadata.getMeta()));
 
         assertEquals(expectedServiceRestMetadata, serviceRestMetadata);
 
diff --git a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/springmvc/SpringMvcServiceRestMetadataResolverTest.java b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/springmvc/SpringMvcServiceRestMetadataResolverTest.java
index 0d1da964d5..4fd0e1a164 100644
--- a/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/springmvc/SpringMvcServiceRestMetadataResolverTest.java
+++ b/dubbo-metadata/dubbo-metadata-api/src/test/java/org/apache/dubbo/metadata/rest/springmvc/SpringMvcServiceRestMetadataResolverTest.java
@@ -16,9 +16,9 @@
  */
 package org.apache.dubbo.metadata.rest.springmvc;
 
+import org.apache.dubbo.common.utils.CollectionUtils;
 import org.apache.dubbo.metadata.rest.ClassPathServiceRestMetadataReader;
 import org.apache.dubbo.metadata.rest.DefaultRestService;
-import org.apache.dubbo.metadata.rest.RestMethodMetadata;
 import org.apache.dubbo.metadata.rest.RestService;
 import org.apache.dubbo.metadata.rest.ServiceRestMetadata;
 import org.apache.dubbo.metadata.rest.SpringRestService;
@@ -26,7 +26,6 @@ import org.apache.dubbo.metadata.rest.StandardRestService;
 
 import org.junit.jupiter.api.Test;
 
-import java.util.LinkedList;
 import java.util.List;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -65,15 +64,7 @@ public class SpringMvcServiceRestMetadataResolverTest {
         ServiceRestMetadata expectedServiceRestMetadata = serviceRestMetadataList.get(0);
         ServiceRestMetadata serviceRestMetadata = instance.resolve(SpringRestService.class);
 
-
-        List<RestMethodMetadata> meta1 = new LinkedList<>(expectedServiceRestMetadata.getMeta());
-        List<RestMethodMetadata> meta2 = new LinkedList<>(serviceRestMetadata.getMeta());
-
-        for (int i = 0; i < meta1.size(); i++) {
-            RestMethodMetadata restMethodMetadata = meta1.get(i);
-            RestMethodMetadata restMethodMetadata2 = meta2.get(i);
-            assertEquals(restMethodMetadata, restMethodMetadata2);
-        }
+        assertTrue(CollectionUtils.equals(expectedServiceRestMetadata.getMeta(), serviceRestMetadata.getMeta()));
 
         assertEquals(expectedServiceRestMetadata, serviceRestMetadata);
 
diff --git a/dubbo-metadata/dubbo-metadata-processor/pom.xml b/dubbo-metadata/dubbo-metadata-processor/pom.xml
index 8da0780840..0cb2c9139d 100644
--- a/dubbo-metadata/dubbo-metadata-processor/pom.xml
+++ b/dubbo-metadata/dubbo-metadata-processor/pom.xml
@@ -45,10 +45,6 @@
                     <groupId>org.apache.dubbo</groupId>
                     <artifactId>dubbo-cluster</artifactId>
                 </exclusion>
-                <exclusion>
-                    <groupId>com.google.code.gson</groupId>
-                    <artifactId>gson</artifactId>
-                </exclusion>
             </exclusions>
         </dependency>
 
@@ -93,10 +89,6 @@
                     <groupId>com.alibaba</groupId>
                     <artifactId>hessian-lite</artifactId>
                 </exclusion>
-                <exclusion>
-                    <groupId>com.alibaba</groupId>
-                    <artifactId>fastjson</artifactId>
-                </exclusion>
                 <exclusion>
                     <groupId>com.esotericsoftware</groupId>
                     <artifactId>kryo</artifactId>
@@ -117,11 +109,6 @@
 
         </dependency>
 
-        <dependency>
-            <groupId>com.google.code.gson</groupId>
-            <artifactId>gson</artifactId>
-        </dependency>
-
         <!-- Test -->
         <dependency>
             <groupId>org.apache.dubbo</groupId>
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/ServiceDefinitionMetadataAnnotationProcessor.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/ServiceDefinitionMetadataAnnotationProcessor.java
index e5d736a416..cbeecc9073 100644
--- a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/ServiceDefinitionMetadataAnnotationProcessor.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/ServiceDefinitionMetadataAnnotationProcessor.java
@@ -16,10 +16,9 @@
  */
 package org.apache.dubbo.metadata.annotation.processing;
 
+import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.metadata.definition.model.ServiceDefinition;
 
-import com.google.gson.Gson;
-
 import javax.annotation.processing.ProcessingEnvironment;
 import javax.annotation.processing.Processor;
 import javax.annotation.processing.RoundEnvironment;
@@ -48,7 +47,7 @@ public class ServiceDefinitionMetadataAnnotationProcessor extends AbstractServic
 
         if (roundEnv.processingOver()) {
             ClassPathMetadataStorage writer = new ClassPathMetadataStorage(processingEnv);
-            writer.write(() -> new Gson().toJson(serviceDefinitions), "META-INF/dubbo/service-definitions.json");
+            writer.write(() -> JsonUtils.getJson().toJson(serviceDefinitions), "META-INF/dubbo/service-definitions.json");
         }
 
         return false;
diff --git a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/ServiceRestMetadataStorage.java b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/ServiceRestMetadataStorage.java
index 73e9871181..48bf5d7197 100644
--- a/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/ServiceRestMetadataStorage.java
+++ b/dubbo-metadata/dubbo-metadata-processor/src/main/java/org/apache/dubbo/metadata/annotation/processing/rest/ServiceRestMetadataStorage.java
@@ -16,17 +16,14 @@
  */
 package org.apache.dubbo.metadata.annotation.processing.rest;
 
+import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.metadata.annotation.processing.ClassPathMetadataStorage;
 import org.apache.dubbo.metadata.rest.ServiceRestMetadata;
 
-import com.google.gson.Gson;
-
 import javax.annotation.processing.ProcessingEnvironment;
 import java.io.IOException;
-import java.util.List;
 import java.util.Set;
 
-import static com.google.gson.reflect.TypeToken.getParameterized;
 import static org.apache.dubbo.metadata.rest.RestMetadataConstants.SERVICE_REST_METADATA_RESOURCE_PATH;
 
 /**
@@ -41,13 +38,20 @@ public class ServiceRestMetadataStorage {
     }
 
     public void append(Set<ServiceRestMetadata> serviceRestMetadata) throws IOException {
+        // Add all existed ServiceRestMetadata
         storage.read(SERVICE_REST_METADATA_RESOURCE_PATH, reader -> {
-            Gson gson = new Gson();
-            return (List) gson.fromJson(reader, getParameterized(List.class, ServiceRestMetadata.class).getType());
-        }).ifPresent(existedMetadata -> {
-            // Add all existed ServiceRestMetadata
-            serviceRestMetadata.addAll(existedMetadata);
-        });
+            try {
+                StringBuilder stringBuilder = new StringBuilder();
+                char[] buf = new char[1024];
+                int len;
+                while ((len = reader.read(buf)) != -1) {
+                    stringBuilder.append(buf, 0, len);
+                }
+                return JsonUtils.getJson().toJavaList(stringBuilder.toString(), ServiceRestMetadata.class);
+            } catch (IOException e) {
+                return null;
+            }
+        }).ifPresent(serviceRestMetadata::addAll);
         write(serviceRestMetadata);
     }
 
@@ -55,7 +59,7 @@ public class ServiceRestMetadataStorage {
         if (serviceRestMetadata.isEmpty()) {
             return;
         }
-        storage.write(() -> new Gson().toJson(serviceRestMetadata), SERVICE_REST_METADATA_RESOURCE_PATH);
+        storage.write(() -> JsonUtils.getJson().toJson(serviceRestMetadata), SERVICE_REST_METADATA_RESOURCE_PATH);
     }
 
 }
diff --git a/dubbo-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReport.java b/dubbo-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReport.java
index 64269b9b39..4ed5ca71bf 100644
--- a/dubbo-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReport.java
+++ b/dubbo-metadata/dubbo-metadata-report-nacos/src/main/java/org/apache/dubbo/metadata/store/nacos/NacosMetadataReport.java
@@ -167,7 +167,7 @@ public class NacosMetadataReport extends AbstractMetadataReport {
     public MetadataInfo getAppMetadata(SubscriberMetadataIdentifier identifier, Map<String, String> instanceMetadata) {
         try {
             String content = configService.getConfig(identifier.getApplication(), identifier.getRevision(), 3000L);
-            return JsonUtils.getGson().fromJson(content, MetadataInfo.class);
+            return JsonUtils.getJson().toJavaObject(content, MetadataInfo.class);
         } catch (NacosException e) {
             throw new IllegalStateException(e.getMessage(), e);
         }
diff --git a/dubbo-metadata/dubbo-metadata-report-redis/src/test/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReportTest.java b/dubbo-metadata/dubbo-metadata-report-redis/src/test/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReportTest.java
index 989c037457..445363cb79 100644
--- a/dubbo-metadata/dubbo-metadata-report-redis/src/test/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReportTest.java
+++ b/dubbo-metadata/dubbo-metadata-report-redis/src/test/java/org/apache/dubbo/metadata/store/redis/RedisMetadataReportTest.java
@@ -17,6 +17,7 @@
 package org.apache.dubbo.metadata.store.redis;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.common.utils.NetUtils;
 import org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
 import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
@@ -24,7 +25,6 @@ import org.apache.dubbo.metadata.report.identifier.KeyTypeEnum;
 import org.apache.dubbo.metadata.report.identifier.MetadataIdentifier;
 import org.apache.dubbo.rpc.RpcException;
 
-import com.google.gson.Gson;
 import org.apache.commons.lang3.SystemUtils;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Assertions;
@@ -49,9 +49,9 @@ import static redis.embedded.RedisServer.newRedisServer;
 public class RedisMetadataReportTest {
 
     private static final String
-            REDIS_URL_TEMPLATE = "redis://%slocalhost:%d",
-            REDIS_PASSWORD = "チェリー",
-            REDIS_URL_AUTH_SECTION = "username:" + REDIS_PASSWORD + "@";
+        REDIS_URL_TEMPLATE = "redis://%slocalhost:%d",
+        REDIS_PASSWORD = "チェリー",
+        REDIS_URL_AUTH_SECTION = "username:" + REDIS_PASSWORD + "@";
 
     RedisMetadataReport redisMetadataReport;
     RedisMetadataReport syncRedisMetadataReport;
@@ -68,11 +68,11 @@ public class RedisMetadataReportTest {
             try {
                 redisPort = NetUtils.getAvailablePort(30000 + new Random().nextInt(10000));
                 redisServer = newRedisServer()
-                        .port(redisPort)
-                        // set maxheap to fix Windows error 0x70 while starting redis
-                        .settingIf(SystemUtils.IS_OS_WINDOWS, "maxheap 128mb")
-                        .settingIf(usesAuthentication, "requirepass " + REDIS_PASSWORD)
-                        .build();
+                    .port(redisPort)
+                    // set maxheap to fix Windows error 0x70 while starting redis
+                    .settingIf(SystemUtils.IS_OS_WINDOWS, "maxheap 128mb")
+                    .settingIf(usesAuthentication, "requirepass " + REDIS_PASSWORD)
+                    .build();
                 this.redisServer.start();
                 exception = null;
             } catch (IOException e) {
@@ -87,7 +87,7 @@ public class RedisMetadataReportTest {
         Assertions.assertNull(exception);
         registryUrl = newRedisUrl(usesAuthentication, redisPort);
         redisMetadataReport = (RedisMetadataReport) new RedisMetadataReportFactory().createMetadataReport(registryUrl);
-        URL syncRegistryUrl = registryUrl.addParameter(SYNC_REPORT_KEY ,"true");
+        URL syncRegistryUrl = registryUrl.addParameter(SYNC_REPORT_KEY, "true");
         syncRedisMetadataReport = (RedisMetadataReport) new RedisMetadataReportFactory().createMetadataReport(syncRegistryUrl);
     }
 
@@ -133,8 +133,7 @@ public class RedisMetadataReportTest {
 
             Assertions.assertNotNull(value);
 
-            Gson gson = new Gson();
-            FullServiceDefinition fullServiceDefinition = gson.fromJson(value, FullServiceDefinition.class);
+            FullServiceDefinition fullServiceDefinition = JsonUtils.getJson().toJavaObject(value, FullServiceDefinition.class);
             Assertions.assertEquals(fullServiceDefinition.getParameters().get("paramTest"), "redisTest");
         } catch (Throwable e) {
             throw new RpcException("Failed to put to redis . cause: " + e.getMessage(), e);
@@ -183,7 +182,7 @@ public class RedisMetadataReportTest {
 
     private MetadataIdentifier storePrivider(RedisMetadataReport redisMetadataReport, String interfaceName, String version, String group, String application) throws ClassNotFoundException {
         URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + interfaceName + "?paramTest=redisTest&version=" + version + "&application="
-                + application + (group == null ? "" : "&group=" + group));
+            + application + (group == null ? "" : "&group=" + group));
 
         MetadataIdentifier providerMetadataIdentifier = new MetadataIdentifier(interfaceName, version, group, PROVIDER_SIDE, application);
         Class interfaceClass = Class.forName(interfaceName);
@@ -200,7 +199,7 @@ public class RedisMetadataReportTest {
 
     private MetadataIdentifier storeConsumer(RedisMetadataReport redisMetadataReport, String interfaceName, String version, String group, String application) throws ClassNotFoundException {
         URL url = URL.valueOf("xxx://" + NetUtils.getLocalAddress().getHostName() + ":4444/" + interfaceName + "?version=" + version + "&application="
-                + application + (group == null ? "" : "&group=" + group));
+            + application + (group == null ? "" : "&group=" + group));
 
         MetadataIdentifier consumerMetadataIdentifier = new MetadataIdentifier(interfaceName, version, group, CONSUMER_SIDE, application);
         Class interfaceClass = Class.forName(interfaceName);
diff --git a/dubbo-metadata/dubbo-metadata-report-zookeeper/src/main/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReport.java b/dubbo-metadata/dubbo-metadata-report-zookeeper/src/main/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReport.java
index d7726a365c..c6334429d9 100644
--- a/dubbo-metadata/dubbo-metadata-report-zookeeper/src/main/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReport.java
+++ b/dubbo-metadata/dubbo-metadata-report-zookeeper/src/main/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReport.java
@@ -155,7 +155,7 @@ public class ZookeeperMetadataReport extends AbstractMetadataReport {
     @Override
     public MetadataInfo getAppMetadata(SubscriberMetadataIdentifier identifier, Map<String, String> instanceMetadata) {
         String content = zkClient.getContent(getNodePath(identifier));
-        return JsonUtils.getGson().fromJson(content, MetadataInfo.class);
+        return JsonUtils.getJson().toJavaObject(content, MetadataInfo.class);
     }
 
     @Override
diff --git a/dubbo-metadata/dubbo-metadata-report-zookeeper/src/test/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReportTest.java b/dubbo-metadata/dubbo-metadata-report-zookeeper/src/test/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReportTest.java
index 04cd436463..c585db9083 100644
--- a/dubbo-metadata/dubbo-metadata-report-zookeeper/src/test/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReportTest.java
+++ b/dubbo-metadata/dubbo-metadata-report-zookeeper/src/test/java/org/apache/dubbo/metadata/store/zookeeper/ZookeeperMetadataReportTest.java
@@ -18,6 +18,7 @@ package org.apache.dubbo.metadata.store.zookeeper;
 
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.config.configcenter.ConfigItem;
+import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.common.utils.NetUtils;
 import org.apache.dubbo.metadata.MappingChangedEvent;
 import org.apache.dubbo.metadata.MappingListener;
@@ -31,7 +32,6 @@ import org.apache.dubbo.metadata.report.identifier.ServiceMetadataIdentifier;
 import org.apache.dubbo.metadata.report.identifier.SubscriberMetadataIdentifier;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 
-import com.google.gson.Gson;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
@@ -100,8 +100,7 @@ public class ZookeeperMetadataReportTest {
         fileContent = waitSeconds(fileContent, 3500, zookeeperMetadataReport.getNodePath(providerMetadataIdentifier));
         Assertions.assertNotNull(fileContent);
 
-        Gson gson = new Gson();
-        FullServiceDefinition fullServiceDefinition = gson.fromJson(fileContent, FullServiceDefinition.class);
+        FullServiceDefinition fullServiceDefinition = JsonUtils.getJson().toJavaObject(fileContent, FullServiceDefinition.class);
         Assertions.assertEquals(fullServiceDefinition.getParameters().get("paramTest"), "zkTest");
     }
 
@@ -204,8 +203,7 @@ public class ZookeeperMetadataReportTest {
         String protocol = "xxx";
         URL url = generateURL(interfaceName, version, group, application);
         SubscriberMetadataIdentifier subscriberMetadataIdentifier = new SubscriberMetadataIdentifier(application, revision);
-        Gson gson = new Gson();
-        String r = gson.toJson(Arrays.asList(url));
+        String r = JsonUtils.getJson().toJson(Arrays.asList(url.toString()));
         zookeeperMetadataReport.doSaveSubscriberData(subscriberMetadataIdentifier, r);
 
         String fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(subscriberMetadataIdentifier));
@@ -225,8 +223,7 @@ public class ZookeeperMetadataReportTest {
         String protocol = "xxx";
         URL url = generateURL(interfaceName, version, group, application);
         SubscriberMetadataIdentifier subscriberMetadataIdentifier = new SubscriberMetadataIdentifier(application, revision);
-        Gson gson = new Gson();
-        String r = gson.toJson(Arrays.asList(url));
+        String r = JsonUtils.getJson().toJson(Arrays.asList(url.toString()));
         zookeeperMetadataReport.doSaveSubscriberData(subscriberMetadataIdentifier, r);
 
         String fileContent = zookeeperMetadataReport.zkClient.getContent(zookeeperMetadataReport.getNodePath(subscriberMetadataIdentifier));
diff --git a/dubbo-monitor/dubbo-monitor-default/pom.xml b/dubbo-monitor/dubbo-monitor-default/pom.xml
index 68a1bac9d1..4489e84ac2 100644
--- a/dubbo-monitor/dubbo-monitor-default/pom.xml
+++ b/dubbo-monitor/dubbo-monitor-default/pom.xml
@@ -66,11 +66,5 @@
             <version>${project.parent.version}</version>
             <scope>test</scope>
         </dependency>
-
-        <dependency>
-            <groupId>com.google.code.gson</groupId>
-            <artifactId>gson</artifactId>
-            <scope>test</scope>
-        </dependency>
     </dependencies>
 </project>
diff --git a/dubbo-monitor/dubbo-monitor-default/src/main/java/org/apache/dubbo/monitor/dubbo/MetricsFilter.java b/dubbo-monitor/dubbo-monitor-default/src/main/java/org/apache/dubbo/monitor/dubbo/MetricsFilter.java
index da552bff52..4edd4a3c98 100644
--- a/dubbo-monitor/dubbo-monitor-default/src/main/java/org/apache/dubbo/monitor/dubbo/MetricsFilter.java
+++ b/dubbo-monitor/dubbo-monitor-default/src/main/java/org/apache/dubbo/monitor/dubbo/MetricsFilter.java
@@ -22,6 +22,7 @@ import org.apache.dubbo.common.extension.ExtensionAccessorAware;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.common.store.DataStore;
+import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.common.utils.NetUtils;
 import org.apache.dubbo.monitor.MetricsService;
 import org.apache.dubbo.rpc.AsyncRpcResult;
@@ -35,7 +36,6 @@ import org.apache.dubbo.rpc.model.ApplicationModel;
 import org.apache.dubbo.rpc.model.ScopeModelAware;
 import org.apache.dubbo.rpc.support.RpcUtils;
 
-import com.alibaba.fastjson.JSON;
 import com.alibaba.metrics.FastCompass;
 import com.alibaba.metrics.MetricLevel;
 import com.alibaba.metrics.MetricManager;
@@ -94,12 +94,12 @@ public class MetricsFilter implements Filter, ExtensionAccessorAware, ScopeModel
     public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
         if (exported.compareAndSet(false, true)) {
             this.protocolName = invoker.getUrl().getParameter(METRICS_PROTOCOL) == null ?
-                    DEFAULT_PROTOCOL : invoker.getUrl().getParameter(METRICS_PROTOCOL);
+                DEFAULT_PROTOCOL : invoker.getUrl().getParameter(METRICS_PROTOCOL);
 
             Protocol protocol = extensionAccessor.getExtensionLoader(Protocol.class).getExtension(protocolName);
 
             this.port = invoker.getUrl().getParameter(METRICS_PORT) == null ?
-                    protocol.getDefaultPort() : Integer.valueOf(invoker.getUrl().getParameter(METRICS_PORT));
+                protocol.getDefaultPort() : Integer.valueOf(invoker.getUrl().getParameter(METRICS_PORT));
 
             Invoker<MetricsService> metricsInvoker = initMetricsInvoker();
 
@@ -107,7 +107,7 @@ public class MetricsFilter implements Filter, ExtensionAccessorAware, ScopeModel
                 protocol.export(metricsInvoker);
             } catch (RuntimeException e) {
                 logger.error("Metrics Service need to be configured" +
-                        " when multiple processes are running on a host" + e.getMessage());
+                    " when multiple processes are running on a host" + e.getMessage());
             }
         }
 
@@ -151,7 +151,7 @@ public class MetricsFilter implements Filter, ExtensionAccessorAware, ScopeModel
         method.append(')');
         Class<?> returnType = RpcUtils.getReturnType(invocation);
         String typeName = null;
-        if(returnType != null) {
+        if (returnType != null) {
             typeName = returnType.getTypeName();
             typeName = typeName.substring(typeName.lastIndexOf(".") + 1);
         }
@@ -218,10 +218,10 @@ public class MetricsFilter implements Filter, ExtensionAccessorAware, ScopeModel
         }
 
         return new MetricObject
-                .Builder(metric)
-                .withValue(value)
-                .withLevel(level)
-                .build();
+            .Builder(metric)
+            .withValue(value)
+            .withLevel(level)
+            .build();
     }
 
     private Invoker<MetricsService> initMetricsInvoker() {
@@ -244,7 +244,7 @@ public class MetricsFilter implements Filter, ExtensionAccessorAware, ScopeModel
 
 
                 MetricsCollector collector = MetricsCollectorFactory.createNew(
-                        CollectLevel.NORMAL, Collections.EMPTY_MAP, rateFactor, durationFactor, null);
+                    CollectLevel.NORMAL, Collections.EMPTY_MAP, rateFactor, durationFactor, null);
 
                 for (Map.Entry<MetricName, FastCompass> entry : fastCompasses.entrySet()) {
                     collector.collect(entry.getKey(), entry.getValue(), timestamp);
@@ -252,7 +252,7 @@ public class MetricsFilter implements Filter, ExtensionAccessorAware, ScopeModel
 
                 List res = collector.build();
                 res.addAll(getThreadPoolMessage());
-                return AsyncRpcResult.newDefaultAsyncResult(JSON.toJSONString(res), invocation);
+                return AsyncRpcResult.newDefaultAsyncResult(JsonUtils.getJson().toJson(res), invocation);
             }
 
             @Override
diff --git a/dubbo-monitor/dubbo-monitor-default/src/test/java/org/apache/dubbo/monitor/dubbo/MetricsFilterTest.java b/dubbo-monitor/dubbo-monitor-default/src/test/java/org/apache/dubbo/monitor/dubbo/MetricsFilterTest.java
index 4d131bd54a..ac6dd55206 100644
--- a/dubbo-monitor/dubbo-monitor-default/src/test/java/org/apache/dubbo/monitor/dubbo/MetricsFilterTest.java
+++ b/dubbo-monitor/dubbo-monitor-default/src/test/java/org/apache/dubbo/monitor/dubbo/MetricsFilterTest.java
@@ -81,7 +81,7 @@ public class MetricsFilterTest {
 
     private URL getUrl() {
         return URL.valueOf("dubbo://" + NetUtils.getLocalHost() + ":" + port +
-                "/org.apache.dubbo.monitor.dubbo.service.DemoService?" + "metrics.port" + "=" + port);
+            "/org.apache.dubbo.monitor.dubbo.service.DemoService?" + "metrics.port" + "=" + port);
     }
 
     private void onInvokeReturns(Invoker<DemoService> invoker, AppResponse response) {
@@ -145,7 +145,7 @@ public class MetricsFilterTest {
         URL url = getUrl().addParameter(SIDE_KEY, CONSUMER_SIDE);
         Invoker<DemoService> invoker = invokerFunction.apply(url);
         AppResponse response = AppResponseBuilder.create()
-                .build();
+            .build();
         onInvokeReturns(invoker, response);
         for (int i = 0; i < 100; i++) {
             metricsFilter.invoke(invoker, invocation);
@@ -172,7 +172,7 @@ public class MetricsFilterTest {
         Invocation invocation = new RpcInvocation("timeoutException", DemoService.class.getName(), "", null, null);
         RpcContext.getServiceContext().setRemoteAddress(NetUtils.getLocalHost(), port).setLocalAddress(NetUtils.getLocalHost(), 2345);
         URL url = getUrl().addParameter(SIDE_KEY, CONSUMER_SIDE)
-                .addParameter(TIMEOUT_KEY, 300);
+            .addParameter(TIMEOUT_KEY, 300);
         Invoker<DemoService> invoker = invokerFunction.apply(url);
         onInvokerThrows(invoker);
         for (int i = 0; i < 10; i++) {
@@ -204,10 +204,10 @@ public class MetricsFilterTest {
         Invocation invocation = new RpcInvocation("sayName", DemoService.class.getName(), "", new Class<?>[0], new Object[0]);
         RpcContext.getServiceContext().setRemoteAddress(NetUtils.getLocalHost(), port).setLocalAddress(NetUtils.getLocalHost(), 2345);
         URL url = getUrl().addParameter(SIDE_KEY, PROVIDER)
-                .addParameter(TIMEOUT_KEY, 300);
+            .addParameter(TIMEOUT_KEY, 300);
         Invoker<DemoService> invoker = invokerFunction.apply(url);
         AppResponse response = AppResponseBuilder.create()
-                .build();
+            .build();
         onInvokeReturns(invoker, response);
         for (int i = 0; i < 100; i++) {
             metricsFilter.invoke(invoker, invocation);
@@ -233,7 +233,7 @@ public class MetricsFilterTest {
         Invocation invocation = new RpcInvocation("sayName", DemoService.class.getName(), "", new Class<?>[0], new Object[0]);
         RpcContext.getServiceContext().setRemoteAddress(NetUtils.getLocalHost(), port).setLocalAddress(NetUtils.getLocalHost(), 2345);
         URL url = getUrl().addParameter(SIDE_KEY, PROVIDER)
-                .addParameter(TIMEOUT_KEY, 300);
+            .addParameter(TIMEOUT_KEY, 300);
         Invoker<DemoService> serviceInvoker = invokerFunction.apply(url);
         Invoker<DemoService> timeoutInvoker = invokerFunction.apply(url);
         AppResponse response = AppResponseBuilder.create().build();
@@ -248,7 +248,7 @@ public class MetricsFilterTest {
             }
         }
         Protocol protocol = new DubboProtocol();
-        // using host name might cause connection failure because multiple addresses might be configured to the same name!  
+        // using host name might cause connection failure because multiple addresses might be configured to the same name!
         url = URL.valueOf("dubbo://" + NetUtils.getLocalHost() + ":" + port + "/" + MetricsService.class.getName());
         Invoker<MetricsService> invoker = protocol.refer(MetricsService.class, url);
         invocation = new RpcInvocation("getMetricsByGroup", DemoService.class.getName(), "", new Class<?>[]{String.class}, new Object[]{DUBBO_GROUP});
@@ -258,6 +258,7 @@ public class MetricsFilterTest {
             // ignore
         }
         String resStr = invoker.invoke(invocation).getValue().toString();
+        // MetricObject do not have setter, should use gson to parse
         List<MetricObject> metricObjectList = new Gson().fromJson(resStr, new TypeToken<List<MetricObject>>() {
         }.getType());
         Map<String, Object> metricMap = new HashMap<>();
@@ -284,7 +285,7 @@ public class MetricsFilterTest {
         Invocation echoInvocation = new RpcInvocation("echo", DemoService.class.getName(), "", new Class<?>[]{Integer.class}, new Integer[]{1});
         RpcContext.getServiceContext().setRemoteAddress(NetUtils.getLocalHost(), port).setLocalAddress(NetUtils.getLocalHost(), 2345);
         URL url = getUrl().addParameter(SIDE_KEY, PROVIDER)
-                .addParameter(TIMEOUT_KEY, 300);
+            .addParameter(TIMEOUT_KEY, 300);
         Invoker<DemoService> serviceInvoker = invokerFunction.apply(url);
         Invoker<DemoService> timeoutInvoker = invokerFunction.apply(url);
         AppResponse response = AppResponseBuilder.create().build();
@@ -333,23 +334,23 @@ public class MetricsFilterTest {
         }
 
         Assertions.assertEquals(50.0,
-                methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void sayName()").get("success_bucket_count"));
+            methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void sayName()").get("success_bucket_count"));
         Assertions.assertEquals(50.0,
-                methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void echo(Integer)").get("success_bucket_count"));
+            methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void echo(Integer)").get("success_bucket_count"));
 
         Assertions.assertEquals(50.0,
-                methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void sayName()").get("timeoutError_bucket_count"));
+            methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void sayName()").get("timeoutError_bucket_count"));
         Assertions.assertEquals(50.0,
-                methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void echo(Integer)").get("timeoutError_bucket_count"));
+            methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void echo(Integer)").get("timeoutError_bucket_count"));
 
         Assertions.assertEquals(100.0 / 15,
-                methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void sayName()").get("qps"));
+            methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void sayName()").get("qps"));
         Assertions.assertEquals(100.0 / 15,
-                methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void echo(Integer)").get("qps"));
+            methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void echo(Integer)").get("qps"));
 
         Assertions.assertEquals(50.0 / 100.0,
-                methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void sayName()").get("success_rate"));
+            methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void sayName()").get("success_rate"));
         Assertions.assertEquals(50.0 / 100.0,
-                methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void echo(Integer)").get("success_rate"));
+            methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void echo(Integer)").get("success_rate"));
     }
 }
diff --git a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/InvokeTelnet.java b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/InvokeTelnet.java
index 9734cf52d0..6ac889ed80 100644
--- a/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/InvokeTelnet.java
+++ b/dubbo-plugin/dubbo-qos/src/main/java/org/apache/dubbo/qos/command/impl/InvokeTelnet.java
@@ -18,6 +18,7 @@ package org.apache.dubbo.qos.command.impl;
 
 import org.apache.dubbo.common.utils.ArrayUtils;
 import org.apache.dubbo.common.utils.CollectionUtils;
+import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.common.utils.ReflectUtils;
 import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.qos.command.BaseCommand;
@@ -28,7 +29,6 @@ import org.apache.dubbo.rpc.model.FrameworkModel;
 import org.apache.dubbo.rpc.model.MethodDescriptor;
 import org.apache.dubbo.rpc.model.ProviderModel;
 
-import com.alibaba.fastjson.JSON;
 import io.netty.channel.Channel;
 import io.netty.util.AttributeKey;
 
@@ -88,7 +88,7 @@ public class InvokeTelnet implements BaseCommand {
 
         List<Object> list;
         try {
-            list = JSON.parseArray("[" + param + "]", Object.class);
+            list = JsonUtils.getJson().toJavaList("[" + param + "]", Object.class);
         } catch (Throwable t) {
             return "Invalid json argument, cause: " + t.getMessage();
         }
@@ -156,7 +156,7 @@ public class InvokeTelnet implements BaseCommand {
             }
             long end = System.currentTimeMillis();
             buf.append("\r\nresult: ");
-            buf.append(JSON.toJSONString(result.recreate()));
+            buf.append(JsonUtils.getJson().toJson(result.recreate()));
             buf.append("\r\nelapsed: ");
             buf.append(end - start);
             buf.append(" ms.");
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/DefaultServiceInstance.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/DefaultServiceInstance.java
index 66609278d1..074811beed 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/DefaultServiceInstance.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/DefaultServiceInstance.java
@@ -16,11 +16,10 @@
  */
 package org.apache.dubbo.registry.client;
 
+import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.metadata.MetadataInfo;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 
-import com.alibaba.fastjson.JSON;
-
 import java.beans.Transient;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -235,7 +234,7 @@ public class DefaultServiceInstance implements ServiceInstance {
 
     public List<Endpoint> getEndpoints() {
         if (endpoints == null) {
-            endpoints = new LinkedList<>(JSON.parseArray(metadata.get(ENDPOINTS), Endpoint.class));
+            endpoints = new LinkedList<>(JsonUtils.getJson().toJavaList(metadata.get(ENDPOINTS), Endpoint.class));
         }
         return endpoints;
     }
@@ -302,8 +301,8 @@ public class DefaultServiceInstance implements ServiceInstance {
         }
         DefaultServiceInstance that = (DefaultServiceInstance) o;
         boolean equals = Objects.equals(getServiceName(), that.getServiceName()) &&
-                Objects.equals(getHost(), that.getHost()) &&
-                Objects.equals(getPort(), that.getPort());
+            Objects.equals(getHost(), that.getHost()) &&
+            Objects.equals(getPort(), that.getPort());
         for (Map.Entry<String, String> entry : this.getMetadata().entrySet()) {
             if (entry.getKey().equals(EXPORTED_SERVICES_REVISION_PROPERTY_NAME)) {
                 continue;
@@ -337,13 +336,13 @@ public class DefaultServiceInstance implements ServiceInstance {
 
     public String toFullString() {
         return "DefaultServiceInstance{" +
-                "serviceName='" + serviceName + '\'' +
-                ", host='" + host + '\'' +
-                ", port=" + port +
-                ", enabled=" + enabled +
-                ", healthy=" + healthy +
-                ", metadata=" + metadata +
-                '}';
+            "serviceName='" + serviceName + '\'' +
+            ", host='" + host + '\'' +
+            ", port=" + port +
+            ", enabled=" + enabled +
+            ", healthy=" + healthy +
+            ", metadata=" + metadata +
+            '}';
     }
 
     public static class Endpoint {
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java
index 6520edb62a..702e63666e 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/ServiceInstanceMetadataUtils.java
@@ -20,6 +20,7 @@ import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.extension.ExtensionLoader;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.metadata.MetadataService;
 import org.apache.dubbo.registry.client.DefaultServiceInstance;
@@ -30,8 +31,6 @@ import org.apache.dubbo.registry.client.ServiceInstanceCustomizer;
 import org.apache.dubbo.registry.support.RegistryManager;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 
-import com.google.gson.Gson;
-
 import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.List;
@@ -90,8 +89,6 @@ public class ServiceInstanceMetadataUtils {
 
     public static final String METADATA_CLUSTER_PROPERTY_NAME = "dubbo.metadata.cluster";
 
-    public static final Gson gson = new Gson();
-
     public static String getMetadataServiceParameter(URL url) {
         if (url == null) {
             return "";
@@ -103,7 +100,7 @@ public class ServiceInstanceMetadataUtils {
             return null;
         }
 
-        return gson.toJson(params);
+        return JsonUtils.getJson().toJson(params);
     }
 
     private static Map<String, String> getParams(URL providerURL) {
@@ -137,6 +134,7 @@ public class ServiceInstanceMetadataUtils {
 
     /**
      * Get the metadata storage type specified by the peer instance.
+     *
      * @return storage type, remote or local
      */
     public static String getMetadataStorageType(ServiceInstance serviceInstance) {
@@ -172,7 +170,7 @@ public class ServiceInstanceMetadataUtils {
             endpoints.add(endpoint);
         });
 
-        metadata.put(ENDPOINTS, gson.toJson(endpoints));
+        metadata.put(ENDPOINTS, JsonUtils.getJson().toJson(endpoints));
     }
 
     /**
@@ -221,7 +219,7 @@ public class ServiceInstanceMetadataUtils {
 
     public static void customizeInstance(ServiceInstance instance, ApplicationModel applicationModel) {
         ExtensionLoader<ServiceInstanceCustomizer> loader =
-                instance.getOrDefaultApplicationModel().getExtensionLoader(ServiceInstanceCustomizer.class);
+            instance.getOrDefaultApplicationModel().getExtensionLoader(ServiceInstanceCustomizer.class);
         // FIXME, sort customizer before apply
         loader.getSupportedExtensionInstances().forEach(customizer -> {
             // customize
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/SpringCloudMetadataServiceURLBuilder.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/SpringCloudMetadataServiceURLBuilder.java
index f3ff0e842d..1ffa4445f1 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/SpringCloudMetadataServiceURLBuilder.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/SpringCloudMetadataServiceURLBuilder.java
@@ -17,11 +17,10 @@
 package org.apache.dubbo.registry.client.metadata;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.registry.client.ServiceInstance;
 
-import com.alibaba.fastjson.JSON;
-
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -45,7 +44,7 @@ public class SpringCloudMetadataServiceURLBuilder implements MetadataServiceURLB
         if (StringUtils.isBlank(dubboUrlsForJson)) {
             return Collections.emptyList();
         }
-        List<String> urlStrings = JSON.parseArray(dubboUrlsForJson, String.class);
+        List<String> urlStrings = JsonUtils.getJson().toJavaList(dubboUrlsForJson, String.class);
         return urlStrings.stream().map(URL::valueOf).collect(Collectors.toList());
     }
 }
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/StandardMetadataServiceURLBuilder.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/StandardMetadataServiceURLBuilder.java
index 988e5dd23c..0094b0a2bd 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/StandardMetadataServiceURLBuilder.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/StandardMetadataServiceURLBuilder.java
@@ -21,6 +21,7 @@ import org.apache.dubbo.common.URLBuilder;
 import org.apache.dubbo.common.config.ConfigurationUtils;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.metadata.MetadataService;
 import org.apache.dubbo.registry.client.ServiceInstance;
 import org.apache.dubbo.remoting.Constants;
@@ -158,6 +159,6 @@ public class StandardMetadataServiceURLBuilder implements MetadataServiceURLBuil
     private Map<String, String> getMetadataServiceURLsParams(ServiceInstance serviceInstance) {
         Map<String, String> metadata = serviceInstance.getMetadata();
         String param = metadata.get(METADATA_SERVICE_URL_PARAMS_PROPERTY_NAME);
-        return isBlank(param) ? emptyMap() : (Map) ServiceInstanceMetadataUtils.gson.fromJson(param,Map.class);
+        return isBlank(param) ? emptyMap() : (Map) JsonUtils.getJson().toJavaObject(param, Map.class);
     }
 }
diff --git a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/store/MetaCacheManager.java b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/store/MetaCacheManager.java
index b56e8d7b56..f060d49fff 100644
--- a/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/store/MetaCacheManager.java
+++ b/dubbo-registry/dubbo-registry-api/src/main/java/org/apache/dubbo/registry/client/metadata/store/MetaCacheManager.java
@@ -66,7 +66,7 @@ public class MetaCacheManager extends AbstractCacheManager<MetadataInfo> {
 
     @Override
     protected MetadataInfo toValueType(String value) {
-        return JsonUtils.getGson().fromJson(value, MetadataInfo.class);
+        return JsonUtils.getJson().toJavaObject(value, MetadataInfo.class);
     }
 
     @Override
diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/event/listener/ServiceInstancesChangedListenerTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/event/listener/ServiceInstancesChangedListenerTest.java
index c4a06f2131..b8c69614c1 100644
--- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/event/listener/ServiceInstancesChangedListenerTest.java
+++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/event/listener/ServiceInstancesChangedListenerTest.java
@@ -17,6 +17,7 @@
 package org.apache.dubbo.registry.client.event.listener;
 
 import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.common.utils.LRUCache;
 import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.metadata.MetadataInfo;
@@ -31,7 +32,6 @@ import org.apache.dubbo.registry.client.metadata.store.MetaCacheManager;
 import org.apache.dubbo.registry.client.support.MockServiceDiscovery;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 
-import com.google.gson.Gson;
 import org.hamcrest.Matchers;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.AfterEach;
@@ -75,7 +75,6 @@ import static org.mockito.Mockito.when;
  */
 @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
 public class ServiceInstancesChangedListenerTest {
-    private static Gson gson = new Gson();
 
     static List<ServiceInstance> app1Instances;
     static List<ServiceInstance> app2Instances;
@@ -169,11 +168,11 @@ public class ServiceInstancesChangedListenerTest {
         app1InstancesWithNoRevision = buildInstances(urlsWithoutRevision);
         app1InstancesMultipleProtocols = buildInstances(urlsMultipleProtocols);
 
-        metadataInfo_111 = gson.fromJson(metadata_111, MetadataInfo.class);
-        metadataInfo_222 = gson.fromJson(metadata_222, MetadataInfo.class);
-        metadataInfo_333 = gson.fromJson(metadata_333, MetadataInfo.class);
-        metadataInfo_444 = gson.fromJson(metadata_444, MetadataInfo.class);
-        metadataInfo_555_tri = gson.fromJson(metadata_555_triple, MetadataInfo.class);
+        metadataInfo_111 = JsonUtils.getJson().toJavaObject(metadata_111, MetadataInfo.class);
+        metadataInfo_222 = JsonUtils.getJson().toJavaObject(metadata_222, MetadataInfo.class);
+        metadataInfo_333 = JsonUtils.getJson().toJavaObject(metadata_333, MetadataInfo.class);
+        metadataInfo_444 = JsonUtils.getJson().toJavaObject(metadata_444, MetadataInfo.class);
+        metadataInfo_555_tri = JsonUtils.getJson().toJavaObject(metadata_555_triple, MetadataInfo.class);
 
         serviceDiscovery = Mockito.mock(ServiceDiscovery.class);
         when(serviceDiscovery.getUrl()).thenReturn(registryURL);
diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/ProtocolPortsMetadataCustomizerTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/ProtocolPortsMetadataCustomizerTest.java
index 166df22532..f0ba7cb82f 100644
--- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/ProtocolPortsMetadataCustomizerTest.java
+++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/ProtocolPortsMetadataCustomizerTest.java
@@ -18,13 +18,12 @@ package org.apache.dubbo.registry.client.metadata;
 
 import org.apache.dubbo.common.URL;
 import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
+import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.metadata.MetadataInfo;
 import org.apache.dubbo.metadata.MetadataService;
 import org.apache.dubbo.registry.client.DefaultServiceInstance;
 import org.apache.dubbo.rpc.model.ApplicationModel;
 
-import com.google.gson.Gson;
-import com.google.gson.reflect.TypeToken;
 import org.hamcrest.MatcherAssert;
 import org.junit.jupiter.api.AfterAll;
 import org.junit.jupiter.api.AfterEach;
@@ -43,7 +42,6 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 
 public class ProtocolPortsMetadataCustomizerTest {
-    private static final Gson gson = new Gson();
 
     public DefaultServiceInstance instance;
     private MetadataService mockedMetadataService;
@@ -87,7 +85,7 @@ public class ProtocolPortsMetadataCustomizerTest {
         customizer.customize(instance, ApplicationModel.defaultModel());
         String endpoints = instance.getMetadata().get(ENDPOINTS);
         assertNotNull(endpoints);
-        List<DefaultServiceInstance.Endpoint> endpointList = gson.fromJson(endpoints, new TypeToken<List<DefaultServiceInstance.Endpoint>>(){}.getType());
+        List<DefaultServiceInstance.Endpoint> endpointList = JsonUtils.getJson().toJavaList(endpoints, DefaultServiceInstance.Endpoint.class);
         assertEquals(2, endpointList.size());
         MatcherAssert.assertThat(endpointList, hasItem(hasProperty("protocol", equalTo("dubbo"))));
         MatcherAssert.assertThat(endpointList, hasItem(hasProperty("port", equalTo(20880))));
diff --git a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/store/MetaCacheManagerTest.java b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/store/MetaCacheManagerTest.java
index 71499ae8e7..daa5ff4264 100644
--- a/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/store/MetaCacheManagerTest.java
+++ b/dubbo-registry/dubbo-registry-api/src/test/java/org/apache/dubbo/registry/client/metadata/store/MetaCacheManagerTest.java
@@ -68,7 +68,7 @@ public class MetaCacheManagerTest {
             assertNull(metadataInfo);
 
             Map<String, MetadataInfo> newMetadatas = new HashMap<>();
-            MetadataInfo metadataInfo2 = JsonUtils.getGson().fromJson("{\"app\":\"demo2\",\"services\":{\"greeting/org.apache.dubbo.registry.service.DemoService2:1.0.0:dubbo\":{\"name\":\"org.apache.dubbo.registry.service.DemoService2\",\"group\":\"greeting\",\"version\":\"1.0.0\",\"protocol\":\"dubbo\",\"path\":\"org.apache.dubbo.registry.service.DemoService2\",\"params\":{\"application\":\"demo-provider2\",\"sayHello.timeout\":\"7000\",\"version\":\"1.0.0\",\"timeout\":\"5000\",\"group [...]
+            MetadataInfo metadataInfo2 = JsonUtils.getJson().toJavaObject("{\"app\":\"demo2\",\"services\":{\"greeting/org.apache.dubbo.registry.service.DemoService2:1.0.0:dubbo\":{\"name\":\"org.apache.dubbo.registry.service.DemoService2\",\"group\":\"greeting\",\"version\":\"1.0.0\",\"protocol\":\"dubbo\",\"path\":\"org.apache.dubbo.registry.service.DemoService2\",\"params\":{\"application\":\"demo-provider2\",\"sayHello.timeout\":\"7000\",\"version\":\"1.0.0\",\"timeout\":\"5000\",\"g [...]
             newMetadatas.put("2", metadataInfo2);
 
             cacheManager.update(newMetadatas);
@@ -87,7 +87,7 @@ public class MetaCacheManagerTest {
     @Test
     public void testCacheDump() {
         System.setProperty("dubbo.meta.cache.fileName", "not-exist.dubbo.cache");
-        MetadataInfo metadataInfo3 = JsonUtils.getGson().fromJson("{\"app\":\"demo3\",\"services\":{\"greeting/org.apache.dubbo.registry.service.DemoService2:1.0.0:dubbo\":{\"name\":\"org.apache.dubbo.registry.service.DemoService2\",\"group\":\"greeting\",\"version\":\"1.0.0\",\"protocol\":\"dubbo\",\"path\":\"org.apache.dubbo.registry.service.DemoService2\",\"params\":{\"application\":\"demo-provider2\",\"sayHello.timeout\":\"7000\",\"version\":\"1.0.0\",\"timeout\":\"5000\",\"group\":\ [...]
+        MetadataInfo metadataInfo3 = JsonUtils.getJson().toJavaObject("{\"app\":\"demo3\",\"services\":{\"greeting/org.apache.dubbo.registry.service.DemoService2:1.0.0:dubbo\":{\"name\":\"org.apache.dubbo.registry.service.DemoService2\",\"group\":\"greeting\",\"version\":\"1.0.0\",\"protocol\":\"dubbo\",\"path\":\"org.apache.dubbo.registry.service.DemoService2\",\"params\":{\"application\":\"demo-provider2\",\"sayHello.timeout\":\"7000\",\"version\":\"1.0.0\",\"timeout\":\"5000\",\"group [...]
         MetaCacheManager cacheManager = new MetaCacheManager();
         try {
             cacheManager.put("3", metadataInfo3);
diff --git a/dubbo-rpc/dubbo-rpc-api/pom.xml b/dubbo-rpc/dubbo-rpc-api/pom.xml
index 4a8fd42b48..e92329b7ed 100644
--- a/dubbo-rpc/dubbo-rpc-api/pom.xml
+++ b/dubbo-rpc/dubbo-rpc-api/pom.xml
@@ -51,10 +51,5 @@
             <scope>test</scope>
         </dependency>
 
-        <dependency>
-            <groupId>com.google.code.gson</groupId>
-            <artifactId>gson</artifactId>
-        </dependency>
-
     </dependencies>
-</project>
\ No newline at end of file
+</project>
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericFilter.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericFilter.java
index 96a9d2473a..a09e285e6c 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericFilter.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/filter/GenericFilter.java
@@ -24,6 +24,7 @@ import org.apache.dubbo.common.constants.CommonConstants;
 import org.apache.dubbo.common.extension.Activate;
 import org.apache.dubbo.common.io.UnsafeByteArrayInputStream;
 import org.apache.dubbo.common.io.UnsafeByteArrayOutputStream;
+import org.apache.dubbo.common.json.GsonUtils;
 import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.common.serialize.Serialization;
@@ -43,10 +44,6 @@ import org.apache.dubbo.rpc.service.GenericException;
 import org.apache.dubbo.rpc.service.GenericService;
 import org.apache.dubbo.rpc.support.ProtocolUtils;
 
-import com.google.gson.Gson;
-import com.google.gson.JsonSyntaxException;
-import com.google.gson.reflect.TypeToken;
-
 import java.io.IOException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Type;
@@ -55,7 +52,6 @@ import java.util.stream.IntStream;
 import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE;
 import static org.apache.dubbo.common.constants.CommonConstants.$INVOKE_ASYNC;
 import static org.apache.dubbo.common.constants.CommonConstants.GENERIC_SERIALIZATION_BEAN;
-import static org.apache.dubbo.common.constants.CommonConstants.GENERIC_SERIALIZATION_GSON;
 import static org.apache.dubbo.common.constants.CommonConstants.GENERIC_SERIALIZATION_NATIVE_JAVA;
 import static org.apache.dubbo.common.constants.CommonConstants.GENERIC_SERIALIZATION_PROTOBUF;
 import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
@@ -67,8 +63,6 @@ import static org.apache.dubbo.rpc.Constants.GENERIC_KEY;
 public class GenericFilter implements Filter, Filter.Listener, ScopeModelAware {
     private final Logger logger = LoggerFactory.getLogger(GenericFilter.class);
 
-    private static final Gson gson = new Gson();
-
     private ApplicationModel applicationModel;
 
     @Override
@@ -79,9 +73,9 @@ public class GenericFilter implements Filter, Filter.Listener, ScopeModelAware {
     @Override
     public Result invoke(Invoker<?> invoker, Invocation inv) throws RpcException {
         if ((inv.getMethodName().equals($INVOKE) || inv.getMethodName().equals($INVOKE_ASYNC))
-                && inv.getArguments() != null
-                && inv.getArguments().length == 3
-                && !GenericService.class.isAssignableFrom(invoker.getInterface())) {
+            && inv.getArguments() != null
+            && inv.getArguments().length == 3
+            && !GenericService.class.isAssignableFrom(invoker.getInterface())) {
             String name = ((String) inv.getArguments()[0]).trim();
             String[] types = (String[]) inv.getArguments()[1];
             Object[] args = (Object[]) inv.getArguments()[2];
@@ -92,13 +86,13 @@ public class GenericFilter implements Filter, Filter.Listener, ScopeModelAware {
                     args = new Object[params.length];
                 }
 
-                if(types == null) {
+                if (types == null) {
                     types = new String[params.length];
                 }
 
                 if (args.length != types.length) {
                     throw new RpcException("GenericFilter#invoke args.length != types.length, please check your "
-                            + "params");
+                        + "params");
                 }
                 String generic = inv.getAttachment(GENERIC_KEY);
 
@@ -107,8 +101,8 @@ public class GenericFilter implements Filter, Filter.Listener, ScopeModelAware {
                 }
 
                 if (StringUtils.isEmpty(generic)
-                        || ProtocolUtils.isDefaultGenericSerialization(generic)
-                        || ProtocolUtils.isGenericReturnRawResult(generic)) {
+                    || ProtocolUtils.isDefaultGenericSerialization(generic)
+                    || ProtocolUtils.isGenericReturnRawResult(generic)) {
                     try {
                         args = PojoUtils.realize(args, params, method.getGenericParameterTypes());
                     } catch (IllegalArgumentException e) {
@@ -120,11 +114,11 @@ public class GenericFilter implements Filter, Filter.Listener, ScopeModelAware {
                     Configuration configuration = ApplicationModel.ofNullable(applicationModel).getModelEnvironment().getConfiguration();
                     if (!configuration.getBoolean(CommonConstants.ENABLE_NATIVE_JAVA_GENERIC_SERIALIZE, false)) {
                         String notice = "Trigger the safety barrier! " +
-                                "Native Java Serializer is not allowed by default." +
-                                "This means currently maybe being attacking by others. " +
-                                "If you are sure this is a mistake, " +
-                                "please set `" + CommonConstants.ENABLE_NATIVE_JAVA_GENERIC_SERIALIZE + "` enable in configuration! " +
-                                "Before doing so, please make sure you have configure JEP290 to prevent serialization attack.";
+                            "Native Java Serializer is not allowed by default." +
+                            "This means currently maybe being attacking by others. " +
+                            "If you are sure this is a mistake, " +
+                            "please set `" + CommonConstants.ENABLE_NATIVE_JAVA_GENERIC_SERIALIZE + "` enable in configuration! " +
+                            "Before doing so, please make sure you have configure JEP290 to prevent serialization attack.";
                         logger.error(notice);
                         throw new RpcException(new IllegalStateException(notice));
                     }
@@ -133,19 +127,19 @@ public class GenericFilter implements Filter, Filter.Listener, ScopeModelAware {
                         if (byte[].class == args[i].getClass()) {
                             try (UnsafeByteArrayInputStream is = new UnsafeByteArrayInputStream((byte[]) args[i])) {
                                 args[i] = applicationModel.getExtensionLoader(Serialization.class)
-                                        .getExtension(GENERIC_SERIALIZATION_NATIVE_JAVA)
-                                        .deserialize(null, is).readObject();
+                                    .getExtension(GENERIC_SERIALIZATION_NATIVE_JAVA)
+                                    .deserialize(null, is).readObject();
                             } catch (Exception e) {
                                 throw new RpcException("Deserialize argument [" + (i + 1) + "] failed.", e);
                             }
                         } else {
                             throw new RpcException(
-                                    "Generic serialization [" +
-                                            GENERIC_SERIALIZATION_NATIVE_JAVA +
-                                            "] only support message type " +
-                                            byte[].class +
-                                            " and your message type is " +
-                                            args[i].getClass());
+                                "Generic serialization [" +
+                                    GENERIC_SERIALIZATION_NATIVE_JAVA +
+                                    "] only support message type " +
+                                    byte[].class +
+                                    " and your message type is " +
+                                    args[i].getClass());
                         }
                     }
                 } else if (ProtocolUtils.isBeanGenericSerialization(generic)) {
@@ -154,33 +148,33 @@ public class GenericFilter implements Filter, Filter.Listener, ScopeModelAware {
                             args[i] = JavaBeanSerializeUtil.deserialize((JavaBeanDescriptor) args[i]);
                         } else {
                             throw new RpcException(
-                                    "Generic serialization [" +
-                                            GENERIC_SERIALIZATION_BEAN +
-                                            "] only support message type " +
-                                            JavaBeanDescriptor.class.getName() +
-                                            " and your message type is " +
-                                            args[i].getClass().getName());
+                                "Generic serialization [" +
+                                    GENERIC_SERIALIZATION_BEAN +
+                                    "] only support message type " +
+                                    JavaBeanDescriptor.class.getName() +
+                                    " and your message type is " +
+                                    args[i].getClass().getName());
                         }
                     }
                 } else if (ProtocolUtils.isProtobufGenericSerialization(generic)) {
                     // as proto3 only accept one protobuf parameter
                     if (args.length == 1 && args[0] instanceof String) {
                         try (UnsafeByteArrayInputStream is =
-                                     new UnsafeByteArrayInputStream(((String) args[0]).getBytes())) {
+                                 new UnsafeByteArrayInputStream(((String) args[0]).getBytes())) {
                             args[0] = applicationModel.getExtensionLoader(Serialization.class)
-                                    .getExtension(GENERIC_SERIALIZATION_PROTOBUF)
-                                    .deserialize(null, is).readObject(method.getParameterTypes()[0]);
+                                .getExtension(GENERIC_SERIALIZATION_PROTOBUF)
+                                .deserialize(null, is).readObject(method.getParameterTypes()[0]);
                         } catch (Exception e) {
                             throw new RpcException("Deserialize argument failed.", e);
                         }
                     } else {
                         throw new RpcException(
-                                "Generic serialization [" +
-                                        GENERIC_SERIALIZATION_PROTOBUF +
-                                        "] only support one " + String.class.getName() +
-                                        " argument and your message size is " +
-                                        args.length + " and type is" +
-                                        args[0].getClass().getName());
+                            "Generic serialization [" +
+                                GENERIC_SERIALIZATION_PROTOBUF +
+                                "] only support one " + String.class.getName() +
+                                " argument and your message size is " +
+                                args.length + " and type is" +
+                                args[0].getClass().getName());
                     }
                 }
 
@@ -203,11 +197,10 @@ public class GenericFilter implements Filter, Filter.Listener, ScopeModelAware {
                 throw new RpcException("When using GSON to deserialize generic dubbo request arguments, the arguments must be of type String");
             }
             String str = args[i].toString();
-            Type type = TypeToken.get(types[i]).getType();
             try {
-                return gson.fromJson(str, type);
-            } catch (JsonSyntaxException ex) {
-                throw new RpcException(String.format("Generic serialization [%s] Json syntax exception thrown when parsing (message:%s type:%s) error:%s", GENERIC_SERIALIZATION_GSON, str, type.toString(), ex.getMessage()));
+                return GsonUtils.fromJson(str, types[i]);
+            } catch (RuntimeException ex) {
+                throw new RpcException(ex.getMessage());
             }
         }).toArray();
     }
@@ -215,9 +208,9 @@ public class GenericFilter implements Filter, Filter.Listener, ScopeModelAware {
     @Override
     public void onResponse(Result appResponse, Invoker<?> invoker, Invocation inv) {
         if ((inv.getMethodName().equals($INVOKE) || inv.getMethodName().equals($INVOKE_ASYNC))
-                && inv.getArguments() != null
-                && inv.getArguments().length == 3
-                && !GenericService.class.isAssignableFrom(invoker.getInterface())) {
+            && inv.getArguments() != null
+            && inv.getArguments().length == 3
+            && !GenericService.class.isAssignableFrom(invoker.getInterface())) {
 
             String generic = inv.getAttachment(GENERIC_KEY);
             if (StringUtils.isBlank(generic)) {
@@ -239,13 +232,13 @@ public class GenericFilter implements Filter, Filter.Listener, ScopeModelAware {
                 try {
                     UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream(512);
                     applicationModel.getExtensionLoader(Serialization.class).getExtension(GENERIC_SERIALIZATION_NATIVE_JAVA)
-                            .serialize(null, os).writeObject(appResponse.getValue());
+                        .serialize(null, os).writeObject(appResponse.getValue());
                     appResponse.setValue(os.toByteArray());
                 } catch (IOException e) {
                     throw new RpcException(
-                            "Generic serialization [" +
-                                    GENERIC_SERIALIZATION_NATIVE_JAVA +
-                                    "] serialize result failed.", e);
+                        "Generic serialization [" +
+                            GENERIC_SERIALIZATION_NATIVE_JAVA +
+                            "] serialize result failed.", e);
                 }
             } else if (ProtocolUtils.isBeanGenericSerialization(generic)) {
                 appResponse.setValue(JavaBeanSerializeUtil.serialize(appResponse.getValue(), JavaBeanAccessor.METHOD));
@@ -253,15 +246,15 @@ public class GenericFilter implements Filter, Filter.Listener, ScopeModelAware {
                 try {
                     UnsafeByteArrayOutputStream os = new UnsafeByteArrayOutputStream(512);
                     applicationModel.getExtensionLoader(Serialization.class)
-                            .getExtension(GENERIC_SERIALIZATION_PROTOBUF)
-                            .serialize(null, os).writeObject(appResponse.getValue());
+                        .getExtension(GENERIC_SERIALIZATION_PROTOBUF)
+                        .serialize(null, os).writeObject(appResponse.getValue());
                     appResponse.setValue(os.toString());
                 } catch (IOException e) {
                     throw new RpcException("Generic serialization [" +
-                            GENERIC_SERIALIZATION_PROTOBUF +
-                            "] serialize result failed.", e);
+                        GENERIC_SERIALIZATION_PROTOBUF +
+                        "] serialize result failed.", e);
                 }
-            } else if(ProtocolUtils.isGenericReturnRawResult(generic)) {
+            } else if (ProtocolUtils.isGenericReturnRawResult(generic)) {
                 return;
             } else {
                 appResponse.setValue(PojoUtils.generalize(appResponse.getValue()));
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/AccessLogData.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/AccessLogData.java
index 33bf46714e..482932daf4 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/AccessLogData.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/AccessLogData.java
@@ -17,11 +17,12 @@
 package org.apache.dubbo.rpc.support;
 
 
+import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.rpc.Invocation;
 import org.apache.dubbo.rpc.Invoker;
 import org.apache.dubbo.rpc.RpcContext;
-import com.alibaba.fastjson.JSON;
+
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
@@ -34,7 +35,6 @@ import java.util.Map;
  * AccessLogData is a container for log event data. In internally uses map and store each field of log as value. It
  * does not generate any dynamic value e.g. time stamp, local jvm machine host address etc. It does not allow any null
  * or empty key.
- *
  */
 public final class AccessLogData {
 
@@ -192,16 +192,16 @@ public final class AccessLogData {
         StringBuilder sn = new StringBuilder();
 
         sn.append('[')
-                .append(LocalDateTime.ofInstant(getInvocationTime().toInstant(), ZoneId.systemDefault()).format(MESSAGE_DATE_FORMATTER))
-                .append("] ")
-                .append(get(REMOTE_HOST))
-                .append(':')
-                .append(get(REMOTE_PORT))
-                .append(" -> ")
-                .append(get(LOCAL_HOST))
-                .append(':')
-                .append(get(LOCAL_PORT))
-                .append(" - ");
+            .append(LocalDateTime.ofInstant(getInvocationTime().toInstant(), ZoneId.systemDefault()).format(MESSAGE_DATE_FORMATTER))
+            .append("] ")
+            .append(get(REMOTE_HOST))
+            .append(':')
+            .append(get(REMOTE_PORT))
+            .append(" -> ")
+            .append(get(LOCAL_HOST))
+            .append(':')
+            .append(get(LOCAL_PORT))
+            .append(" - ");
 
         String group = get(GROUP) != null ? get(GROUP).toString() : "";
         if (StringUtils.isNotEmpty(group)) {
@@ -234,15 +234,16 @@ public final class AccessLogData {
 
         Object[] args = get(ARGUMENTS) != null ? (Object[]) get(ARGUMENTS) : null;
         if (args != null && args.length > 0) {
-            sn.append(JSON.toJSONString(args));
+            sn.append(JsonUtils.getJson().toJson(args));
         }
 
         return sn.toString();
     }
 
     private Date getInvocationTime() {
-        return (Date)get(INVOCATION_TIME);
+        return (Date) get(INVOCATION_TIME);
     }
+
     /**
      * Return value of key
      *
@@ -262,7 +263,7 @@ public final class AccessLogData {
     private void set(String key, Object value) {
         data.put(key, value);
     }
-    
+
     public void buildAccessLogData(Invoker<?> invoker, Invocation inv) {
         setServiceName(invoker.getInterface().getName());
         setMethodName(inv.getMethodName());
diff --git a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/MockInvoker.java b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/MockInvoker.java
index 57e80f8e1c..6469ba4333 100644
--- a/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/MockInvoker.java
+++ b/dubbo-rpc/dubbo-rpc-api/src/main/java/org/apache/dubbo/rpc/support/MockInvoker.java
@@ -21,6 +21,7 @@ import org.apache.dubbo.common.extension.ExtensionDirector;
 import org.apache.dubbo.common.extension.ExtensionInjector;
 import org.apache.dubbo.common.utils.ArrayUtils;
 import org.apache.dubbo.common.utils.ConfigUtils;
+import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.common.utils.PojoUtils;
 import org.apache.dubbo.common.utils.ReflectUtils;
 import org.apache.dubbo.common.utils.StringUtils;
@@ -32,11 +33,8 @@ import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcException;
 import org.apache.dubbo.rpc.RpcInvocation;
 
-import com.alibaba.fastjson.JSON;
-
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Type;
-import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -76,16 +74,16 @@ final public class MockInvoker<T> implements Invoker<T> {
         } else if ("false".equals(mock)) {
             value = false;
         } else if (mock.length() >= 2 && (mock.startsWith("\"") && mock.endsWith("\"")
-                || mock.startsWith("\'") && mock.endsWith("\'"))) {
+            || mock.startsWith("\'") && mock.endsWith("\'"))) {
             value = mock.subSequence(1, mock.length() - 1);
         } else if (returnTypes != null && returnTypes.length > 0 && returnTypes[0] == String.class) {
             value = mock;
         } else if (StringUtils.isNumeric(mock, false)) {
-            value = JSON.parse(mock);
+            value = JsonUtils.getJson().toJavaObject(mock, Object.class);
         } else if (mock.startsWith("{")) {
-            value = JSON.parseObject(mock, Map.class);
+            value = JsonUtils.getJson().toJavaObject(mock, Map.class);
         } else if (mock.startsWith("[")) {
-            value = JSON.parseObject(mock, List.class);
+            value = JsonUtils.getJson().toJavaList(mock, Object.class);
         } else {
             value = mock;
         }
@@ -114,7 +112,7 @@ final public class MockInvoker<T> implements Invoker<T> {
                 return AsyncRpcResult.newDefaultAsyncResult(value, invocation);
             } catch (Exception ew) {
                 throw new RpcException("mock return invoke error. method :" + invocation.getMethodName()
-                        + ", mock:" + mock + ", url: " + url, ew);
+                    + ", mock:" + mock + ", url: " + url, ew);
             }
         } else if (mock.startsWith(THROW_PREFIX)) {
             mock = mock.substring(THROW_PREFIX.length()).trim();
@@ -192,13 +190,13 @@ final public class MockInvoker<T> implements Invoker<T> {
                 }
             }
             throw new IllegalStateException("Did not find mock class or instance "
-                    + mockService
-                    + ", please check if there's mock class or instance implementing interface "
-                    + serviceType.getName(), e);
+                + mockService
+                + ", please check if there's mock class or instance implementing interface "
+                + serviceType.getName(), e);
         }
         if (mockClass == null || !serviceType.isAssignableFrom(mockClass)) {
             throw new IllegalStateException("The mock class " + mockClass.getName() +
-                    " not implement interface " + serviceType.getName());
+                " not implement interface " + serviceType.getName());
         }
 
         try {
diff --git a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/filter/TraceFilter.java b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/filter/TraceFilter.java
index 2ae46bc7f1..3247436179 100644
--- a/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/filter/TraceFilter.java
+++ b/dubbo-rpc/dubbo-rpc-dubbo/src/main/java/org/apache/dubbo/rpc/protocol/dubbo/filter/TraceFilter.java
@@ -22,6 +22,7 @@ import org.apache.dubbo.common.logger.Logger;
 import org.apache.dubbo.common.logger.LoggerFactory;
 import org.apache.dubbo.common.utils.CollectionUtils;
 import org.apache.dubbo.common.utils.ConcurrentHashSet;
+import org.apache.dubbo.common.utils.JsonUtils;
 import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.remoting.Channel;
 import org.apache.dubbo.remoting.Constants;
@@ -32,8 +33,6 @@ import org.apache.dubbo.rpc.Result;
 import org.apache.dubbo.rpc.RpcContext;
 import org.apache.dubbo.rpc.RpcException;
 
-import com.alibaba.fastjson.JSON;
-
 import java.util.ArrayList;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
@@ -103,11 +102,11 @@ public class TraceFilter implements Filter {
                             if (count < max) {
                                 String prompt = channel.getUrl().getParameter(Constants.PROMPT_KEY, Constants.DEFAULT_PROMPT);
                                 channel.send("\r\n" + RpcContext.getServiceContext().getRemoteAddress() + " -> "
-                                        + invoker.getInterface().getName()
-                                        + "." + invocation.getMethodName()
-                                        + "(" + JSON.toJSONString(invocation.getArguments()) + ")" + " -> " + JSON.toJSONString(result.getValue())
-                                        + "\r\nelapsed: " + (end - start) + " ms."
-                                        + "\r\n\r\n" + prompt);
+                                    + invoker.getInterface().getName()
+                                    + "." + invocation.getMethodName()
+                                    + "(" + JsonUtils.getJson().toJson(invocation.getArguments()) + ")" + " -> " + JsonUtils.getJson().toJson(result.getValue())
+                                    + "\r\nelapsed: " + (end - start) + " ms."
+                                    + "\r\n\r\n" + prompt);
                             }
                             if (count >= max - 1) {
                                 channels.remove(channel);