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

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


The following commit(s) were added to refs/heads/3.1 by this push:
     new f0f01c36c3 Fix serializable check & Add test cases (#12054)
f0f01c36c3 is described below

commit f0f01c36c3ae2bd2c620fbace66ea8616df7588e
Author: Albumen Kevin <[email protected]>
AuthorDate: Tue Apr 11 16:58:55 2023 +0800

    Fix serializable check & Add test cases (#12054)
    
    * Add test cases
    
    * Fix uts
    
    * Add fj2 test
    
    * save
    
    * Fix check
    
    * Disable some test cases
    
    * Fix test
---
 .../org/apache/dubbo/common/utils/ClassUtils.java  | 100 ++--
 dubbo-dependencies-bom/pom.xml                     |   2 +-
 .../remoting/exchange/codec/ExchangeCodec.java     |   2 +-
 .../dubbo/remoting/codec/ExchangeCodecTest.java    |   4 +
 .../apache/dubbo/common/serialize/ObjectInput.java |   4 +-
 .../dubbo/common/serialize/ObjectOutput.java       |   4 +-
 .../dubbo-serialization-fastjson2/pom.xml          |   1 -
 .../serialize/fastjson2/FastJson2ObjectInput.java  |  32 +-
 .../src/test/java/com/example/test/TestPojo.java}  |  33 +-
 .../fastjson2/FastJson2SerializationTest.java      | 583 +++++++++++++++++++
 .../fastjson2/TrustedNotSerializable.java}         |  30 +-
 .../common/serialize/fastjson2/TrustedPojo.java}   |  31 +-
 .../common/serialize/fastjson2/TrustedPojo2.java}  |  31 +-
 .../common/serialize/fastjson2/TypeMatchTest.java  | 159 ++++++
 .../serialize/hessian2/Hessian2FactoryManager.java |   7 +
 .../hessian2/Hessian2ScopeModelInitializer.java    |   2 +
 .../hessian2/Hessian2SerializerFactory.java        |   2 +-
 .../java/com/example/test/TestPojo.java}           |  33 +-
 .../hessian2/Hessian2SerializationTest.java        | 615 +++++++++++++++++++++
 .../hessian2/TrustedNotSerializable.java}          |  28 +-
 .../common/serialize/hessian2/TrustedPojo.java}    |  29 +-
 .../common/serialize/hessian2/TrustedPojo2.java}   |  29 +-
 .../common/serialize/hessian2/TypeMatchTest.java   | 162 ++++++
 23 files changed, 1760 insertions(+), 163 deletions(-)

