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 5ebe5d2e fix(java): fix register serializer for abstract class (#2347)
5ebe5d2e is described below
commit 5ebe5d2efb609ea461e1011e34ec6e3a84c29cdd
Author: Shawn Yang <[email protected]>
AuthorDate: Wed Jun 18 11:44:59 2025 +0800
fix(java): fix register serializer for abstract class (#2347)
## What does this PR do?
fix register serializer for abstract class
## Related issues
#2345 #2311
## 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.
-->
- [ ] 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.
-->
---
.../org/apache/fory/reflect/ReflectionUtils.java | 2 +-
.../org/apache/fory/resolver/ClassResolver.java | 24 +++--
.../apache/fory/resolver/ClassResolverTest.java | 106 ++++++++-------------
3 files changed, 50 insertions(+), 82 deletions(-)
diff --git
a/java/fory-core/src/main/java/org/apache/fory/reflect/ReflectionUtils.java
b/java/fory-core/src/main/java/org/apache/fory/reflect/ReflectionUtils.java
index 98bb0fa9..69220535 100644
--- a/java/fory-core/src/main/java/org/apache/fory/reflect/ReflectionUtils.java
+++ b/java/fory-core/src/main/java/org/apache/fory/reflect/ReflectionUtils.java
@@ -61,7 +61,7 @@ import org.apache.fory.util.unsafe._JDKAccess;
@SuppressWarnings({"unchecked", "rawtypes"})
public class ReflectionUtils {
public static boolean isAbstract(Class<?> clazz) {
- if (clazz.isArray()) {
+ if (clazz.isArray() || clazz.isPrimitive()) {
return false;
}
return Modifier.isAbstract(clazz.getModifiers());
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 69db915f..5fb44794 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
@@ -469,7 +469,7 @@ public class ClassResolver implements TypeResolver {
classInfo = new ClassInfo(this, cls, null, id, NOT_SUPPORT_XLANG);
// make `extRegistry.registeredClassIdMap` and `classInfoMap` share same
classInfo
// instances.
- setClassInfo(cls, classInfo);
+ classInfoMap.put(cls, classInfo);
}
// serializer will be set lazily in `addSerializer` method if it's null.
registeredId2ClassInfo[id] = classInfo;
@@ -517,7 +517,7 @@ public class ClassResolver implements TypeResolver {
MetaStringBytes nameBytes =
metaStringResolver.getOrCreateMetaStringBytes(encodeTypeName(name));
ClassInfo classInfo =
new ClassInfo(cls, fullNameBytes, nsBytes, nameBytes, false, null,
NO_CLASS_ID, (short) -1);
- setClassInfo(cls, classInfo);
+ classInfoMap.put(cls, classInfo);
compositeNameBytes2ClassInfo.put(
new TypeNameBytes(nsBytes.hashCode, nameBytes.hashCode), classInfo);
extRegistry.registeredClasses.put(fullname, cls);
@@ -748,6 +748,12 @@ public class ClassResolver implements TypeResolver {
register(type);
}
addSerializer(type, serializer);
+ ClassInfo classInfo = classInfoMap.get(type);
+ classInfoMap.put(type, classInfo);
+ // in order to support customized serializer for abstract or interface.
+ if (!type.isPrimitive() && (ReflectionUtils.isAbstract(type) ||
type.isInterface())) {
+ extRegistry.absClassInfo.put(type, classInfo);
+ }
}
public void setSerializerFactory(SerializerFactory serializerFactory) {
@@ -860,7 +866,7 @@ public class ClassResolver implements TypeResolver {
if (classInfo == null || classId != classInfo.classId) {
classInfo = new ClassInfo(this, type, null, classId, (short) 0);
- setClassInfo(type, classInfo);
+ classInfoMap.put(type, classInfo);
if (registered) {
registeredId2ClassInfo[classId] = classInfo;
}
@@ -1295,14 +1301,6 @@ public class ClassResolver implements TypeResolver {
}
}
- void setClassInfo(Class<?> cls, ClassInfo classInfo) {
- classInfoMap.put(cls, classInfo);
- // in order to support customized serializer for abstract or interface.
- if (!cls.isPrimitive() && (ReflectionUtils.isAbstract(cls) ||
cls.isInterface())) {
- extRegistry.absClassInfo.put(cls, classInfo);
- }
- }
-
@Internal
public ClassInfo getOrUpdateClassInfo(Class<?> cls) {
ClassInfo classInfo = classInfoCache;
@@ -1796,7 +1794,7 @@ public class ClassResolver implements TypeResolver {
classInfo =
new ClassInfo(
this, cls, null, classId == null ? NO_CLASS_ID : classId,
NOT_SUPPORT_XLANG);
- setClassInfo(cls, classInfo);
+ classInfoMap.put(cls, classInfo);
}
writeClassInternal(buffer, classInfo);
}
@@ -1977,7 +1975,7 @@ public class ClassResolver implements TypeResolver {
// don't create serializer here, if the class is an interface,
// there won't be serializer since interface has no instance.
if (!classInfoMap.containsKey(cls)) {
- setClassInfo(cls, classInfo);
+ classInfoMap.put(cls, classInfo);
}
}
compositeNameBytes2ClassInfo.put(typeNameBytes, classInfo);
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 61d0251d..19604663 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
@@ -46,7 +46,6 @@ import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.apache.fory.Fory;
import org.apache.fory.ForyTestBase;
-import org.apache.fory.ThreadSafeFory;
import org.apache.fory.builder.Generated;
import org.apache.fory.config.Language;
import org.apache.fory.logging.Logger;
@@ -402,26 +401,16 @@ public class ClassResolverTest extends ForyTestBase {
@Test
public void testFooCustomSerializer() {
- ThreadSafeFory threadSafeFory =
- Fory.builder().withLanguage(Language.JAVA).buildThreadSafeFory();
- Assert.assertThrows(
- () -> threadSafeFory.registerSerializer(Foo.class,
FooCustomSerializer.class));
- threadSafeFory.registerSerializer(Foo.class, f -> new
FooCustomSerializer(f, Foo.class));
+ Fory fory = Fory.builder().withLanguage(Language.JAVA).build();
+ Assert.assertThrows(() -> fory.registerSerializer(Foo.class,
FooCustomSerializer.class));
+ fory.registerSerializer(Foo.class, f -> new FooCustomSerializer(f,
Foo.class));
final Foo foo = new Foo();
foo.setF1(100);
- threadSafeFory.execute(
- fory -> {
- Assert.assertEquals(foo, serDe(fory, foo));
- return null;
- });
- threadSafeFory.execute(
- fory -> {
- Assert.assertEquals(
- fory.getClassResolver().getSerializer(foo.getClass()).getClass(),
- FooCustomSerializer.class);
- return null;
- });
+ Assert.assertEquals(foo, serDe(fory, foo));
+ Assert.assertEquals(
+ fory.getClassResolver().getSerializer(foo.getClass()).getClass(),
+ FooCustomSerializer.class);
}
interface ITest {
@@ -467,30 +456,32 @@ public class ClassResolverTest extends ForyTestBase {
@Test
public void testInterfaceCustomSerializer() {
- ThreadSafeFory threadSafeFory =
- Fory.builder()
- .withLanguage(Language.JAVA)
- .requireClassRegistration(false)
- .buildThreadSafeFory();
- threadSafeFory.registerSerializer(
- ITest.class, f -> new InterfaceCustomSerializer(f, ITest.class));
+ Fory fory =
Fory.builder().withLanguage(Language.JAVA).requireClassRegistration(false).build();
+ fory.registerSerializer(ITest.class, new InterfaceCustomSerializer(fory,
ITest.class));
final ITest iTest = new ImplTest();
iTest.setF1(100);
- threadSafeFory.execute(
- fory -> {
- Assert.assertEquals(iTest, serDe(fory, iTest));
- return null;
- });
- threadSafeFory.execute(
- fory -> {
- Assert.assertEquals(
-
fory.getClassResolver().getSerializer(iTest.getClass()).getClass(),
- InterfaceCustomSerializer.class);
- return null;
- });
+ Assert.assertEquals(iTest, serDe(fory, iTest));
+ Assert.assertEquals(
+ fory.getClassResolver().getSerializer(iTest.getClass()).getClass(),
+ InterfaceCustomSerializer.class);
+
+ fory =
Fory.builder().withLanguage(Language.JAVA).requireClassRegistration(false).build();
+ fory.register(ITest.class);
+ Assert.assertNotEquals(
+ fory.getClassResolver().getSerializer(ImplTest.class).getClass(),
+ InterfaceCustomSerializer.class);
+
+ fory =
Fory.builder().withLanguage(Language.JAVA).requireClassRegistration(false).build();
+ fory.registerSerializer(ITest.class, new InterfaceCustomSerializer(fory,
ITest.class));
+ Assert.assertEquals(
+ fory.getClassResolver().getSerializer(ImplTest.class).getClass(),
+ InterfaceCustomSerializer.class);
}
+ @Test
+ public void testRegisterAbstractClass() {}
+
@Data
abstract static class AbsTest {
int f1;
@@ -530,43 +521,22 @@ public class ClassResolverTest extends ForyTestBase {
@Test
public void testAbstractCustomSerializer() {
- ThreadSafeFory threadSafeFory =
- Fory.builder()
- .withLanguage(Language.JAVA)
- .requireClassRegistration(false)
- .buildThreadSafeFory();
- threadSafeFory.registerSerializer(
- AbsTest.class, f -> new AbstractCustomSerializer(f, AbsTest.class));
+ Fory fory =
Fory.builder().withLanguage(Language.JAVA).requireClassRegistration(false).build();
+ fory.registerSerializer(AbsTest.class, new AbstractCustomSerializer(fory,
AbsTest.class));
final AbsTest absTest = new SubAbsTest();
absTest.setF1(100);
- threadSafeFory.execute(
- fory -> {
- Assert.assertEquals(absTest, serDe(fory, absTest));
- return null;
- });
- threadSafeFory.execute(
- fory -> {
- Assert.assertEquals(
-
fory.getClassResolver().getSerializer(absTest.getClass()).getClass(),
- AbstractCustomSerializer.class);
- return null;
- });
+ Assert.assertEquals(absTest, serDe(fory, absTest));
+ Assert.assertEquals(
+ fory.getClassResolver().getSerializer(absTest.getClass()).getClass(),
+ AbstractCustomSerializer.class);
final AbsTest abs2Test = new Sub2AbsTest();
abs2Test.setF1(100);
- threadSafeFory.execute(
- fory -> {
- Assert.assertEquals(abs2Test.getF1(), serDe(fory, abs2Test).getF1());
- return null;
- });
- threadSafeFory.execute(
- fory -> {
- Assert.assertEquals(
-
fory.getClassResolver().getSerializer(abs2Test.getClass()).getClass(),
- AbstractCustomSerializer.class);
- return null;
- });
+ Assert.assertEquals(abs2Test.getF1(), serDe(fory, abs2Test).getF1());
+ Assert.assertEquals(
+ fory.getClassResolver().getSerializer(abs2Test.getClass()).getClass(),
+ AbstractCustomSerializer.class);
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]