This is an automated email from the ASF dual-hosted git repository.
pandalee 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 9a246c594 fix(java): fix row encoder for private struct (#2469)
9a246c594 is described below
commit 9a246c594acf98fc335649afd662f4e5ce93085e
Author: Shawn Yang <[email protected]>
AuthorDate: Thu Aug 14 19:08:03 2025 +0800
fix(java): fix row encoder for private struct (#2469)
## What does this PR do?
<!-- Describe the purpose of this PR. -->
## Related issues
Closes #2439
## 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.
-->
---
.../main/java/org/apache/fory/type/TypeUtils.java | 63 ++++++++++------------
.../fory/format/encoder/RowEncoderBuilder.java | 2 +-
.../apache/fory/format/encoder/RowEncoderTest.java | 17 ++++++
3 files changed, 47 insertions(+), 35 deletions(-)
diff --git a/java/fory-core/src/main/java/org/apache/fory/type/TypeUtils.java
b/java/fory-core/src/main/java/org/apache/fory/type/TypeUtils.java
index a4af2479f..5d35b5b5c 100644
--- a/java/fory-core/src/main/java/org/apache/fory/type/TypeUtils.java
+++ b/java/fory-core/src/main/java/org/apache/fory/type/TypeUtils.java
@@ -619,43 +619,38 @@ public class TypeUtils {
|| ctx.getCustomTypeRegistry().isExtraSupportedType(typeRef)) {
return false;
}
- // since we need to access class in generated code in our package, the
class must be public
// if ReflectionUtils.hasNoArgConstructor(cls) return false, we use Unsafe
to create object.
- if (Modifier.isPublic(cls.getModifiers())) {
- // bean class can be static nested class, but can't be not a non-static
inner class
- if (cls.getEnclosingClass() != null &&
!Modifier.isStatic(cls.getModifiers())) {
- return false;
- }
- TypeResolutionContext newTypePath = ctx.appendTypePath(typeRef);
- if (cls == Object.class) {
- // return false for typeToken that point to un-specialized generic
type.
- return false;
- }
- boolean maybe =
- !SUPPORTED_TYPES.contains(typeRef)
- && !typeRef.isArray()
- && !cls.isEnum()
- && !ITERABLE_TYPE.isSupertypeOf(typeRef)
- && !MAP_TYPE.isSupertypeOf(typeRef);
- if (maybe) {
- for (Descriptor d : Descriptor.getDescriptors(cls)) {
- TypeRef<?> t = d.getTypeRef();
- // do field modifiers and getter/setter validation here, not in
getDescriptors.
- // If Modifier.isFinal(d.getModifiers()), use reflection
- // private field that doesn't have getter/setter will be handled by
reflection.
- TypeRef<?> replacementType =
- ctx.getCustomTypeRegistry().replacementTypeFor(cls,
t.getRawType());
- if (replacementType != null) {
- t = replacementType;
- }
- if (!isSupported(t, newTypePath)) {
- return false;
- }
+ // bean class can be static nested class, but can't be not a non-static
inner class
+ if (cls.getEnclosingClass() != null &&
!Modifier.isStatic(cls.getModifiers())) {
+ return false;
+ }
+ TypeResolutionContext newTypePath = ctx.appendTypePath(typeRef);
+ if (cls == Object.class) {
+ // return false for typeToken that point to un-specialized generic type.
+ return false;
+ }
+ boolean maybe =
+ !SUPPORTED_TYPES.contains(typeRef)
+ && !typeRef.isArray()
+ && !cls.isEnum()
+ && !ITERABLE_TYPE.isSupertypeOf(typeRef)
+ && !MAP_TYPE.isSupertypeOf(typeRef);
+ if (maybe) {
+ for (Descriptor d : Descriptor.getDescriptors(cls)) {
+ TypeRef<?> t = d.getTypeRef();
+ // do field modifiers and getter/setter validation here, not in
getDescriptors.
+ // If Modifier.isFinal(d.getModifiers()), use reflection
+ // private field that doesn't have getter/setter will be handled by
reflection.
+ TypeRef<?> replacementType =
+ ctx.getCustomTypeRegistry().replacementTypeFor(cls,
t.getRawType());
+ if (replacementType != null) {
+ t = replacementType;
+ }
+ if (!isSupported(t, newTypePath)) {
+ return false;
}
- return true;
- } else {
- return false;
}
+ return true;
} else {
return false;
}
diff --git
a/java/fory-format/src/main/java/org/apache/fory/format/encoder/RowEncoderBuilder.java
b/java/fory-format/src/main/java/org/apache/fory/format/encoder/RowEncoderBuilder.java
index f8c16a38c..45f65fff9 100644
---
a/java/fory-format/src/main/java/org/apache/fory/format/encoder/RowEncoderBuilder.java
+++
b/java/fory-format/src/main/java/org/apache/fory/format/encoder/RowEncoderBuilder.java
@@ -184,7 +184,7 @@ public class RowEncoderBuilder extends
BaseBinaryEncoderBuilder {
@Override
public Expression buildEncodeExpression() {
Reference inputObject = new Reference(ROOT_OBJECT_NAME,
TypeUtils.OBJECT_TYPE, false);
- Expression bean = new Expression.Cast(inputObject, beanType,
ctx.newName(beanClass));
+ Expression bean = tryCastIfPublic(inputObject, beanType);
Reference writer = new Reference(ROOT_ROW_WRITER_NAME, rowWriterTypeToken,
false);
Reference schemaExpr = new Reference(SCHEMA_NAME, schemaTypeToken, false);
diff --git
a/java/fory-format/src/test/java/org/apache/fory/format/encoder/RowEncoderTest.java
b/java/fory-format/src/test/java/org/apache/fory/format/encoder/RowEncoderTest.java
index dd6832e9a..484296456 100644
---
a/java/fory-format/src/test/java/org/apache/fory/format/encoder/RowEncoderTest.java
+++
b/java/fory-format/src/test/java/org/apache/fory/format/encoder/RowEncoderTest.java
@@ -19,6 +19,7 @@
package org.apache.fory.format.encoder;
+import static org.apache.fory.collection.Collections.ofHashMap;
import static
org.apache.fory.format.encoder.CodecBuilderTest.testStreamingEncode;
import com.google.common.collect.ImmutableMap;
@@ -101,4 +102,20 @@ public class RowEncoderTest {
Foo deserializedFoo = encoder.fromRow(row);
Assert.assertEquals(foo, deserializedFoo);
}
+
+ private static class PrivateStruct {
+ java.util.Map<Long, Long> f1;
+ java.util.Map<String, String> f2;
+ }
+
+ @Test
+ public void testPrivateBean() {
+ RowEncoder<PrivateStruct> encoder = Encoders.bean(PrivateStruct.class);
+ PrivateStruct s = new PrivateStruct();
+ s.f1 = ofHashMap(10L, 100L);
+ s.f2 = ofHashMap("k", "v");
+ PrivateStruct s1 = encoder.decode(encoder.encode(s));
+ Assert.assertEquals(s1.f1, s.f1);
+ Assert.assertEquals(s1.f2, s.f2);
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]