diff --git 
a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassUtils.java 
b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassUtils.java
index a403519318..d07d01f3a5 100644
--- a/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassUtils.java
+++ b/dubbo-common/src/main/java/org/apache/dubbo/common/utils/ClassUtils.java
@@ -74,20 +74,20 @@ public class ClassUtils {
      * @since 2.7.6
      */
     public static final Set<Class<?>> SIMPLE_TYPES = ofSet(
-            Void.class,
-            Boolean.class,
-            Character.class,
-            Byte.class,
-            Short.class,
-            Integer.class,
-            Long.class,
-            Float.class,
-            Double.class,
-            String.class,
-            BigDecimal.class,
-            BigInteger.class,
-            Date.class,
-            Object.class
+        Void.class,
+        Boolean.class,
+        Character.class,
+        Byte.class,
+        Short.class,
+        Integer.class,
+        Long.class,
+        Float.class,
+        Double.class,
+        String.class,
+        BigDecimal.class,
+        BigInteger.class,
+        Date.class,
+        Object.class
     );
     /**
      * Prefix for internal array class names: "[L"
@@ -118,8 +118,8 @@ public class ClassUtils {
         Set<Class<?>> primitiveTypeNames = new HashSet<>(32);
         primitiveTypeNames.addAll(PRIMITIVE_WRAPPER_TYPE_MAP.values());
         primitiveTypeNames.addAll(Arrays
-                .asList(boolean[].class, byte[].class, char[].class, 
double[].class,
-                        float[].class, int[].class, long[].class, 
short[].class));
+            .asList(boolean[].class, byte[].class, char[].class, 
double[].class,
+                float[].class, int[].class, long[].class, short[].class));
         for (Class<?> primitiveTypeName : primitiveTypeNames) {
             PRIMITIVE_TYPE_NAME_MAP.put(primitiveTypeName.getName(), 
primitiveTypeName);
         }
@@ -137,12 +137,12 @@ public class ClassUtils {
     private static final char PACKAGE_SEPARATOR_CHAR = '.';
 
     public static Class<?> forNameWithThreadContextClassLoader(String name)
-            throws ClassNotFoundException {
+        throws ClassNotFoundException {
         return forName(name, Thread.currentThread().getContextClassLoader());
     }
 
     public static Class<?> forNameWithCallerClassLoader(String name, Class<?> 
caller)
-            throws ClassNotFoundException {
+        throws ClassNotFoundException {
         return forName(name, caller.getClassLoader());
     }
 
@@ -224,7 +224,7 @@ public class ClassUtils {
      * @see Class#forName(String, boolean, ClassLoader)
      */
     public static Class<?> forName(String name, ClassLoader classLoader)
-            throws ClassNotFoundException, LinkageError {
+        throws ClassNotFoundException, LinkageError {
 
         Class<?> clazz = resolvePrimitiveClassName(name);
         if (clazz != null) {
@@ -244,7 +244,7 @@ public class ClassUtils {
             String elementClassName = null;
             if (internalArrayMarker == 0) {
                 elementClassName = name
-                        .substring(INTERNAL_ARRAY_PREFIX.length(), 
name.length() - 1);
+                    .substring(INTERNAL_ARRAY_PREFIX.length(), name.length() - 
1);
             } else if (name.startsWith("[")) {
                 elementClassName = name.substring(1);
             }
@@ -354,7 +354,7 @@ public class ClassUtils {
      */
     public static boolean isTypeMatch(Class<?> type, String value) {
         if ((type == boolean.class || type == Boolean.class)
-                && !("true".equals(value) || "false".equals(value))) {
+            && !("true".equals(value) || "false".equals(value))) {
             return false;
         }
         return true;
@@ -408,18 +408,18 @@ public class ClassUtils {
             if (isNotEmpty(interfaces)) {
                 // add current interfaces
                 Arrays.stream(interfaces)
-                        .filter(resolved::add)
-                        .forEach(cls -> {
-                            allInterfaces.add(cls);
-                            waitResolve.add(cls);
-                        });
+                    .filter(resolved::add)
+                    .forEach(cls -> {
+                        allInterfaces.add(cls);
+                        waitResolve.add(cls);
+                    });
             }
 
             // add all super classes to waitResolve
             getAllSuperClasses(clazz)
-                    .stream()
-                    .filter(resolved::add)
-                    .forEach(waitResolve::add);
+                .stream()
+                .filter(resolved::add)
+                .forEach(waitResolve::add);
 
             clazz = waitResolve.poll();
         }
@@ -535,7 +535,7 @@ public class ClassUtils {
         }
         Method[] methods = Arrays.stream(tClass.getMethods())
             .collect(Collectors.toList())
-            .toArray(new Method[] {});
+            .toArray(new Method[]{});
         List<String> mns = new ArrayList<>(); // method names.
         boolean hasMethod = hasMethods(methods);
         if (hasMethod) {
@@ -551,6 +551,44 @@ public class ClassUtils {
         return mns.toArray(new String[0]);
     }
 
+    public static boolean isMatch(Class<?> from, Class<?> to) {
+        if (from == to) {
+            return true;
+        }
+        boolean isMatch;
+        if (from.isPrimitive()) {
+            isMatch = matchPrimitive(from, to);
+        } else if (to.isPrimitive()) {
+            isMatch = matchPrimitive(to, from);
+        } else {
+            isMatch = to.isAssignableFrom(from);
+        }
+        return isMatch;
+    }
+
+    private static boolean matchPrimitive(Class<?> from, Class<?> to) {
+        if (from == boolean.class) {
+            return to == Boolean.class;
+        } else if (from == byte.class) {
+            return  to == Byte.class;
+        } else if (from == char.class) {
+            return  to == Character.class;
+        } else if (from == short.class) {
+            return  to == Short.class;
+        } else if (from == int.class) {
+            return  to == Integer.class;
+        } else if (from == long.class) {
+            return  to == Long.class;
+        } else if (from == float.class) {
+            return  to == Float.class;
+        } else if (from == double.class) {
+            return  to == Double.class;
+        } else if (from == void.class) {
+            return  to == Void.class;
+        }
+        return false;
+    }
+
     /**
      * get method name array.
      *
@@ -562,7 +600,7 @@ public class ClassUtils {
         }
         Method[] methods = Arrays.stream(tClass.getMethods())
             .collect(Collectors.toList())
-            .toArray(new Method[] {});
+            .toArray(new Method[]{});
         List<String> dmns = new ArrayList<>(); // method names.
         boolean hasMethod = hasMethods(methods);
         if (hasMethod) {
diff --git a/dubbo-dependencies-bom/pom.xml b/dubbo-dependencies-bom/pom.xml
index 2ecc954a37..ed88d6d823 100644
--- a/dubbo-dependencies-bom/pom.xml
+++ b/dubbo-dependencies-bom/pom.xml
@@ -100,7 +100,7 @@
         <httpclient_version>4.5.13</httpclient_version>
         <httpcore_version>4.4.6</httpcore_version>
         <fastjson_version>1.2.83</fastjson_version>
-        <fastjson2_version>2.0.23</fastjson2_version>
+        <fastjson2_version>2.0.27</fastjson2_version>
         <zookeeper_version>3.4.14</zookeeper_version>
         <curator_version>4.2.0</curator_version>
         <curator_test_version>2.12.0</curator_test_version>
diff --git 
a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/codec/ExchangeCodec.java
 
b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/codec/ExchangeCodec.java
index 58a2eaeea8..18294aac62 100644
--- 
a/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/codec/ExchangeCodec.java
+++ 
b/dubbo-remoting/dubbo-remoting-api/src/main/java/org/apache/dubbo/remoting/exchange/codec/ExchangeCodec.java
@@ -414,7 +414,7 @@ public class ExchangeCodec extends TelnetCodec {
     }
 
     private void encodeEventData(ObjectOutput out, Object data) throws 
IOException {
-        out.writeEvent(data);
+        out.writeEvent((String) data);
     }
 
     @Deprecated
diff --git 
a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/codec/ExchangeCodecTest.java
 
b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/codec/ExchangeCodecTest.java
index 0951739c82..09e1f6a341 100644
--- 
a/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/codec/ExchangeCodecTest.java
+++ 
b/dubbo-remoting/dubbo-remoting-api/src/test/java/org/apache/dubbo/remoting/codec/ExchangeCodecTest.java
@@ -37,6 +37,7 @@ import org.apache.dubbo.rpc.model.FrameworkModel;
 
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 import org.mockito.Mockito;
 
@@ -261,6 +262,7 @@ class ExchangeCodecTest extends TelnetCodecTest {
     }
 
     @Test
+    @Disabled("Event should not be object.")
     void test_Decode_Return_Request_Event_Object() throws IOException {
         //|10011111|20-stats=ok|id=0|length=0
         byte[] header = new byte[]{MAGIC_HIGH, MAGIC_LOW, (byte) 
(SERIALIZATION_BYTE | (byte) 0xe0), 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
@@ -306,6 +308,7 @@ class ExchangeCodecTest extends TelnetCodecTest {
     }
 
     @Test
+    @Disabled("Event should not be object.")
     void test_Decode_Return_Request_Object() throws IOException {
         //|10011111|20-stats=ok|id=0|length=0
         byte[] header = new byte[]{MAGIC_HIGH, MAGIC_LOW, (byte) 
(SERIALIZATION_BYTE | (byte) 0xe0), 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
@@ -393,6 +396,7 @@ class ExchangeCodecTest extends TelnetCodecTest {
     }
 
     @Test
+    @Disabled("Event should not be object.")
     void test_Encode_Response() throws IOException {
         DefaultFuture future = 
DefaultFuture.newFuture(Mockito.mock(Channel.class), new Request(1001), 100000, 
null);
 
diff --git 
a/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/ObjectInput.java
 
b/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/ObjectInput.java
index 4c3ce7c736..b63438f714 100644
--- 
a/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/ObjectInput.java
+++ 
b/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/ObjectInput.java
@@ -78,8 +78,8 @@ public interface ObjectInput extends DataInput {
         return (Throwable) obj;
     }
 
-    default Object readEvent() throws IOException, ClassNotFoundException {
-        return readObject();
+    default String readEvent() throws IOException, ClassNotFoundException {
+        return readUTF();
     }
 
     default Map<String, Object> readAttachments() throws IOException, 
ClassNotFoundException {
diff --git 
a/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/ObjectOutput.java
 
b/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/ObjectOutput.java
index 997f781ce4..20b189fd5d 100644
--- 
a/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/ObjectOutput.java
+++ 
b/dubbo-serialization/dubbo-serialization-api/src/main/java/org/apache/dubbo/common/serialize/ObjectOutput.java
@@ -45,11 +45,11 @@ public interface ObjectOutput extends DataOutput {
      * restricting the content of headers / attachments to Ascii strings and 
uses ISO_8859_1 to encode them.
      * https://tools.ietf.org/html/rfc7540#section-8.1.2
      */
-    default void writeThrowable(Object obj) throws IOException {
+    default void writeThrowable(Throwable obj) throws IOException {
         writeObject(obj);
     }
 
-    default void writeEvent(Object data) throws IOException {
+    default void writeEvent(String data) throws IOException {
         writeObject(data);
     }
 
diff --git a/dubbo-serialization/dubbo-serialization-fastjson2/pom.xml 
b/dubbo-serialization/dubbo-serialization-fastjson2/pom.xml
index 683e099d83..736bd1fc2c 100644
--- a/dubbo-serialization/dubbo-serialization-fastjson2/pom.xml
+++ b/dubbo-serialization/dubbo-serialization-fastjson2/pom.xml
@@ -45,5 +45,4 @@ limitations under the License.
             <artifactId>fastjson2</artifactId>
         </dependency>
     </dependencies>
-
 </project>
diff --git 
a/dubbo-serialization/dubbo-serialization-fastjson2/src/main/java/org/apache/dubbo/common/serialize/fastjson2/FastJson2ObjectInput.java
 
b/dubbo-serialization/dubbo-serialization-fastjson2/src/main/java/org/apache/dubbo/common/serialize/fastjson2/FastJson2ObjectInput.java
index 10a261e555..6b19a110ee 100644
--- 
a/dubbo-serialization/dubbo-serialization-fastjson2/src/main/java/org/apache/dubbo/common/serialize/fastjson2/FastJson2ObjectInput.java
+++ 
b/dubbo-serialization/dubbo-serialization-fastjson2/src/main/java/org/apache/dubbo/common/serialize/fastjson2/FastJson2ObjectInput.java
@@ -16,15 +16,16 @@
  */
 package org.apache.dubbo.common.serialize.fastjson2;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.Type;
-
 import org.apache.dubbo.common.serialize.ObjectInput;
+import org.apache.dubbo.common.utils.ClassUtils;
 
 import com.alibaba.fastjson2.JSONB;
 import com.alibaba.fastjson2.JSONReader;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Type;
+
 /**
  * FastJson object input implementation
  */
@@ -112,22 +113,28 @@ public class FastJson2ObjectInput implements ObjectInput {
             throw new IllegalArgumentException("deserialize failed. expected 
read length: " + length + " but actual read: " + read);
         }
         Fastjson2SecurityManager.Handler securityFilter = 
fastjson2SecurityManager.getSecurityFilter();
+        T result;
         if (securityFilter.isCheckSerializable()) {
-            return (T) JSONB.parseObject(bytes, Object.class, securityFilter,
+            result = JSONB.parseObject(bytes, cls, securityFilter,
                 JSONReader.Feature.UseDefaultConstructorAsPossible,
                 JSONReader.Feature.ErrorOnNoneSerializable,
+                JSONReader.Feature.IgnoreAutoTypeNotMatch,
                 JSONReader.Feature.UseNativeObject,
                 JSONReader.Feature.FieldBased);
         } else {
-            return (T) JSONB.parseObject(bytes, Object.class, securityFilter,
+            result = JSONB.parseObject(bytes, cls, securityFilter,
                 JSONReader.Feature.UseDefaultConstructorAsPossible,
                 JSONReader.Feature.UseNativeObject,
+                JSONReader.Feature.IgnoreAutoTypeNotMatch,
                 JSONReader.Feature.FieldBased);
         }
+        if (result != null && cls != null && 
!ClassUtils.isMatch(result.getClass(), cls)) {
+            throw new IllegalArgumentException("deserialize failed. expected 
class: " + cls + " but actual class: " + result.getClass());
+        }
+        return result;
     }
 
     @Override
-    @SuppressWarnings("unchecked")
     public <T> T readObject(Class<T> cls, Type type) throws IOException, 
ClassNotFoundException {
         updateClassLoaderIfNeed();
         int length = readLength();
@@ -137,18 +144,25 @@ public class FastJson2ObjectInput implements ObjectInput {
             throw new IllegalArgumentException("deserialize failed. expected 
read length: " + length + " but actual read: " + read);
         }
         Fastjson2SecurityManager.Handler securityFilter = 
fastjson2SecurityManager.getSecurityFilter();
+        T result;
         if (securityFilter.isCheckSerializable()) {
-            return (T) JSONB.parseObject(bytes, Object.class, securityFilter,
+            result = JSONB.parseObject(bytes, cls, securityFilter,
                 JSONReader.Feature.UseDefaultConstructorAsPossible,
                 JSONReader.Feature.ErrorOnNoneSerializable,
+                JSONReader.Feature.IgnoreAutoTypeNotMatch,
                 JSONReader.Feature.UseNativeObject,
                 JSONReader.Feature.FieldBased);
         } else {
-            return (T) JSONB.parseObject(bytes, Object.class, securityFilter,
+            result = JSONB.parseObject(bytes, cls, securityFilter,
                 JSONReader.Feature.UseDefaultConstructorAsPossible,
                 JSONReader.Feature.UseNativeObject,
+                JSONReader.Feature.IgnoreAutoTypeNotMatch,
                 JSONReader.Feature.FieldBased);
         }
+        if (result != null && cls != null && 
!ClassUtils.isMatch(result.getClass(), cls)) {
+            throw new IllegalArgumentException("deserialize failed. expected 
class: " + cls + " but actual class: " + result.getClass());
+        }
+        return result;
     }
 
     private void updateClassLoaderIfNeed() {
diff --git 
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
 
b/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/com/example/test/TestPojo.java
similarity index 53%
copy from 
dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
copy to 
dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/com/example/test/TestPojo.java
index 578850905c..3c2471ba54 100644
--- 
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
+++ 
b/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/com/example/test/TestPojo.java
@@ -14,28 +14,33 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.common.serialize.hessian2;
+package com.example.test;
 
-import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.apache.dubbo.rpc.model.FrameworkModel;
-import org.apache.dubbo.rpc.model.ModuleModel;
-import org.apache.dubbo.rpc.model.ScopeModelInitializer;
+import java.io.Serializable;
+import java.util.Objects;
 
-public class Hessian2ScopeModelInitializer implements ScopeModelInitializer {
-    @Override
-    public void initializeFrameworkModel(FrameworkModel frameworkModel) {
-        ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
-        beanFactory.registerBean(Hessian2FactoryManager.class);
+public class TestPojo implements Serializable {
+    private final String data;
+
+    public TestPojo(String data) {
+        this.data = data;
     }
 
     @Override
-    public void initializeApplicationModel(ApplicationModel applicationModel) {
-
+    public String toString() {
+        throw new IllegalAccessError();
     }
 
     @Override
-    public void initializeModuleModel(ModuleModel moduleModel) {
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        TestPojo testPojo = (TestPojo) o;
+        return Objects.equals(data, testPojo.data);
+    }
 
+    @Override
+    public int hashCode() {
+        return Objects.hash(data);
     }
 }
diff --git 
a/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/FastJson2SerializationTest.java
 
b/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/FastJson2SerializationTest.java
new file mode 100644
index 0000000000..447e3396aa
--- /dev/null
+++ 
b/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/FastJson2SerializationTest.java
@@ -0,0 +1,583 @@
+/*
+ * 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.serialize.fastjson2;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.serialize.ObjectInput;
+import org.apache.dubbo.common.serialize.ObjectOutput;
+import org.apache.dubbo.common.serialize.Serialization;
+import org.apache.dubbo.common.utils.SerializeCheckStatus;
+import org.apache.dubbo.common.utils.SerializeSecurityManager;
+import org.apache.dubbo.rpc.model.FrameworkModel;
+
+import com.example.test.TestPojo;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ThreadLocalRandom;
+
+public class FastJson2SerializationTest {
+
+    @Test
+    void testReadString() throws IOException {
+        FrameworkModel frameworkModel = new FrameworkModel();
+        Serialization serialization = 
frameworkModel.getExtensionLoader(Serialization.class).getExtension("fastjson2");
+        URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+        // write string, read string
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject("hello");
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertEquals("hello", objectInput.readUTF());
+        }
+
+        // write string, read string
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(null);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertNull(objectInput.readUTF());
+        }
+
+        // write date, read failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(new HashMap<>());
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(RuntimeException.class, 
objectInput::readUTF);
+        }
+
+        // write pojo, read failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(new 
TrustedPojo(ThreadLocalRandom.current().nextDouble()));
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertInstanceOf(String.class, objectInput.readUTF());
+        }
+
+        // write map, read failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(new HashMap<>());
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(RuntimeException.class, 
objectInput::readUTF);
+        }
+
+        // write list, read failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(new LinkedList<>());
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertInstanceOf(String.class, objectInput.readUTF());
+        }
+
+        frameworkModel.destroy();
+    }
+
+    @Test
+    void testReadEvent() throws IOException, ClassNotFoundException {
+        FrameworkModel frameworkModel = new FrameworkModel();
+        Serialization serialization = 
frameworkModel.getExtensionLoader(Serialization.class).getExtension("fastjson2");
+        URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+        // write string, read event
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject("hello");
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertEquals("hello", objectInput.readEvent());
+        }
+
+        // write date, read failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(new HashMap<>());
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(RuntimeException.class, 
objectInput::readEvent);
+        }
+
+        // write pojo, read failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(new 
TrustedPojo(ThreadLocalRandom.current().nextDouble()));
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertInstanceOf(String.class, objectInput.readEvent());
+        }
+
+        // write map, read failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(new HashMap<>());
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(RuntimeException.class, 
objectInput::readEvent);
+        }
+
+        // write list, read failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(new LinkedList<>());
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertInstanceOf(String.class, objectInput.readEvent());
+        }
+
+        frameworkModel.destroy();
+    }
+
+    @Test
+    void testReadByte() throws IOException {
+        FrameworkModel frameworkModel = new FrameworkModel();
+        Serialization serialization = 
frameworkModel.getExtensionLoader(Serialization.class).getExtension("fastjson2");
+        URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+        // write byte, read byte
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject((byte) 11);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertEquals((byte) 11, objectInput.readByte());
+        }
+
+        // write date, read failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(new Date());
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(RuntimeException.class, 
objectInput::readByte);
+        }
+
+        // write pojo, read failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(new 
TrustedPojo(ThreadLocalRandom.current().nextDouble()));
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(RuntimeException.class, 
objectInput::readByte);
+        }
+
+        // write map, read failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(new HashMap<>());
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(RuntimeException.class, 
objectInput::readByte);
+        }
+
+        // write list, read failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(new LinkedList<>());
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(RuntimeException.class, 
objectInput::readByte);
+        }
+
+        frameworkModel.destroy();
+    }
+
+    @Test
+    void testReadObject() throws IOException, ClassNotFoundException {
+        FrameworkModel frameworkModel = new FrameworkModel();
+        Serialization serialization = 
frameworkModel.getExtensionLoader(Serialization.class).getExtension("fastjson2");
+        URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+        // write pojo, read pojo
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+            objectOutput.writeObject(trustedPojo);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertEquals(trustedPojo, objectInput.readObject());
+        }
+
+        // write list, read list
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+            LinkedList<TrustedPojo> pojos = new LinkedList<>();
+            pojos.add(trustedPojo);
+
+            objectOutput.writeObject(pojos);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertEquals(pojos, objectInput.readObject());
+        }
+
+        // write pojo, read pojo
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+            objectOutput.writeObject(trustedPojo);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertEquals(trustedPojo, 
objectInput.readObject(TrustedPojo.class));
+        }
+
+        // write list, read list
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+            LinkedList<TrustedPojo> pojos = new LinkedList<>();
+            pojos.add(trustedPojo);
+
+            objectOutput.writeObject(pojos);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertEquals(pojos, objectInput.readObject(List.class));
+        }
+
+        // write list, read list
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+            LinkedList<TrustedPojo> pojos = new LinkedList<>();
+            pojos.add(trustedPojo);
+
+            objectOutput.writeObject(pojos);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertEquals(pojos, 
objectInput.readObject(LinkedList.class));
+        }
+
+        frameworkModel.destroy();
+    }
+
+    @Test
+    void testReadObjectNotMatched() throws IOException, ClassNotFoundException 
{
+        FrameworkModel frameworkModel = new FrameworkModel();
+        Serialization serialization = 
frameworkModel.getExtensionLoader(Serialization.class).getExtension("fastjson2");
+        
frameworkModel.getBeanFactory().getBean(SerializeSecurityManager.class).setCheckStatus(SerializeCheckStatus.STRICT);
+        URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+        // write pojo, read list failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+            objectOutput.writeObject(trustedPojo);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(RuntimeException.class, () -> 
objectInput.readObject(List.class));
+        }
+
+        // write pojo, read list failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+            objectOutput.writeObject(trustedPojo);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(RuntimeException.class, () -> 
objectInput.readObject(LinkedList.class));
+        }
+
+        // write pojo, read string failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+            objectOutput.writeObject(trustedPojo);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertInstanceOf(String.class, 
objectInput.readObject(String.class));
+        }
+
+        // write pojo, read other failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+            objectOutput.writeObject(trustedPojo);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(RuntimeException.class, () -> 
objectInput.readObject(TrustedNotSerializable.class));
+        }
+
+        // write pojo, read same field failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+            objectOutput.writeObject(trustedPojo);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(RuntimeException.class, () -> 
objectInput.readObject(TrustedPojo2.class));
+        }
+
+        // write pojo, read map failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+            objectOutput.writeObject(trustedPojo);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(RuntimeException.class, () -> 
objectInput.readObject(Map.class));
+        }
+
+        // write list, read pojo failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+            LinkedList<TrustedPojo> pojos = new LinkedList<>();
+            pojos.add(trustedPojo);
+
+            objectOutput.writeObject(pojos);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(RuntimeException.class, () -> 
objectInput.readObject(TrustedPojo.class));
+        }
+
+        // write list, read map failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+            LinkedList<TrustedPojo> pojos = new LinkedList<>();
+            pojos.add(trustedPojo);
+
+            objectOutput.writeObject(pojos);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(RuntimeException.class, () -> 
objectInput.readObject(Map.class));
+        }
+
+        frameworkModel.destroy();
+    }
+
+    @Test
+    void testLimit1() throws IOException, ClassNotFoundException {
+        FrameworkModel frameworkModel = new FrameworkModel();
+        Serialization serialization = 
frameworkModel.getExtensionLoader(Serialization.class).getExtension("fastjson2");
+        URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+        // write trusted, read trusted
+        TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        ObjectOutput objectOutput = serialization.serialize(url, outputStream);
+        objectOutput.writeObject(trustedPojo);
+        objectOutput.flushBuffer();
+
+        byte[] bytes = outputStream.toByteArray();
+        ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+        ObjectInput objectInput = serialization.deserialize(url, inputStream);
+        Assertions.assertEquals(trustedPojo, objectInput.readObject());
+
+        frameworkModel.destroy();
+    }
+
+    @Test
+    void testLimit4() throws IOException, ClassNotFoundException {
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        // write force untrusted, read failed
+
+        {
+            FrameworkModel frameworkModel = new FrameworkModel();
+            Serialization serialization = 
frameworkModel.getExtensionLoader(Serialization.class).getExtension("fastjson2");
+            URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+            TestPojo trustedPojo = new TestPojo("12345");
+
+            
frameworkModel.getBeanFactory().getBean(SerializeSecurityManager.class).addToAllowed(trustedPojo.getClass().getName());
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(trustedPojo);
+            objectOutput.flushBuffer();
+
+            frameworkModel.destroy();
+        }
+
+        {
+            FrameworkModel frameworkModel = new FrameworkModel();
+            Serialization serialization = 
frameworkModel.getExtensionLoader(Serialization.class).getExtension("fastjson2");
+            URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+            byte[] bytes = outputStream.toByteArray();
+            
frameworkModel.getBeanFactory().getBean(SerializeSecurityManager.class).setCheckStatus(SerializeCheckStatus.STRICT);
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(RuntimeException.class, 
objectInput::readObject);
+            frameworkModel.destroy();
+        }
+    }
+
+    @Test
+    void testLimit5() throws IOException, ClassNotFoundException {
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        // write force un-serializable, read failed
+
+        {
+            FrameworkModel frameworkModel = new FrameworkModel();
+            Serialization serialization = 
frameworkModel.getExtensionLoader(Serialization.class).getExtension("fastjson2");
+            URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+            TrustedNotSerializable trustedPojo = new 
TrustedNotSerializable(ThreadLocalRandom.current().nextDouble());
+
+            
frameworkModel.getBeanFactory().getBean(SerializeSecurityManager.class).setCheckSerializable(false);
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(trustedPojo);
+            objectOutput.flushBuffer();
+
+            frameworkModel.destroy();
+        }
+
+        {
+            FrameworkModel frameworkModel = new FrameworkModel();
+            Serialization serialization = 
frameworkModel.getExtensionLoader(Serialization.class).getExtension("fastjson2");
+            URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+            byte[] bytes = outputStream.toByteArray();
+            
frameworkModel.getBeanFactory().getBean(SerializeSecurityManager.class).setCheckStatus(SerializeCheckStatus.STRICT);
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(RuntimeException.class, 
objectInput::readObject);
+            frameworkModel.destroy();
+        }
+    }
+}
diff --git 
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
 
b/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/TrustedNotSerializable.java
similarity index 52%
copy from 
dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
copy to 
dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/TrustedNotSerializable.java
index 578850905c..3172e870fe 100644
--- 
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
+++ 
b/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/TrustedNotSerializable.java
@@ -14,28 +14,28 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.common.serialize.hessian2;
+package org.apache.dubbo.common.serialize.fastjson2;
 
-import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.apache.dubbo.rpc.model.FrameworkModel;
-import org.apache.dubbo.rpc.model.ModuleModel;
-import org.apache.dubbo.rpc.model.ScopeModelInitializer;
+import java.util.Objects;
 
-public class Hessian2ScopeModelInitializer implements ScopeModelInitializer {
-    @Override
-    public void initializeFrameworkModel(FrameworkModel frameworkModel) {
-        ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
-        beanFactory.registerBean(Hessian2FactoryManager.class);
-    }
+public class TrustedNotSerializable {
 
-    @Override
-    public void initializeApplicationModel(ApplicationModel applicationModel) {
+    private final double data;
 
+    public TrustedNotSerializable(double data) {
+        this.data = data;
     }
 
     @Override
-    public void initializeModuleModel(ModuleModel moduleModel) {
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        TrustedNotSerializable that = (TrustedNotSerializable) o;
+        return Objects.equals(data, that.data);
+    }
 
+    @Override
+    public int hashCode() {
+        return Objects.hash(data);
     }
 }
diff --git 
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
 
b/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/TrustedPojo.java
similarity index 52%
copy from 
dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
copy to 
dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/TrustedPojo.java
index 578850905c..ae4f3db440 100644
--- 
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
+++ 
b/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/TrustedPojo.java
@@ -14,28 +14,29 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.common.serialize.hessian2;
+package org.apache.dubbo.common.serialize.fastjson2;
 
-import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.apache.dubbo.rpc.model.FrameworkModel;
-import org.apache.dubbo.rpc.model.ModuleModel;
-import org.apache.dubbo.rpc.model.ScopeModelInitializer;
+import java.io.Serializable;
+import java.util.Objects;
 
-public class Hessian2ScopeModelInitializer implements ScopeModelInitializer {
-    @Override
-    public void initializeFrameworkModel(FrameworkModel frameworkModel) {
-        ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
-        beanFactory.registerBean(Hessian2FactoryManager.class);
-    }
+public class TrustedPojo implements Serializable {
 
-    @Override
-    public void initializeApplicationModel(ApplicationModel applicationModel) {
+    private final double data;
 
+    public TrustedPojo(double data) {
+        this.data = data;
     }
 
     @Override
-    public void initializeModuleModel(ModuleModel moduleModel) {
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        TrustedPojo that = (TrustedPojo) o;
+        return Objects.equals(data, that.data);
+    }
 
+    @Override
+    public int hashCode() {
+        return Objects.hash(data);
     }
 }
diff --git 
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
 
b/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/TrustedPojo2.java
similarity index 52%
copy from 
dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
copy to 
dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/TrustedPojo2.java
index 578850905c..3aaa74684e 100644
--- 
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
+++ 
b/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/TrustedPojo2.java
@@ -14,28 +14,29 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.common.serialize.hessian2;
+package org.apache.dubbo.common.serialize.fastjson2;
 
-import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.apache.dubbo.rpc.model.FrameworkModel;
-import org.apache.dubbo.rpc.model.ModuleModel;
-import org.apache.dubbo.rpc.model.ScopeModelInitializer;
+import java.io.Serializable;
+import java.util.Objects;
 
-public class Hessian2ScopeModelInitializer implements ScopeModelInitializer {
-    @Override
-    public void initializeFrameworkModel(FrameworkModel frameworkModel) {
-        ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
-        beanFactory.registerBean(Hessian2FactoryManager.class);
-    }
+public class TrustedPojo2 implements Serializable {
 
-    @Override
-    public void initializeApplicationModel(ApplicationModel applicationModel) {
+    private final double data;
 
+    public TrustedPojo2(double data) {
+        this.data = data;
     }
 
     @Override
-    public void initializeModuleModel(ModuleModel moduleModel) {
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        TrustedPojo2 that = (TrustedPojo2) o;
+        return Objects.equals(data, that.data);
+    }
 
+    @Override
+    public int hashCode() {
+        return Objects.hash(data);
     }
 }
diff --git 
a/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/TypeMatchTest.java
 
b/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/TypeMatchTest.java
new file mode 100644
index 0000000000..974f685a2a
--- /dev/null
+++ 
b/dubbo-serialization/dubbo-serialization-fastjson2/src/test/java/org/apache/dubbo/common/serialize/fastjson2/TypeMatchTest.java
@@ -0,0 +1,159 @@
+/*
+ * 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.serialize.fastjson2;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.serialize.DataInput;
+import org.apache.dubbo.common.serialize.DataOutput;
+import org.apache.dubbo.common.serialize.ObjectInput;
+import org.apache.dubbo.common.serialize.ObjectOutput;
+import org.apache.dubbo.common.serialize.Serialization;
+import org.apache.dubbo.rpc.model.FrameworkModel;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.ArgumentsProvider;
+import org.junit.jupiter.params.provider.ArgumentsSource;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Stream;
+
+class TypeMatchTest {
+    static class DataProvider implements ArgumentsProvider {
+        @Override
+        public Stream<? extends Arguments> provideArguments(ExtensionContext 
extensionContext) throws Exception {
+            List<Object> datas = new LinkedList<>();
+            List<Method> readMethods = new LinkedList<>();
+            List<Method> writeMethods = new LinkedList<>();
+
+            datas.add(true);
+            datas.add(false);
+            datas.add((byte) 123);
+            datas.add((byte) 234);
+            datas.add((short) 12345);
+            datas.add((short) 23456);
+            datas.add(123456);
+            datas.add(234567);
+            datas.add(1234567L);
+            datas.add(2345678L);
+            datas.add(0.123F);
+            datas.add(1.234F);
+            datas.add(0.1234D);
+            datas.add(1.2345D);
+            datas.add("hello");
+            datas.add("world");
+            datas.add("hello".getBytes());
+            datas.add("world".getBytes());
+
+            for (Method method : ObjectInput.class.getMethods()) {
+                if (method.getName().startsWith("read") && 
method.getParameterTypes().length == 0 && 
!method.getReturnType().equals(Object.class)) {
+                    readMethods.add(method);
+                }
+            }
+            for (Method method : DataInput.class.getMethods()) {
+                if (method.getName().startsWith("read") && 
method.getParameterTypes().length == 0 && 
!method.getReturnType().equals(Object.class)) {
+                    readMethods.add(method);
+                }
+            }
+
+            for (Method method : ObjectOutput.class.getMethods()) {
+                if (method.getName().startsWith("write") && 
method.getParameterTypes().length == 1 && 
!method.getParameterTypes()[0].equals(Object.class)) {
+                    writeMethods.add(method);
+                }
+            }
+
+            for (Method method : DataOutput.class.getMethods()) {
+                if (method.getName().startsWith("write") && 
method.getParameterTypes().length == 1 && 
!method.getParameterTypes()[0].equals(Object.class)) {
+                    writeMethods.add(method);
+                }
+            }
+
+            Map<Class<?>, Class<?>> primitiveWrapperTypeMap = new 
HashMap<>(16);
+            primitiveWrapperTypeMap.put(Boolean.class, boolean.class);
+            primitiveWrapperTypeMap.put(Byte.class, byte.class);
+            primitiveWrapperTypeMap.put(Character.class, char.class);
+            primitiveWrapperTypeMap.put(Double.class, double.class);
+            primitiveWrapperTypeMap.put(Float.class, float.class);
+            primitiveWrapperTypeMap.put(Integer.class, int.class);
+            primitiveWrapperTypeMap.put(Long.class, long.class);
+            primitiveWrapperTypeMap.put(Short.class, short.class);
+            primitiveWrapperTypeMap.put(Void.class, void.class);
+
+            List<Arguments> argumentsList = new LinkedList<>();
+            for (Object data : datas) {
+                for (Method input : readMethods) {
+                    for (Method output : writeMethods) {
+                        if 
(output.getParameterTypes()[0].isAssignableFrom(data.getClass())) {
+                            argumentsList.add(Arguments.arguments(data, input, 
output));
+                        }
+                        if 
(primitiveWrapperTypeMap.containsKey(data.getClass()) &&
+                            
output.getParameterTypes()[0].isAssignableFrom(primitiveWrapperTypeMap.get(data.getClass())))
 {
+                            argumentsList.add(Arguments.arguments(data, input, 
output));
+                        }
+                    }
+                }
+            }
+
+            return argumentsList.stream();
+        }
+    }
+
+    @ParameterizedTest
+    @ArgumentsSource(DataProvider.class)
+    void test(Object data, Method input, Method output) throws Exception {
+        FrameworkModel frameworkModel = new FrameworkModel();
+        Serialization serialization = 
frameworkModel.getExtensionLoader(Serialization.class).getExtension("fastjson2");
+        URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        ObjectOutput objectOutput = serialization.serialize(url, outputStream);
+        output.invoke(objectOutput, data);
+        objectOutput.flushBuffer();
+
+        byte[] bytes = outputStream.toByteArray();
+        ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+        ObjectInput objectInput = serialization.deserialize(url, inputStream);
+        if (output.getParameterTypes()[0].equals(input.getReturnType())) {
+            Object result = input.invoke(objectInput);
+            if (data.getClass().isArray()) {
+                Assertions.assertArrayEquals((byte[]) data, (byte[]) result);
+            } else {
+                Assertions.assertEquals(data, result);
+            }
+        } else {
+            try {
+                Object result = input.invoke(objectInput);
+                if (data.getClass().isArray()) {
+                    Assertions.assertNotEquals(data.getClass(), 
result.getClass());
+                } else {
+                    Assertions.assertNotEquals(data, result);
+                }
+            } catch (Exception e) {
+                // ignore
+            }
+        }
+        frameworkModel.destroy();
+    }
+}
diff --git 
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2FactoryManager.java
 
b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2FactoryManager.java
index 512f67115f..60f9dfe2fe 100644
--- 
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2FactoryManager.java
+++ 
b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2FactoryManager.java
@@ -20,6 +20,8 @@ import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
 import org.apache.dubbo.common.utils.DefaultSerializeClassChecker;
+import org.apache.dubbo.common.utils.SerializeCheckStatus;
+import org.apache.dubbo.common.utils.SerializeSecurityManager;
 import org.apache.dubbo.common.utils.StringUtils;
 import org.apache.dubbo.rpc.model.FrameworkModel;
 
@@ -33,9 +35,11 @@ public class Hessian2FactoryManager {
     private volatile SerializerFactory SYSTEM_SERIALIZER_FACTORY;
     private final Map<ClassLoader, SerializerFactory> CL_2_SERIALIZER_FACTORY 
= new ConcurrentHashMap<>();
 
+    private final SerializeSecurityManager serializeSecurityManager;
     private final DefaultSerializeClassChecker defaultSerializeClassChecker;
 
     public Hessian2FactoryManager(FrameworkModel frameworkModel) {
+        serializeSecurityManager = 
frameworkModel.getBeanFactory().getOrRegisterBean(SerializeSecurityManager.class);
         defaultSerializeClassChecker = 
frameworkModel.getBeanFactory().getOrRegisterBean(DefaultSerializeClassChecker.class);
     }
 
@@ -89,14 +93,17 @@ public class Hessian2FactoryManager {
             if (StringUtils.isNotEmpty(allowPattern)) {
                 for (String pattern : allowPattern.split(";")) {
                     serializerFactory.getClassFactory().allow(pattern);
+                    serializeSecurityManager.addToAlwaysAllowed(pattern);
                 }
             }
+            
serializeSecurityManager.setCheckStatus(SerializeCheckStatus.STRICT);
         } else {
             serializerFactory.getClassFactory().setWhitelist(false);
             String denyPattern = System.getProperty(DENY);
             if (StringUtils.isNotEmpty(denyPattern)) {
                 for (String pattern : denyPattern.split(";")) {
                     serializerFactory.getClassFactory().deny(pattern);
+                    serializeSecurityManager.addToDisAllowed(pattern);
                 }
             }
         }
diff --git 
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
 
b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
index 578850905c..a86b39bdb8 100644
--- 
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
+++ 
b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
@@ -27,6 +27,8 @@ public class Hessian2ScopeModelInitializer implements 
ScopeModelInitializer {
     public void initializeFrameworkModel(FrameworkModel frameworkModel) {
         ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
         beanFactory.registerBean(Hessian2FactoryManager.class);
+
+        frameworkModel.addClassLoaderListener(new 
Hessian2ClassLoaderListener());
     }
 
     @Override
diff --git 
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializerFactory.java
 
b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializerFactory.java
index 099c5e9766..0d886b9d39 100644
--- 
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializerFactory.java
+++ 
b/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializerFactory.java
@@ -52,7 +52,7 @@ public class Hessian2SerializerFactory extends 
SerializerFactory {
         }
 
         if (!Serializable.class.isAssignableFrom(cl)
-            && (!isAllowNonSerializable() || 
!defaultSerializeClassChecker.isCheckSerializable())) {
+            && (!isAllowNonSerializable() || 
defaultSerializeClassChecker.isCheckSerializable())) {
             throw new IllegalStateException("Serialized class " + cl.getName() 
+ " must implement java.io.Serializable");
         }
 
diff --git 
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
 
b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/com/example/test/TestPojo.java
similarity index 53%
copy from 
dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
copy to 
dubbo-serialization/dubbo-serialization-hessian2/src/test/java/com/example/test/TestPojo.java
index 578850905c..3c2471ba54 100644
--- 
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
+++ 
b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/com/example/test/TestPojo.java
@@ -14,28 +14,33 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.common.serialize.hessian2;
+package com.example.test;
 
-import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.apache.dubbo.rpc.model.FrameworkModel;
-import org.apache.dubbo.rpc.model.ModuleModel;
-import org.apache.dubbo.rpc.model.ScopeModelInitializer;
+import java.io.Serializable;
+import java.util.Objects;
 
-public class Hessian2ScopeModelInitializer implements ScopeModelInitializer {
-    @Override
-    public void initializeFrameworkModel(FrameworkModel frameworkModel) {
-        ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
-        beanFactory.registerBean(Hessian2FactoryManager.class);
+public class TestPojo implements Serializable {
+    private final String data;
+
+    public TestPojo(String data) {
+        this.data = data;
     }
 
     @Override
-    public void initializeApplicationModel(ApplicationModel applicationModel) {
-
+    public String toString() {
+        throw new IllegalAccessError();
     }
 
     @Override
-    public void initializeModuleModel(ModuleModel moduleModel) {
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        TestPojo testPojo = (TestPojo) o;
+        return Objects.equals(data, testPojo.data);
+    }
 
+    @Override
+    public int hashCode() {
+        return Objects.hash(data);
     }
 }
diff --git 
a/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializationTest.java
 
b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializationTest.java
new file mode 100644
index 0000000000..b43e0a8c80
--- /dev/null
+++ 
b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/Hessian2SerializationTest.java
@@ -0,0 +1,615 @@
+/*
+ * 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.serialize.hessian2;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.serialize.ObjectInput;
+import org.apache.dubbo.common.serialize.ObjectOutput;
+import org.apache.dubbo.common.serialize.Serialization;
+import org.apache.dubbo.common.utils.SerializeCheckStatus;
+import org.apache.dubbo.common.utils.SerializeSecurityManager;
+import org.apache.dubbo.rpc.model.FrameworkModel;
+
+import com.example.test.TestPojo;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ThreadLocalRandom;
+
+class Hessian2SerializationTest {
+    @Test
+    void testReadString() throws IOException {
+        FrameworkModel frameworkModel = new FrameworkModel();
+        Serialization serialization = 
frameworkModel.getExtensionLoader(Serialization.class).getExtension("hessian2");
+        URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+        // write string, read string
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject("hello");
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertEquals("hello", objectInput.readUTF());
+        }
+
+        // write string, read string
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(null);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertNull(objectInput.readUTF());
+        }
+
+        // write date, read failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(new Date());
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(IOException.class, objectInput::readUTF);
+        }
+
+        // write pojo, read failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(new 
TrustedPojo(ThreadLocalRandom.current().nextDouble()));
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(IOException.class, objectInput::readUTF);
+        }
+
+        // write map, read failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(new HashMap<>());
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(IOException.class, objectInput::readUTF);
+        }
+
+        // write list, read failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(new LinkedList<>());
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(IOException.class, objectInput::readUTF);
+        }
+
+        frameworkModel.destroy();
+    }
+
+    @Test
+    void testReadEvent() throws IOException, ClassNotFoundException {
+        FrameworkModel frameworkModel = new FrameworkModel();
+        Serialization serialization = 
frameworkModel.getExtensionLoader(Serialization.class).getExtension("hessian2");
+        URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+        // write string, read event
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject("hello");
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertEquals("hello", objectInput.readEvent());
+        }
+
+        // write date, read failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(new Date());
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(IOException.class, objectInput::readEvent);
+        }
+
+        // write pojo, read failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(new 
TrustedPojo(ThreadLocalRandom.current().nextDouble()));
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(IOException.class, objectInput::readEvent);
+        }
+
+        // write map, read failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(new HashMap<>());
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(IOException.class, objectInput::readEvent);
+        }
+
+        // write list, read failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(new LinkedList<>());
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(IOException.class, objectInput::readEvent);
+        }
+
+        frameworkModel.destroy();
+    }
+
+    @Test
+    void testReadByte() throws IOException {
+        FrameworkModel frameworkModel = new FrameworkModel();
+        Serialization serialization = 
frameworkModel.getExtensionLoader(Serialization.class).getExtension("hessian2");
+        URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+        // write byte, read byte
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject((byte) 11);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertEquals((byte) 11, objectInput.readByte());
+        }
+
+        // write date, read failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(new Date());
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(IOException.class, objectInput::readByte);
+        }
+
+        // write pojo, read failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(new 
TrustedPojo(ThreadLocalRandom.current().nextDouble()));
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(IOException.class, objectInput::readByte);
+        }
+
+        // write map, read failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(new HashMap<>());
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(IOException.class, objectInput::readByte);
+        }
+
+        // write list, read failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(new LinkedList<>());
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(IOException.class, objectInput::readByte);
+        }
+
+        frameworkModel.destroy();
+    }
+
+    @Test
+    void testReadObject() throws IOException, ClassNotFoundException {
+        FrameworkModel frameworkModel = new FrameworkModel();
+        Serialization serialization = 
frameworkModel.getExtensionLoader(Serialization.class).getExtension("hessian2");
+        URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+        // write pojo, read pojo
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+            objectOutput.writeObject(trustedPojo);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertEquals(trustedPojo, objectInput.readObject());
+        }
+
+        // write list, read list
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+            LinkedList<TrustedPojo> pojos = new LinkedList<>();
+            pojos.add(trustedPojo);
+
+            objectOutput.writeObject(pojos);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertEquals(pojos, objectInput.readObject());
+        }
+
+        // write pojo, read pojo
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+            objectOutput.writeObject(trustedPojo);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertEquals(trustedPojo, 
objectInput.readObject(TrustedPojo.class));
+        }
+
+        // write list, read list
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+            LinkedList<TrustedPojo> pojos = new LinkedList<>();
+            pojos.add(trustedPojo);
+
+            objectOutput.writeObject(pojos);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertEquals(pojos, objectInput.readObject(List.class));
+        }
+
+        // write list, read list
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+            LinkedList<TrustedPojo> pojos = new LinkedList<>();
+            pojos.add(trustedPojo);
+
+            objectOutput.writeObject(pojos);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertEquals(pojos, 
objectInput.readObject(LinkedList.class));
+        }
+
+        frameworkModel.destroy();
+    }
+
+    @Test
+    void testReadObjectNotMatched() throws IOException, ClassNotFoundException 
{
+        FrameworkModel frameworkModel = new FrameworkModel();
+        Serialization serialization = 
frameworkModel.getExtensionLoader(Serialization.class).getExtension("hessian2");
+        URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+        // write pojo, read list failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+            objectOutput.writeObject(trustedPojo);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(RuntimeException.class, () -> 
objectInput.readObject(List.class));
+        }
+
+        // write pojo, read list failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+            objectOutput.writeObject(trustedPojo);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(RuntimeException.class, () -> 
objectInput.readObject(LinkedList.class));
+        }
+
+        // write pojo, read string failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+            objectOutput.writeObject(trustedPojo);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(RuntimeException.class, () -> 
objectInput.readObject(String.class));
+        }
+
+        // write pojo, read other failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+            objectOutput.writeObject(trustedPojo);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(RuntimeException.class, () -> 
objectInput.readObject(TrustedNotSerializable.class));
+        }
+
+        // write pojo, read same field failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+            objectOutput.writeObject(trustedPojo);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertInstanceOf(TrustedPojo2.class, 
objectInput.readObject(TrustedPojo2.class));
+        }
+
+        // write pojo, read map failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+            objectOutput.writeObject(trustedPojo);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertInstanceOf(Map.class, 
objectInput.readObject(Map.class));
+        }
+
+        // write list, read pojo failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+            LinkedList<TrustedPojo> pojos = new LinkedList<>();
+            pojos.add(trustedPojo);
+
+            objectOutput.writeObject(pojos);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(RuntimeException.class, () -> 
objectInput.readObject(TrustedPojo.class));
+        }
+
+        // write list, read map failed
+        {
+            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+            LinkedList<TrustedPojo> pojos = new LinkedList<>();
+            pojos.add(trustedPojo);
+
+            objectOutput.writeObject(pojos);
+            objectOutput.flushBuffer();
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertThrows(RuntimeException.class, () -> 
objectInput.readObject(Map.class));
+        }
+
+        frameworkModel.destroy();
+    }
+
+    @Test
+    void testLimit1() throws IOException, ClassNotFoundException {
+        FrameworkModel frameworkModel = new FrameworkModel();
+        Serialization serialization = 
frameworkModel.getExtensionLoader(Serialization.class).getExtension("hessian2");
+        URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+        // write trusted, read trusted
+        TrustedPojo trustedPojo = new 
TrustedPojo(ThreadLocalRandom.current().nextDouble());
+
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        ObjectOutput objectOutput = serialization.serialize(url, outputStream);
+        objectOutput.writeObject(trustedPojo);
+        objectOutput.flushBuffer();
+
+        byte[] bytes = outputStream.toByteArray();
+        ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+        ObjectInput objectInput = serialization.deserialize(url, inputStream);
+        Assertions.assertEquals(trustedPojo, objectInput.readObject());
+
+        frameworkModel.destroy();
+    }
+
+    @Test
+    void testLimit2() throws IOException, ClassNotFoundException {
+        FrameworkModel frameworkModel = new FrameworkModel();
+        Serialization serialization = 
frameworkModel.getExtensionLoader(Serialization.class).getExtension("hessian2");
+        
frameworkModel.getBeanFactory().getBean(SerializeSecurityManager.class).setCheckStatus(SerializeCheckStatus.STRICT);
+        URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+        // write untrusted failed
+        TestPojo trustedPojo = new TestPojo("12345");
+
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        ObjectOutput objectOutput = serialization.serialize(url, outputStream);
+        Assertions.assertThrows(IllegalArgumentException.class, () -> 
objectOutput.writeObject(trustedPojo));
+
+        frameworkModel.destroy();
+    }
+
+    @Test
+    void testLimit3() throws IOException, ClassNotFoundException {
+        FrameworkModel frameworkModel = new FrameworkModel();
+        Serialization serialization = 
frameworkModel.getExtensionLoader(Serialization.class).getExtension("hessian2");
+        URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+        // write un-serializable failed
+        TrustedNotSerializable trustedPojo = new 
TrustedNotSerializable(ThreadLocalRandom.current().nextDouble());
+
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        ObjectOutput objectOutput = serialization.serialize(url, outputStream);
+        Assertions.assertThrows(IllegalArgumentException.class, () -> 
objectOutput.writeObject(trustedPojo));
+
+        frameworkModel.destroy();
+    }
+
+    @Test
+    void testLimit4() throws IOException, ClassNotFoundException {
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        // write force untrusted, read failed
+
+        {
+            FrameworkModel frameworkModel = new FrameworkModel();
+            Serialization serialization = 
frameworkModel.getExtensionLoader(Serialization.class).getExtension("hessian2");
+            URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+            TestPojo trustedPojo = new TestPojo("12345");
+
+            
frameworkModel.getBeanFactory().getBean(SerializeSecurityManager.class).addToAllowed(trustedPojo.getClass().getName());
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(trustedPojo);
+            objectOutput.flushBuffer();
+
+            frameworkModel.destroy();
+        }
+
+        {
+            FrameworkModel frameworkModel = new FrameworkModel();
+            Serialization serialization = 
frameworkModel.getExtensionLoader(Serialization.class).getExtension("hessian2");
+            URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+            byte[] bytes = outputStream.toByteArray();
+            
frameworkModel.getBeanFactory().getBean(SerializeSecurityManager.class).setCheckStatus(SerializeCheckStatus.STRICT);
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertInstanceOf(Map.class, objectInput.readObject());
+            frameworkModel.destroy();
+        }
+    }
+
+    @Test
+    void testLimit5() throws IOException, ClassNotFoundException {
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        // write force un-serializable, read failed
+
+        {
+            System.setProperty("dubbo.hessian.allowNonSerializable", "true");
+            FrameworkModel frameworkModel = new FrameworkModel();
+            Serialization serialization = 
frameworkModel.getExtensionLoader(Serialization.class).getExtension("hessian2");
+            URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+            TrustedNotSerializable trustedPojo = new 
TrustedNotSerializable(ThreadLocalRandom.current().nextDouble());
+
+            
frameworkModel.getBeanFactory().getBean(SerializeSecurityManager.class).setCheckSerializable(false);
+            ObjectOutput objectOutput = serialization.serialize(url, 
outputStream);
+            objectOutput.writeObject(trustedPojo);
+            objectOutput.flushBuffer();
+
+            frameworkModel.destroy();
+            System.clearProperty("dubbo.hessian.allowNonSerializable");
+        }
+
+        {
+            FrameworkModel frameworkModel = new FrameworkModel();
+            Serialization serialization = 
frameworkModel.getExtensionLoader(Serialization.class).getExtension("hessian2");
+            URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+            byte[] bytes = outputStream.toByteArray();
+            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+            ObjectInput objectInput = serialization.deserialize(url, 
inputStream);
+            Assertions.assertInstanceOf(Map.class, objectInput.readObject());
+            frameworkModel.destroy();
+        }
+    }
+}
diff --git 
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
 
b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/TrustedNotSerializable.java
similarity index 55%
copy from 
dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
copy to 
dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/TrustedNotSerializable.java
index 578850905c..dea99604e8 100644
--- 
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
+++ 
b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/TrustedNotSerializable.java
@@ -16,26 +16,26 @@
  */
 package org.apache.dubbo.common.serialize.hessian2;
 
-import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.apache.dubbo.rpc.model.FrameworkModel;
-import org.apache.dubbo.rpc.model.ModuleModel;
-import org.apache.dubbo.rpc.model.ScopeModelInitializer;
+import java.util.Objects;
 
-public class Hessian2ScopeModelInitializer implements ScopeModelInitializer {
-    @Override
-    public void initializeFrameworkModel(FrameworkModel frameworkModel) {
-        ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
-        beanFactory.registerBean(Hessian2FactoryManager.class);
-    }
+public class TrustedNotSerializable {
 
-    @Override
-    public void initializeApplicationModel(ApplicationModel applicationModel) {
+    private final double data;
 
+    public TrustedNotSerializable(double data) {
+        this.data = data;
     }
 
     @Override
-    public void initializeModuleModel(ModuleModel moduleModel) {
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        TrustedNotSerializable that = (TrustedNotSerializable) o;
+        return Objects.equals(data, that.data);
+    }
 
+    @Override
+    public int hashCode() {
+        return Objects.hash(data);
     }
 }
diff --git 
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
 
b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/TrustedPojo.java
similarity index 55%
copy from 
dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
copy to 
dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/TrustedPojo.java
index 578850905c..14eabaa853 100644
--- 
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
+++ 
b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/TrustedPojo.java
@@ -16,26 +16,27 @@
  */
 package org.apache.dubbo.common.serialize.hessian2;
 
-import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.apache.dubbo.rpc.model.FrameworkModel;
-import org.apache.dubbo.rpc.model.ModuleModel;
-import org.apache.dubbo.rpc.model.ScopeModelInitializer;
+import java.io.Serializable;
+import java.util.Objects;
 
-public class Hessian2ScopeModelInitializer implements ScopeModelInitializer {
-    @Override
-    public void initializeFrameworkModel(FrameworkModel frameworkModel) {
-        ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
-        beanFactory.registerBean(Hessian2FactoryManager.class);
-    }
+public class TrustedPojo implements Serializable {
 
-    @Override
-    public void initializeApplicationModel(ApplicationModel applicationModel) {
+    private final double data;
 
+    public TrustedPojo(double data) {
+        this.data = data;
     }
 
     @Override
-    public void initializeModuleModel(ModuleModel moduleModel) {
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        TrustedPojo that = (TrustedPojo) o;
+        return Objects.equals(data, that.data);
+    }
 
+    @Override
+    public int hashCode() {
+        return Objects.hash(data);
     }
 }
diff --git 
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
 
b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/TrustedPojo2.java
similarity index 55%
copy from 
dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
copy to 
dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/TrustedPojo2.java
index 578850905c..db499e49f3 100644
--- 
a/dubbo-serialization/dubbo-serialization-hessian2/src/main/java/org/apache/dubbo/common/serialize/hessian2/Hessian2ScopeModelInitializer.java
+++ 
b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/TrustedPojo2.java
@@ -16,26 +16,27 @@
  */
 package org.apache.dubbo.common.serialize.hessian2;
 
-import org.apache.dubbo.common.beans.factory.ScopeBeanFactory;
-import org.apache.dubbo.rpc.model.ApplicationModel;
-import org.apache.dubbo.rpc.model.FrameworkModel;
-import org.apache.dubbo.rpc.model.ModuleModel;
-import org.apache.dubbo.rpc.model.ScopeModelInitializer;
+import java.io.Serializable;
+import java.util.Objects;
 
-public class Hessian2ScopeModelInitializer implements ScopeModelInitializer {
-    @Override
-    public void initializeFrameworkModel(FrameworkModel frameworkModel) {
-        ScopeBeanFactory beanFactory = frameworkModel.getBeanFactory();
-        beanFactory.registerBean(Hessian2FactoryManager.class);
-    }
+public class TrustedPojo2 implements Serializable {
 
-    @Override
-    public void initializeApplicationModel(ApplicationModel applicationModel) {
+    private final double data;
 
+    public TrustedPojo2(double data) {
+        this.data = data;
     }
 
     @Override
-    public void initializeModuleModel(ModuleModel moduleModel) {
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        TrustedPojo2 that = (TrustedPojo2) o;
+        return Objects.equals(data, that.data);
+    }
 
+    @Override
+    public int hashCode() {
+        return Objects.hash(data);
     }
 }
diff --git 
a/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/TypeMatchTest.java
 
b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/TypeMatchTest.java
new file mode 100644
index 0000000000..b155981be7
--- /dev/null
+++ 
b/dubbo-serialization/dubbo-serialization-hessian2/src/test/java/org/apache/dubbo/common/serialize/hessian2/TypeMatchTest.java
@@ -0,0 +1,162 @@
+/*
+ * 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.serialize.hessian2;
+
+import org.apache.dubbo.common.URL;
+import org.apache.dubbo.common.serialize.DataInput;
+import org.apache.dubbo.common.serialize.DataOutput;
+import org.apache.dubbo.common.serialize.ObjectInput;
+import org.apache.dubbo.common.serialize.ObjectOutput;
+import org.apache.dubbo.common.serialize.Serialization;
+import org.apache.dubbo.common.utils.ClassUtils;
+import org.apache.dubbo.rpc.model.FrameworkModel;
+
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.extension.ExtensionContext;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.ArgumentsProvider;
+import org.junit.jupiter.params.provider.ArgumentsSource;
+import org.junit.jupiter.params.provider.ArgumentsSources;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Stream;
+
+class TypeMatchTest {
+    static class DataProvider implements ArgumentsProvider {
+        @Override
+        public Stream<? extends Arguments> provideArguments(ExtensionContext 
extensionContext) throws Exception {
+            List<Object> datas = new LinkedList<>();
+            List<Method> readMethods = new LinkedList<>();
+            List<Method> writeMethods = new LinkedList<>();
+
+            datas.add(true);
+            datas.add(false);
+            datas.add((byte) 123);
+            datas.add((byte) 234);
+            datas.add((short) 12345);
+            datas.add((short) 23456);
+            datas.add(123456);
+            datas.add(234567);
+            datas.add(1234567L);
+            datas.add(2345678L);
+            datas.add(0.123F);
+            datas.add(1.234F);
+            datas.add(0.1234D);
+            datas.add(1.2345D);
+            datas.add("hello");
+            datas.add("world");
+            datas.add("hello".getBytes());
+            datas.add("world".getBytes());
+
+            for (Method method : ObjectInput.class.getMethods()) {
+                if (method.getName().startsWith("read") && 
method.getParameterTypes().length == 0 && 
!method.getReturnType().equals(Object.class)) {
+                    readMethods.add(method);
+                }
+            }
+            for (Method method : DataInput.class.getMethods()) {
+                if (method.getName().startsWith("read") && 
method.getParameterTypes().length == 0 && 
!method.getReturnType().equals(Object.class)) {
+                    readMethods.add(method);
+                }
+            }
+
+            for (Method method : ObjectOutput.class.getMethods()) {
+                if (method.getName().startsWith("write") && 
method.getParameterTypes().length == 1 && 
!method.getParameterTypes()[0].equals(Object.class)) {
+                    writeMethods.add(method);
+                }
+            }
+
+            for (Method method : DataOutput.class.getMethods()) {
+                if (method.getName().startsWith("write") && 
method.getParameterTypes().length == 1 && 
!method.getParameterTypes()[0].equals(Object.class)) {
+                    writeMethods.add(method);
+                }
+            }
+
+            Map<Class<?>, Class<?>> primitiveWrapperTypeMap = new 
HashMap<>(16);
+            primitiveWrapperTypeMap.put(Boolean.class, boolean.class);
+            primitiveWrapperTypeMap.put(Byte.class, byte.class);
+            primitiveWrapperTypeMap.put(Character.class, char.class);
+            primitiveWrapperTypeMap.put(Double.class, double.class);
+            primitiveWrapperTypeMap.put(Float.class, float.class);
+            primitiveWrapperTypeMap.put(Integer.class, int.class);
+            primitiveWrapperTypeMap.put(Long.class, long.class);
+            primitiveWrapperTypeMap.put(Short.class, short.class);
+            primitiveWrapperTypeMap.put(Void.class, void.class);
+
+            List<Arguments> argumentsList = new LinkedList<>();
+            for (Object data : datas) {
+                for (Method input : readMethods) {
+                    for (Method output : writeMethods) {
+                        if 
(output.getParameterTypes()[0].isAssignableFrom(data.getClass())) {
+                            argumentsList.add(Arguments.arguments(data, input, 
output));
+                        }
+                        if 
(primitiveWrapperTypeMap.containsKey(data.getClass()) &&
+                            
output.getParameterTypes()[0].isAssignableFrom(primitiveWrapperTypeMap.get(data.getClass())))
 {
+                            argumentsList.add(Arguments.arguments(data, input, 
output));
+                        }
+                    }
+                }
+            }
+
+            return argumentsList.stream();
+        }
+    }
+
+    @ParameterizedTest
+    @ArgumentsSource(DataProvider.class)
+    void test(Object data, Method input, Method output) throws Exception {
+        FrameworkModel frameworkModel = new FrameworkModel();
+        Serialization serialization = 
frameworkModel.getExtensionLoader(Serialization.class).getExtension("hessian2");
+        URL url = URL.valueOf("").setScopeModel(frameworkModel);
+
+        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+        ObjectOutput objectOutput = serialization.serialize(url, outputStream);
+        output.invoke(objectOutput, data);
+        objectOutput.flushBuffer();
+
+        byte[] bytes = outputStream.toByteArray();
+        ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
+        ObjectInput objectInput = serialization.deserialize(url, inputStream);
+        if (output.getParameterTypes()[0].equals(input.getReturnType())) {
+            Object result = input.invoke(objectInput);
+            if (data.getClass().isArray()) {
+                Assertions.assertArrayEquals((byte[]) data, (byte[]) result);
+            } else {
+                Assertions.assertEquals(data, result);
+            }
+        } else {
+            try {
+                Object result = input.invoke(objectInput);
+                if (data.getClass().isArray()) {
+                    Assertions.assertNotEquals(data.getClass(), 
result.getClass());
+                } else {
+                    Assertions.assertNotEquals(data, result);
+                }
+            } catch (Exception e) {
+                // ignore
+            }
+        }
+        frameworkModel.destroy();
+    }
+}

Reply via email to