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

chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory.git


The following commit(s) were added to refs/heads/main by this push:
     new ac9eeedfd fix: modify the depth setting in Fory to prevent duplicate 
registrations. (#2852)
ac9eeedfd is described below

commit ac9eeedfd3caaa92c7e1196272adb5926a9caf80
Author: zhou yong kang <[email protected]>
AuthorDate: Sun Nov 2 16:32:04 2025 +0800

    fix: modify the depth setting in Fory to prevent duplicate registrations. 
(#2852)
    
    <!--
    **Thanks for contributing to Apache Fory™.**
    
    **If this is your first time opening a PR on fory, you can refer to
    
[CONTRIBUTING.md](https://github.com/apache/fory/blob/main/CONTRIBUTING.md).**
    
    Contribution Checklist
    
    - The **Apache Fory™** community has requirements on the naming of pr
    titles. You can also find instructions in
    [CONTRIBUTING.md](https://github.com/apache/fory/blob/main/CONTRIBUTING.md).
    
    - Apache Fory™ has a strong focus on performance. If the PR you submit
    will have an impact on performance, please benchmark it first and
    provide the benchmark result here.
    -->
    
    ## Why?
    By adding a depth field to the fory instance to indicate whether it is
    registered, and then checking in the TypeResolver, it is ensured that
    the fory instance cannot be registered after serialization, otherwise a
    foryexception will be thrown.
    <!-- Describe the purpose of this PR. -->
    
    ## What does this PR do?
    
    <!-- Describe the details of this PR. -->
    ## Related issues
    Close #2840
    
    <!--
    Is there any related issue? If this PR closes them you say say
    fix/closes:
    
    - #xxxx0
    - #xxxx1
    - Fixes #xxxx2
    -->
    
    ## Does this PR introduce any user-facing change?
    
    <!--
    If any user-facing interface changes, please [open an
    issue](https://github.com/apache/fory/issues/new/choose) describing the
    need to do so and update the document if necessary.
    
    Delete section if not applicable.
    -->
    
    - [ ] Does this PR introduce any public API change?
    - [ ] Does this PR introduce any binary protocol compatibility change?
    
    ## Benchmark
    
    <!--
    When the PR has an impact on performance (if you don't know whether the
    PR will have an impact on performance, you can submit the PR first, and
    if it will have impact on performance, the code reviewer will explain
    it), be sure to attach a benchmark data here.
    
    Delete section if not applicable.
    -->
---
 .../src/main/java/org/apache/fory/Fory.java        |  26 +++---
 .../main/java/org/apache/fory/ThreadLocalFory.java |  11 ++-
 .../java/org/apache/fory/pool/ThreadPoolFory.java  |  11 ++-
 .../org/apache/fory/resolver/ClassResolver.java    |   4 +
 .../org/apache/fory/resolver/TypeResolver.java     |   9 ++
 .../org/apache/fory/resolver/XtypeResolver.java    |   4 +
 .../fory/test/ResolverValidateSerializerTest.java  |   5 +-
 .../java/org/apache/fory/CrossLanguageTest.java    |   6 +-
 .../src/test/java/org/apache/fory/ForyTest.java    |  11 ++-
 .../java/org/apache/fory/ThreadSafeForyTest.java   |  26 ++++++
 .../apache/fory/resolver/ClassResolverTest.java    |   5 +-
 .../fory/serializer/ArraySerializersTest.java      | 103 ++++++++++++++++-----
 .../serializer/ObjectStreamSerializerTest.java     |  46 +++++----
 .../serializer/ReplaceResolveSerializerTest.java   |  14 ++-
 14 files changed, 197 insertions(+), 84 deletions(-)

diff --git a/java/fory-core/src/main/java/org/apache/fory/Fory.java 
b/java/fory-core/src/main/java/org/apache/fory/Fory.java
index 3ce595398..fc9aee8cb 100644
--- a/java/fory-core/src/main/java/org/apache/fory/Fory.java
+++ b/java/fory-core/src/main/java/org/apache/fory/Fory.java
@@ -154,6 +154,7 @@ public final class Fory implements BaseFory {
     jitContext = new JITContext(this);
     generics = new Generics(this);
     metaStringResolver = new MetaStringResolver();
+    depth = -1;
     classResolver = new ClassResolver(this);
     if (crossLanguage) {
       xtypeResolver = new XtypeResolver(this);
@@ -316,9 +317,10 @@ public final class Fory implements BaseFory {
     buffer.writeByte(bitmap);
     try {
       jitContext.lock();
-      if (depth != 0) {
+      if (depth > 0) {
         throwDepthSerializationException();
       }
+      depth = 0;
       if (!crossLanguage) {
         write(buffer, obj);
       } else {
@@ -838,9 +840,10 @@ public final class Fory implements BaseFory {
   public Object deserialize(MemoryBuffer buffer, Iterable<MemoryBuffer> 
outOfBandBuffers) {
     try {
       jitContext.lock();
-      if (depth != 0) {
+      if (depth > 0) {
         throwDepthDeserializationException();
       }
+      depth = 0;
       if (crossLanguage) {
         short magicNumber = buffer.readInt16();
         assert magicNumber == MAGIC_NUMBER
@@ -1152,7 +1155,7 @@ public final class Fory implements BaseFory {
   public void serializeJavaObject(MemoryBuffer buffer, Object obj) {
     try {
       jitContext.lock();
-      if (depth != 0) {
+      if (depth > 0) {
         throwDepthSerializationException();
       }
       if (config.isMetaShareEnabled()) {
@@ -1201,7 +1204,7 @@ public final class Fory implements BaseFory {
   public <T> T deserializeJavaObject(MemoryBuffer buffer, Class<T> cls) {
     try {
       jitContext.lock();
-      if (depth != 0) {
+      if (depth > 0) {
         throwDepthDeserializationException();
       }
       if (shareMeta) {
@@ -1286,7 +1289,7 @@ public final class Fory implements BaseFory {
   public void serializeJavaObjectAndClass(MemoryBuffer buffer, Object obj) {
     try {
       jitContext.lock();
-      if (depth != 0) {
+      if (depth > 0) {
         throwDepthSerializationException();
       }
       write(buffer, obj);
@@ -1324,7 +1327,7 @@ public final class Fory implements BaseFory {
   public Object deserializeJavaObjectAndClass(MemoryBuffer buffer) {
     try {
       jitContext.lock();
-      if (depth != 0) {
+      if (depth > 0) {
         throwDepthDeserializationException();
       }
       if (shareMeta) {
@@ -1556,13 +1559,8 @@ public final class Fory implements BaseFory {
   }
 
   public void reset() {
-    refResolver.reset();
-    classResolver.reset();
-    metaStringResolver.reset();
-    serializationContext.reset();
-    peerOutOfBandEnabled = false;
-    bufferCallback = null;
-    depth = 0;
+    resetWrite();
+    resetRead();
     resetCopy();
   }
 
@@ -1581,8 +1579,8 @@ public final class Fory implements BaseFory {
     metaStringResolver.resetRead();
     serializationContext.resetRead();
     peerOutOfBandEnabled = false;
-    depth = 0;
     classDefEndOffset = -1;
+    depth = 0;
   }
 
   public void resetCopy() {
diff --git a/java/fory-core/src/main/java/org/apache/fory/ThreadLocalFory.java 
b/java/fory-core/src/main/java/org/apache/fory/ThreadLocalFory.java
index a0093e5ba..aa82fd785 100644
--- a/java/fory-core/src/main/java/org/apache/fory/ThreadLocalFory.java
+++ b/java/fory-core/src/main/java/org/apache/fory/ThreadLocalFory.java
@@ -51,6 +51,7 @@ public class ThreadLocalFory extends AbstractThreadSafeFory {
   private final Map<LoaderBinding, Object> allFory;
 
   private ClassLoader classLoader;
+  private final Object callbackLock = new Object();
 
   public ThreadLocalFory(Function<ClassLoader, Fory> foryFactory) {
     factoryCallback = f -> {};
@@ -78,10 +79,12 @@ public class ThreadLocalFory extends AbstractThreadSafeFory 
{
   @Internal
   @Override
   public void registerCallback(Consumer<Fory> callback) {
-    factoryCallback = factoryCallback.andThen(callback);
-    for (LoaderBinding binding : allFory.keySet()) {
-      binding.visitAllFory(callback);
-      binding.setBindingCallback(factoryCallback);
+    synchronized (callbackLock) {
+      factoryCallback = factoryCallback.andThen(callback);
+      for (LoaderBinding binding : allFory.keySet()) {
+        binding.visitAllFory(callback);
+        binding.setBindingCallback(factoryCallback);
+      }
     }
   }
 
diff --git 
a/java/fory-core/src/main/java/org/apache/fory/pool/ThreadPoolFory.java 
b/java/fory-core/src/main/java/org/apache/fory/pool/ThreadPoolFory.java
index b1bebc1a6..d7017d762 100644
--- a/java/fory-core/src/main/java/org/apache/fory/pool/ThreadPoolFory.java
+++ b/java/fory-core/src/main/java/org/apache/fory/pool/ThreadPoolFory.java
@@ -44,6 +44,7 @@ public class ThreadPoolFory extends AbstractThreadSafeFory {
 
   private final ForyPooledObjectFactory foryPooledObjectFactory;
   private Consumer<Fory> factoryCallback = f -> {};
+  private final Object callbackLock = new Object();
 
   public ThreadPoolFory(
       Function<ClassLoader, Fory> foryFactory,
@@ -64,10 +65,12 @@ public class ThreadPoolFory extends AbstractThreadSafeFory {
   @Internal
   @Override
   public void registerCallback(Consumer<Fory> callback) {
-    factoryCallback = factoryCallback.andThen(callback);
-    for (ClassLoaderForyPooled foryPooled :
-        foryPooledObjectFactory.classLoaderForyPooledCache.asMap().values()) {
-      foryPooled.allFory.keySet().forEach(callback);
+    synchronized (callbackLock) {
+      factoryCallback = factoryCallback.andThen(callback);
+      for (ClassLoaderForyPooled foryPooled :
+          foryPooledObjectFactory.classLoaderForyPooledCache.asMap().values()) 
{
+        foryPooled.allFory.keySet().forEach(callback);
+      }
     }
   }
 
diff --git 
a/java/fory-core/src/main/java/org/apache/fory/resolver/ClassResolver.java 
b/java/fory-core/src/main/java/org/apache/fory/resolver/ClassResolver.java
index 62fda3322..77a66cdfc 100644
--- a/java/fory-core/src/main/java/org/apache/fory/resolver/ClassResolver.java
+++ b/java/fory-core/src/main/java/org/apache/fory/resolver/ClassResolver.java
@@ -408,6 +408,7 @@ public class ClassResolver extends TypeResolver {
    * In the future this limitation may be relaxed.
    */
   public void register(Class<?> cls, int classId) {
+    checkRegisterAllowed();
     // class id must be less than Integer.MAX_VALUE/2 since we use bit 0 as 
class id flag.
     Preconditions.checkArgument(classId >= 0 && classId < Short.MAX_VALUE);
     short id = (short) classId;
@@ -453,6 +454,7 @@ public class ClassResolver extends TypeResolver {
    */
   @Override
   public void register(Class<?> cls, String namespace, String name) {
+    checkRegisterAllowed();
     Preconditions.checkArgument(!Functions.isLambda(cls));
     Preconditions.checkArgument(!ReflectionUtils.isJdkProxy(cls));
     Preconditions.checkArgument(!cls.isArray());
@@ -668,6 +670,7 @@ public class ClassResolver extends TypeResolver {
    * @param <T> type of class
    */
   public <T> void registerSerializer(Class<T> type, Class<? extends 
Serializer> serializerClass) {
+    checkRegisterAllowed();
     registerSerializer(type, Serializers.newSerializer(fory, type, 
serializerClass));
   }
 
@@ -678,6 +681,7 @@ public class ClassResolver extends TypeResolver {
    * @param serializer serializer for object of {@code type}
    */
   public void registerSerializer(Class<?> type, Serializer<?> serializer) {
+    checkRegisterAllowed();
     if 
(!serializer.getClass().getPackage().getName().startsWith("org.apache.fory")) {
       SerializationUtils.validate(type, serializer.getClass());
     }
diff --git 
a/java/fory-core/src/main/java/org/apache/fory/resolver/TypeResolver.java 
b/java/fory-core/src/main/java/org/apache/fory/resolver/TypeResolver.java
index 4db04ecf9..9cd7bd73b 100644
--- a/java/fory-core/src/main/java/org/apache/fory/resolver/TypeResolver.java
+++ b/java/fory-core/src/main/java/org/apache/fory/resolver/TypeResolver.java
@@ -51,6 +51,7 @@ import org.apache.fory.collection.LongMap;
 import org.apache.fory.collection.ObjectArray;
 import org.apache.fory.collection.Tuple2;
 import org.apache.fory.config.CompatibleMode;
+import org.apache.fory.exception.ForyException;
 import org.apache.fory.logging.Logger;
 import org.apache.fory.logging.LoggerFactory;
 import org.apache.fory.memory.MemoryBuffer;
@@ -111,6 +112,14 @@ public abstract class TypeResolver {
     metaStringResolver = fory.getMetaStringResolver();
   }
 
+  protected final void checkRegisterAllowed() {
+    if (fory.getDepth() >= 0) {
+      throw new ForyException(
+          "Cannot register class/serializer after 
serialization/deserialization has started. "
+              + "Please register all classes before invoking 
`serialize/deserialize` methods of Fory.");
+    }
+  }
+
   public abstract void register(Class<?> type);
 
   public abstract void register(Class<?> type, int id);
diff --git 
a/java/fory-core/src/main/java/org/apache/fory/resolver/XtypeResolver.java 
b/java/fory-core/src/main/java/org/apache/fory/resolver/XtypeResolver.java
index 34ac51918..b5451869f 100644
--- a/java/fory-core/src/main/java/org/apache/fory/resolver/XtypeResolver.java
+++ b/java/fory-core/src/main/java/org/apache/fory/resolver/XtypeResolver.java
@@ -160,6 +160,7 @@ public class XtypeResolver extends TypeResolver {
 
   @Override
   public void register(Class<?> type, int userTypeId) {
+    checkRegisterAllowed();
     // ClassInfo[] has length of max type id. If the type id is too big, Fory 
will waste many
     // memory. We can relax this limit in the future.
     Preconditions.checkArgument(userTypeId < MAX_TYPE_ID, "Too big type id 
%s", userTypeId);
@@ -209,6 +210,7 @@ public class XtypeResolver extends TypeResolver {
 
   @Override
   public void register(Class<?> type, String namespace, String typeName) {
+    checkRegisterAllowed();
     Preconditions.checkArgument(
         !typeName.contains("."),
         "Typename %s should not contains `.`, please put it into namespace",
@@ -339,10 +341,12 @@ public class XtypeResolver extends TypeResolver {
   }
 
   public <T> void registerSerializer(Class<T> type, Class<? extends 
Serializer> serializerClass) {
+    checkRegisterAllowed();
     registerSerializer(type, Serializers.newSerializer(fory, type, 
serializerClass));
   }
 
   public void registerSerializer(Class<?> type, Serializer<?> serializer) {
+    checkRegisterAllowed();
     ClassInfo classInfo = checkClassRegistration(type);
     if 
(!serializer.getClass().getPackage().getName().startsWith("org.apache.fory")) {
       SerializationUtils.validate(type, serializer.getClass());
diff --git 
a/java/fory-core/src/test/java/javax/fory/test/ResolverValidateSerializerTest.java
 
b/java/fory-core/src/test/java/javax/fory/test/ResolverValidateSerializerTest.java
index 89320d729..b61988724 100644
--- 
a/java/fory-core/src/test/java/javax/fory/test/ResolverValidateSerializerTest.java
+++ 
b/java/fory-core/src/test/java/javax/fory/test/ResolverValidateSerializerTest.java
@@ -156,7 +156,6 @@ public class ResolverValidateSerializerTest {
   @Test
   public void testListAndMapSerializerRegistration() {
     Fory fory = 
Fory.builder().withRefTracking(true).requireClassRegistration(false).build();
-    // List invalid
     assertThrows(
         IllegalArgumentException.class,
         () -> fory.registerSerializer(InvalidList.class, 
InvalidList.InvalidListSerializer.class));
@@ -173,8 +172,6 @@ public class ResolverValidateSerializerTest {
     // List valid
     fory.register(ValidList.class);
     fory.registerSerializer(ValidList.class, new 
ValidList.ValidListSerializer(fory));
-    Object listResult = fory.deserialize(fory.serialize(new ValidList()));
-    assertTrue(listResult instanceof ValidList);
     // Map invalid
     assertThrows(
         IllegalArgumentException.class,
@@ -189,6 +186,8 @@ public class ResolverValidateSerializerTest {
     // Map valid
     fory.register(ValidMap.class);
     fory.registerSerializer(ValidMap.class, new 
ValidMap.ValidMapSerializer(fory));
+    Object listResult = fory.deserialize(fory.serialize(new ValidList()));
+    assertTrue(listResult instanceof ValidList);
     Object mapResult = fory.deserialize(fory.serialize(new ValidMap()));
     assertTrue(mapResult instanceof ValidMap);
   }
diff --git 
a/java/fory-core/src/test/java/org/apache/fory/CrossLanguageTest.java 
b/java/fory-core/src/test/java/org/apache/fory/CrossLanguageTest.java
index a5111f3a7..5e69ba90b 100644
--- a/java/fory-core/src/test/java/org/apache/fory/CrossLanguageTest.java
+++ b/java/fory-core/src/test/java/org/apache/fory/CrossLanguageTest.java
@@ -781,13 +781,13 @@ public class CrossLanguageTest extends ForyTestBase {
             .requireClassRegistration(false);
     Fory fory1 = builder.build();
     Fory fory2 = builder.build();
-    assertEquals("str", serDe(fory1, fory2, "str"));
-    assertEquals("str", serDeObject(fory1, fory2, new 
StringBuilder("str")).toString());
-    assertEquals("str", serDeObject(fory1, fory2, new 
StringBuffer("str")).toString());
     fory1.register(EnumSerializerTest.EnumFoo.class);
     fory2.register(EnumSerializerTest.EnumFoo.class);
     fory1.register(EnumSerializerTest.EnumSubClass.class);
     fory2.register(EnumSerializerTest.EnumSubClass.class);
+    assertEquals("str", serDe(fory1, fory2, "str"));
+    assertEquals("str", serDeObject(fory1, fory2, new 
StringBuilder("str")).toString());
+    assertEquals("str", serDeObject(fory1, fory2, new 
StringBuffer("str")).toString());
     assertEquals(EnumSerializerTest.EnumFoo.A, serDe(fory1, fory2, 
EnumSerializerTest.EnumFoo.A));
     assertEquals(EnumSerializerTest.EnumFoo.B, serDe(fory1, fory2, 
EnumSerializerTest.EnumFoo.B));
     assertEquals(
diff --git a/java/fory-core/src/test/java/org/apache/fory/ForyTest.java 
b/java/fory-core/src/test/java/org/apache/fory/ForyTest.java
index 01a2943cf..80c5af116 100644
--- a/java/fory-core/src/test/java/org/apache/fory/ForyTest.java
+++ b/java/fory-core/src/test/java/org/apache/fory/ForyTest.java
@@ -189,17 +189,18 @@ public class ForyTest extends ForyTestBase {
   }
 
   public void assertSerializationToBuffer(Fory fory1, Fory fory2, MemoryBuffer 
buffer) {
-    assertEquals(true, serDeCheckIndex(fory1, fory2, buffer, true));
-    assertEquals(Byte.MAX_VALUE, serDeCheckIndex(fory1, fory2, buffer, 
Byte.MAX_VALUE));
-    assertEquals(Short.MAX_VALUE, serDeCheckIndex(fory1, fory2, buffer, 
Short.MAX_VALUE));
-    assertEquals("str", serDeCheckIndex(fory1, fory2, buffer, "str"));
-    assertEquals("str", serDeCheckIndex(fory1, fory2, buffer, new 
StringBuilder("str")).toString());
     if (fory1.isCrossLanguage()) {
       fory1.register(EnumSerializerTest.EnumFoo.class);
       fory2.register(EnumSerializerTest.EnumFoo.class);
       fory1.register(EnumSerializerTest.EnumSubClass.class);
       fory2.register(EnumSerializerTest.EnumSubClass.class);
     }
+
+    assertEquals(true, serDeCheckIndex(fory1, fory2, buffer, true));
+    assertEquals(Byte.MAX_VALUE, serDeCheckIndex(fory1, fory2, buffer, 
Byte.MAX_VALUE));
+    assertEquals(Short.MAX_VALUE, serDeCheckIndex(fory1, fory2, buffer, 
Short.MAX_VALUE));
+    assertEquals("str", serDeCheckIndex(fory1, fory2, buffer, "str"));
+    assertEquals("str", serDeCheckIndex(fory1, fory2, buffer, new 
StringBuilder("str")).toString());
     assertEquals(
         EnumSerializerTest.EnumFoo.A,
         serDeCheckIndex(fory1, fory2, buffer, EnumSerializerTest.EnumFoo.A));
diff --git 
a/java/fory-core/src/test/java/org/apache/fory/ThreadSafeForyTest.java 
b/java/fory-core/src/test/java/org/apache/fory/ThreadSafeForyTest.java
index dd8697e8c..6087745b5 100644
--- a/java/fory-core/src/test/java/org/apache/fory/ThreadSafeForyTest.java
+++ b/java/fory-core/src/test/java/org/apache/fory/ThreadSafeForyTest.java
@@ -32,6 +32,7 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
 import lombok.Data;
 import org.apache.fory.config.Language;
+import org.apache.fory.exception.ForyException;
 import org.apache.fory.memory.MemoryBuffer;
 import org.apache.fory.resolver.MetaContext;
 import org.apache.fory.serializer.Serializer;
@@ -373,4 +374,29 @@ public class ThreadSafeForyTest extends ForyTestBase {
           return null;
         });
   }
+
+  @Test
+  public void testRegisterAfterSerializeThrowsException() throws Exception {
+    ThreadSafeFory fory = 
Fory.builder().requireClassRegistration(true).buildThreadLocalFory();
+    fory.register(BeanA.class);
+    fory.serialize("ok");
+    Assert.assertThrows(ForyException.class, () -> fory.register(BeanB.class));
+  }
+
+  @Test
+  public void testRegisterAfterSerializeThrowsExceptionWithFory() {
+    Fory fory = Fory.builder().requireClassRegistration(true).build();
+    fory.register(BeanA.class);
+    fory.serialize("ok");
+    Assert.assertThrows(ForyException.class, () -> fory.register(BeanB.class));
+  }
+
+  @Test
+  public void testRegisterAfterSerializeThrowsExceptionWithForyPool() {
+    ThreadSafeFory fory =
+        
Fory.builder().requireClassRegistration(true).buildThreadSafeForyPool(1, 2);
+    fory.register(BeanA.class);
+    fory.serialize("ok");
+    Assert.assertThrows(ForyException.class, () -> fory.register(BeanB.class));
+  }
 }
diff --git 
a/java/fory-core/src/test/java/org/apache/fory/resolver/ClassResolverTest.java 
b/java/fory-core/src/test/java/org/apache/fory/resolver/ClassResolverTest.java
index 196046633..d0790e836 100644
--- 
a/java/fory-core/src/test/java/org/apache/fory/resolver/ClassResolverTest.java
+++ 
b/java/fory-core/src/test/java/org/apache/fory/resolver/ClassResolverTest.java
@@ -100,14 +100,15 @@ public class ClassResolverTest extends ForyTestBase {
         IllegalArgumentException.class, () -> classResolver.register(C1.class, 
"ns", "C1"));
     Assert.assertThrows(
         IllegalArgumentException.class, () -> classResolver.register(C1.class, 
200));
+    classResolver.register(C2.class, "", "C2");
+    classResolver.register(Foo.class, "ns", "Foo");
+
     Assert.assertTrue(fory.serialize(C1.class).length < 12);
     serDeCheck(fory, C1.class);
 
-    classResolver.register(C2.class, "", "C2");
     Assert.assertTrue(fory.serialize(C2.class).length < 12);
     serDeCheck(fory, C2.class);
 
-    classResolver.register(Foo.class, "ns", "Foo");
     Foo foo = new Foo();
     foo.f1 = 10;
     serDeCheck(fory, foo);
diff --git 
a/java/fory-core/src/test/java/org/apache/fory/serializer/ArraySerializersTest.java
 
b/java/fory-core/src/test/java/org/apache/fory/serializer/ArraySerializersTest.java
index 625f59e12..f2e53c8e1 100644
--- 
a/java/fory-core/src/test/java/org/apache/fory/serializer/ArraySerializersTest.java
+++ 
b/java/fory-core/src/test/java/org/apache/fory/serializer/ArraySerializersTest.java
@@ -43,8 +43,54 @@ import org.testng.annotations.Test;
 
 public class ArraySerializersTest extends ForyTestBase {
 
+  private static void registerTypes(Fory... forys) {
+    Class<?>[] types =
+        new Class<?>[] {
+          Object.class,
+          Boolean.class,
+          Byte.class,
+          Short.class,
+          Integer.class,
+          Float.class,
+          Double.class,
+          Long.class,
+          String.class,
+          Object[].class,
+          Boolean[].class,
+          Byte[].class,
+          Short[].class,
+          Integer[].class,
+          Float[].class,
+          Double[].class,
+          Long[].class,
+          String[].class,
+          Object[][].class,
+          Boolean[][].class,
+          Byte[][].class,
+          Short[][].class,
+          Integer[][].class,
+          Float[][].class,
+          Double[][].class,
+          Long[][].class,
+          String[][].class
+        };
+    for (Fory f : forys) {
+      for (Class<?> t : types) {
+        f.getSerializer(t);
+      }
+      if (f.getConfig().getLanguage() == Language.JAVA) {
+        f.getSerializer(Character.class);
+        f.getSerializer(Character[].class);
+        f.getSerializer(Character[][].class);
+      }
+    }
+  }
+
   @Test(dataProvider = "crossLanguageReferenceTrackingConfig")
   public void testObjectArraySerialization(boolean referenceTracking, Language 
language) {
+    if (language != Language.JAVA) {
+      return;
+    }
     ForyBuilder builder =
         Fory.builder()
             .withLanguage(language)
@@ -52,30 +98,35 @@ public class ArraySerializersTest extends ForyTestBase {
             .requireClassRegistration(false);
     Fory fory1 = builder.build();
     Fory fory2 = builder.build();
-    serDeCheckTyped(fory1, fory2, new Object[] {false, true});
-    serDeCheckTyped(fory1, fory2, new Object[] {(byte) 1, (byte) 1});
-    serDeCheckTyped(fory1, fory2, new Object[] {(short) 1, (short) 1});
+    if (fory1.getConfig().isMetaShareEnabled()) {
+      fory1.getSerializationContext().setMetaContext(new 
org.apache.fory.resolver.MetaContext());
+      fory2.getSerializationContext().setMetaContext(new 
org.apache.fory.resolver.MetaContext());
+    }
+    registerTypes(fory1, fory2);
+    serDeCheck(fory1, fory2, new Object[] {false, true});
+    serDeCheck(fory1, fory2, new Object[] {(byte) 1, (byte) 1});
+    serDeCheck(fory1, fory2, new Object[] {(short) 1, (short) 1});
     if (language == Language.JAVA) {
-      serDeCheckTyped(fory1, fory2, new Object[] {(char) 1, (char) 1});
+      serDeCheck(fory1, fory2, new Object[] {(char) 1, (char) 1});
     }
-    serDeCheckTyped(fory1, fory2, new Object[] {1, 1});
-    serDeCheckTyped(fory1, fory2, new Object[] {(float) 1.0, (float) 1.1});
-    serDeCheckTyped(fory1, fory2, new Object[] {1.0, 1.1});
-    serDeCheckTyped(fory1, fory2, new Object[] {1L, 2L});
-    serDeCheckTyped(fory1, fory2, new Boolean[] {false, true});
-    serDeCheckTyped(fory1, fory2, new Byte[] {(byte) 1, (byte) 1});
-    serDeCheckTyped(fory1, fory2, new Short[] {(short) 1, (short) 1});
+    serDeCheck(fory1, fory2, new Object[] {1, 1});
+    serDeCheck(fory1, fory2, new Object[] {(float) 1.0, (float) 1.1});
+    serDeCheck(fory1, fory2, new Object[] {1.0, 1.1});
+    serDeCheck(fory1, fory2, new Object[] {1L, 2L});
+    serDeCheck(fory1, fory2, new Boolean[] {false, true});
+    serDeCheck(fory1, fory2, new Byte[] {(byte) 1, (byte) 1});
+    serDeCheck(fory1, fory2, new Short[] {(short) 1, (short) 1});
     if (language == Language.JAVA) {
-      serDeCheckTyped(fory1, fory2, new Character[] {(char) 1, (char) 1});
+      serDeCheck(fory1, fory2, new Character[] {(char) 1, (char) 1});
     }
-    serDeCheckTyped(fory1, fory2, new Integer[] {1, 1});
-    serDeCheckTyped(fory1, fory2, new Float[] {(float) 1.0, (float) 1.1});
-    serDeCheckTyped(fory1, fory2, new Double[] {1.0, 1.1});
-    serDeCheckTyped(fory1, fory2, new Long[] {1L, 2L});
-    serDeCheckTyped(
+    serDeCheck(fory1, fory2, new Integer[] {1, 1});
+    serDeCheck(fory1, fory2, new Float[] {(float) 1.0, (float) 1.1});
+    serDeCheck(fory1, fory2, new Double[] {1.0, 1.1});
+    serDeCheck(fory1, fory2, new Long[] {1L, 2L});
+    serDeCheck(
         fory1, fory2, new Object[] {false, true, (byte) 1, (byte) 1, (float) 
1.0, (float) 1.1});
-    serDeCheckTyped(fory1, fory2, new String[] {"str", "str"});
-    serDeCheckTyped(fory1, fory2, new Object[] {"str", 1});
+    serDeCheck(fory1, fory2, new String[] {"str", "str"});
+    serDeCheck(fory1, fory2, new Object[] {"str", 1});
   }
 
   @Test(dataProvider = "foryCopyConfig")
@@ -103,6 +154,9 @@ public class ArraySerializersTest extends ForyTestBase {
 
   @Test(dataProvider = "crossLanguageReferenceTrackingConfig")
   public void testMultiArraySerialization(boolean referenceTracking, Language 
language) {
+    if (language != Language.JAVA) {
+      return;
+    }
     ForyBuilder builder =
         Fory.builder()
             .withLanguage(language)
@@ -110,15 +164,20 @@ public class ArraySerializersTest extends ForyTestBase {
             .requireClassRegistration(false);
     Fory fory1 = builder.build();
     Fory fory2 = builder.build();
-    serDeCheckTyped(fory1, fory2, new Object[][] {{false, true}, {false, 
true}});
-    serDeCheckTyped(
+    if (fory1.getConfig().isMetaShareEnabled()) {
+      fory1.getSerializationContext().setMetaContext(new 
org.apache.fory.resolver.MetaContext());
+      fory2.getSerializationContext().setMetaContext(new 
org.apache.fory.resolver.MetaContext());
+    }
+    registerTypes(fory1, fory2);
+    serDeCheck(fory1, fory2, new Object[][] {{false, true}, {false, true}});
+    serDeCheck(
         fory1,
         fory2,
         new Object[][] {
           {false, true, (byte) 1, (byte) 1, (float) 1.0, (float) 1.1},
           {false, true, (byte) 1, (byte) 1, (float) 1.0, (float) 1.1}
         });
-    serDeCheckTyped(fory1, fory2, new Integer[][] {{1, 2}, {1, 2}});
+    serDeCheck(fory1, fory2, new Integer[][] {{1, 2}, {1, 2}});
   }
 
   @Test(dataProvider = "foryCopyConfig")
diff --git 
a/java/fory-core/src/test/java/org/apache/fory/serializer/ObjectStreamSerializerTest.java
 
b/java/fory-core/src/test/java/org/apache/fory/serializer/ObjectStreamSerializerTest.java
index 464b300f9..ccd545c0c 100644
--- 
a/java/fory-core/src/test/java/org/apache/fory/serializer/ObjectStreamSerializerTest.java
+++ 
b/java/fory-core/src/test/java/org/apache/fory/serializer/ObjectStreamSerializerTest.java
@@ -77,12 +77,13 @@ public class ObjectStreamSerializerTest extends 
ForyTestBase {
 
   @Test(dataProvider = "javaFory")
   public void testJDKCompatibleCommon(Fory fory) {
-    WriteObjectTestClass o = new WriteObjectTestClass(new char[] {'a', 'b'});
     fory.registerSerializer(
         WriteObjectTestClass.class, new ObjectStreamSerializer(fory, 
WriteObjectTestClass.class));
-    serDeCheckSerializer(fory, o, "ObjectStreamSerializer");
     fory.registerSerializer(
         StringBuilder.class, new ObjectStreamSerializer(fory, 
StringBuilder.class));
+
+    WriteObjectTestClass o = new WriteObjectTestClass(new char[] {'a', 'b'});
+    serDeCheckSerializer(fory, o, "ObjectStreamSerializer");
     assertSame(
         fory.getClassResolver().getSerializerClass(StringBuilder.class),
         ObjectStreamSerializer.class);
@@ -157,6 +158,15 @@ public class ObjectStreamSerializerTest extends 
ForyTestBase {
   public void testJDKCompatiblePutFields(Fory fory) {
     fory.registerSerializer(
         StringBuffer.class, new ObjectStreamSerializer(fory, 
StringBuffer.class));
+    fory.registerSerializer(BigInteger.class, new ObjectStreamSerializer(fory, 
BigInteger.class));
+    fory.registerSerializer(InetAddress.class, new 
ObjectStreamSerializer(fory, InetAddress.class));
+    fory.registerSerializer(
+        Inet4Address.class, new ObjectStreamSerializer(fory, 
Inet4Address.class));
+    fory.registerSerializer(
+        WriteObjectTestClass2.class, new ObjectStreamSerializer(fory, 
WriteObjectTestClass2.class));
+    fory.registerSerializer(
+        WriteObjectTestClass3.class, new ObjectStreamSerializer(fory, 
WriteObjectTestClass3.class));
+
     assertSame(
         fory.getClassResolver().getSerializerClass(StringBuffer.class),
         ObjectStreamSerializer.class);
@@ -164,21 +174,13 @@ public class ObjectStreamSerializerTest extends 
ForyTestBase {
     StringBuffer newStringBuffer = (StringBuffer) serDe(fory, new 
StringBuffer("abc"));
     assertEquals(newStringBuffer.toString(), "abc");
     BigInteger bigInteger = BigInteger.valueOf(1000);
-    fory.registerSerializer(BigInteger.class, new ObjectStreamSerializer(fory, 
BigInteger.class));
     serDeCheck(fory, bigInteger);
-    fory.registerSerializer(InetAddress.class, new 
ObjectStreamSerializer(fory, InetAddress.class));
-    fory.registerSerializer(
-        Inet4Address.class, new ObjectStreamSerializer(fory, 
Inet4Address.class));
     InetAddress inetAddress = InetAddress.getLoopbackAddress();
     serDeCheck(fory, inetAddress);
     WriteObjectTestClass2 testClassObj2 = new WriteObjectTestClass2(new char[] 
{'a', 'b'}, "abc");
-    fory.registerSerializer(
-        WriteObjectTestClass2.class, new ObjectStreamSerializer(fory, 
WriteObjectTestClass2.class));
     serDeCheck(fory, testClassObj2);
     // test defaultReadObject compatible with putFields.
     WriteObjectTestClass3 testClassObj3 = new WriteObjectTestClass3(new char[] 
{'a', 'b'}, "abc");
-    fory.registerSerializer(
-        WriteObjectTestClass3.class, new ObjectStreamSerializer(fory, 
WriteObjectTestClass3.class));
     serDeCheck(fory, testClassObj3);
   }
 
@@ -210,6 +212,12 @@ public class ObjectStreamSerializerTest extends 
ForyTestBase {
   @Test(dataProvider = "javaFory")
   public void testJDKCompatibleMap(Fory fory) {
     ImmutableMap<String, Integer> mapData = ImmutableMap.of("k1", 1, "k2", 2);
+    fory.registerSerializer(
+        ConcurrentHashMap.class, new ObjectStreamSerializer(fory, 
ConcurrentHashMap.class));
+    Map<String, Integer> hashMap = new HashMap<>(mapData);
+    fory.registerSerializer(
+        hashMap.getClass(), new ObjectStreamSerializer(fory, 
hashMap.getClass()));
+
     {
       ObjectStreamSerializer serializer = new ObjectStreamSerializer(fory, 
ConcurrentHashMap.class);
       MemoryBuffer buffer = MemoryBuffer.newHeapBuffer(32);
@@ -225,8 +233,6 @@ public class ObjectStreamSerializerTest extends 
ForyTestBase {
       fory.reset();
     }
     {
-      fory.registerSerializer(
-          ConcurrentHashMap.class, new ObjectStreamSerializer(fory, 
ConcurrentHashMap.class));
       serDeCheck(fory, new ConcurrentHashMap<>(mapData));
       assertSame(
           
fory.getClassResolver().getSerializer(ConcurrentHashMap.class).getClass(),
@@ -234,9 +240,7 @@ public class ObjectStreamSerializerTest extends 
ForyTestBase {
     }
     {
       // ImmutableMap use writeReplace, which needs special handling.
-      Map<String, Integer> map = new HashMap<>(mapData);
-      fory.registerSerializer(map.getClass(), new ObjectStreamSerializer(fory, 
map.getClass()));
-      serDeCheck(fory, map);
+      serDeCheck(fory, hashMap);
     }
   }
 
@@ -264,11 +268,12 @@ public class ObjectStreamSerializerTest extends 
ForyTestBase {
   @Test(dataProvider = "javaFory")
   public void testJDKCompatibleList(Fory fory) {
     fory.registerSerializer(ArrayList.class, new ObjectStreamSerializer(fory, 
ArrayList.class));
+    fory.registerSerializer(LinkedList.class, new ObjectStreamSerializer(fory, 
LinkedList.class));
+    fory.registerSerializer(Vector.class, new ObjectStreamSerializer(fory, 
Vector.class));
+
     List<String> list = new ArrayList<>(ImmutableList.of("a", "b", "c", "d"));
     serDeCheck(fory, list);
-    fory.registerSerializer(LinkedList.class, new ObjectStreamSerializer(fory, 
LinkedList.class));
     serDeCheck(fory, new LinkedList<>(list));
-    fory.registerSerializer(Vector.class, new ObjectStreamSerializer(fory, 
Vector.class));
     serDeCheck(fory, new Vector<>(list));
   }
 
@@ -292,6 +297,8 @@ public class ObjectStreamSerializerTest extends 
ForyTestBase {
             .withRefTracking(true)
             .withCodegen(enableCodegen)
             .build();
+    fory.registerSerializer(
+        ConcurrentHashMap.class, new ObjectStreamSerializer(fory, 
ConcurrentHashMap.class));
     {
       ObjectStreamSerializer serializer = new ObjectStreamSerializer(fory, 
ConcurrentHashMap.class);
       MemoryBuffer buffer = MemoryBuffer.newHeapBuffer(32);
@@ -416,12 +423,13 @@ public class ObjectStreamSerializerTest extends 
ForyTestBase {
 
   @Test(dataProvider = "javaFory")
   public void testWriteObjectReplace(Fory fory) throws MalformedURLException {
+    fory.registerSerializer(
+        WriteObjectTestClass4.class, new ObjectStreamSerializer(fory, 
WriteObjectTestClass4.class));
+
     Assert.assertEquals(
         serDeCheckSerializer(fory, new URL("http://test";), "ReplaceResolve"),
         new URL("http://test";));
     WriteObjectTestClass4 testClassObj4 = new WriteObjectTestClass4(new char[] 
{'a', 'b'});
-    fory.registerSerializer(
-        WriteObjectTestClass4.class, new ObjectStreamSerializer(fory, 
WriteObjectTestClass4.class));
     serDeCheckSerializer(fory, testClassObj4, "ObjectStreamSerializer");
   }
 
diff --git 
a/java/fory-core/src/test/java/org/apache/fory/serializer/ReplaceResolveSerializerTest.java
 
b/java/fory-core/src/test/java/org/apache/fory/serializer/ReplaceResolveSerializerTest.java
index 4335ab5d5..b017d7d87 100644
--- 
a/java/fory-core/src/test/java/org/apache/fory/serializer/ReplaceResolveSerializerTest.java
+++ 
b/java/fory-core/src/test/java/org/apache/fory/serializer/ReplaceResolveSerializerTest.java
@@ -79,19 +79,20 @@ public class ReplaceResolveSerializerTest extends 
ForyTestBase {
             .requireClassRegistration(false)
             .withRefTracking(referenceTracking)
             .build();
-    CustomReplaceClass1 o1 = new CustomReplaceClass1("abc");
     fory.registerSerializer(CustomReplaceClass1.class, 
ReplaceResolveSerializer.class);
     fory.registerSerializer(CustomReplaceClass1.Replaced.class, 
ReplaceResolveSerializer.class);
+    ImmutableList<Integer> list1 = ImmutableList.of(1, 2, 3, 4);
+    fory.registerSerializer(list1.getClass(), new 
ReplaceResolveSerializer(fory, list1.getClass()));
+    ImmutableMap<String, Integer> map1 = ImmutableMap.of("k1", 1, "k2", 2);
+    fory.registerSerializer(map1.getClass(), new 
ReplaceResolveSerializer(fory, map1.getClass()));
+
+    CustomReplaceClass1 o1 = new CustomReplaceClass1("abc");
     serDeCheck(fory, o1);
     assertTrue(
         fory.getClassResolver().getSerializer(o1.getClass()) instanceof 
ReplaceResolveSerializer);
 
-    ImmutableList<Integer> list1 = ImmutableList.of(1, 2, 3, 4);
-    fory.registerSerializer(list1.getClass(), new 
ReplaceResolveSerializer(fory, list1.getClass()));
     serDeCheck(fory, list1);
 
-    ImmutableMap<String, Integer> map1 = ImmutableMap.of("k1", 1, "k2", 2);
-    fory.registerSerializer(map1.getClass(), new 
ReplaceResolveSerializer(fory, map1.getClass()));
     serDeCheck(fory, map1);
     assertTrue(
         fory.getClassResolver().getSerializer(list1.getClass())
@@ -162,7 +163,6 @@ public class ReplaceResolveSerializerTest extends 
ForyTestBase {
           new CustomReplaceClass2(false, 2), new CustomReplaceClass2(true, 2),
         }) {
       assertEquals(jdkDeserialize(jdkSerialize(o)), o);
-      fory.registerSerializer(o.getClass(), ReplaceResolveSerializer.class);
       serDeCheck(fory, o);
     }
     CustomReplaceClass2 o = new CustomReplaceClass2(false, 6);
@@ -340,7 +340,6 @@ public class ReplaceResolveSerializerTest extends 
ForyTestBase {
           new Subclass1(false, 2, 10), new Subclass1(true, 2, 11),
         }) {
       assertEquals(jdkDeserialize(jdkSerialize(o)), o);
-      fory.registerSerializer(o.getClass(), ReplaceResolveSerializer.class);
       serDeCheck(fory, o);
     }
     Subclass1 o = new Subclass1(false, 6, 12);
@@ -397,7 +396,6 @@ public class ReplaceResolveSerializerTest extends 
ForyTestBase {
           new Subclass2(false, 2, 10), new Subclass2(true, 2, 11),
         }) {
       assertEquals(jdkDeserialize(jdkSerialize(o)), o);
-      fory.registerSerializer(o.getClass(), ReplaceResolveSerializer.class);
       serDeCheck(fory, o);
     }
     Subclass2 o = new Subclass2(false, 6, 12);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to