Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1028,6 +1028,12 @@ private TypeInfo getMetaSharedTypeInfo(TypeDef typeDef, Class<?> clz) {
if (clz.isArray() || cls.isEnum()) {
return getTypeInfo(cls);
}
if (ReflectionUtils.isAbstract(cls) || cls.isInterface()) {
// Compatible serializers allocate their root type during read. A meta-share TypeDef may name
// an abstract declared field type, but the actual value must be read through concrete runtime
// type metadata or a concrete target-class transformation.
return typeInfo;
}
Class<? extends Serializer> sc =
getCompatibleDeserializerClassFromGraalvmRegistry(cls, typeDef);
if (sc == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,18 @@
import org.apache.fory.ForyTestBase;
import org.apache.fory.context.MetaReadContext;
import org.apache.fory.context.MetaWriteContext;
import org.apache.fory.meta.TypeDef;
import org.apache.fory.test.bean.BeanA;
import org.apache.fory.test.bean.BeanB;
import org.apache.fory.test.bean.Foo;
import org.testng.Assert;
import org.testng.annotations.Test;

public class MetaShareContextTest extends ForyTestBase {
public interface InterfacePrice {
int cents();
}

@Test
public void testShareClassName() {
Fory fory =
Expand Down Expand Up @@ -66,6 +71,24 @@ public void testShareTypeDefCompatible(boolean enableCodegen) {
}
}

@Test(dataProvider = "enableCodegen")
public void testMetaSharedInterfaceDoesNotBuildInstantiatingSerializer(boolean enableCodegen) {
Fory fory =
Fory.builder()
.withXlang(false)
.withRefTracking(true)
.withMetaShare(true)
.withScopedMetaShare(false)
.withCompatible(true)
.withCodegen(enableCodegen)
.requireClassRegistration(false)
.build();
TypeResolver resolver = fory.getTypeResolver();
TypeDef typeDef = TypeDef.buildTypeDef(resolver, InterfacePrice.class);
TypeInfo typeInfo = resolver.buildMetaSharedTypeInfo(typeDef);
Assert.assertNull(typeInfo.getSerializer());
}

private void checkMetaShare(Fory fory, Object o) {
MetaWriteContext metaWriteContext = new MetaWriteContext();
MetaReadContext metaReadContext = new MetaReadContext();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,37 @@ public static Object serDeMetaShareCheck(Fory fory, Object obj) {
return newObj;
}

public interface Price {
int cents();
}

public static final class ImmutablePrice implements Price {
public int cents;

public ImmutablePrice() {}

public ImmutablePrice(int cents) {
this.cents = cents;
}

@Override
public int cents() {
return cents;
}
}

public static final class InterfaceFieldOrder {
public int id;
public Price price;

public InterfaceFieldOrder() {}

public InterfaceFieldOrder(int id, Price price) {
this.id = id;
this.price = price;
}
}

@DataProvider
public static Object[][] config1() {
return Sets.cartesianProduct(
Expand Down Expand Up @@ -121,6 +152,32 @@ public void testWrite(boolean referenceTracking, boolean compressNumber, boolean
serDeMetaShareCheck(fory, BeanA.createBeanA(2));
}

@Test(dataProvider = "enableCodegen")
public void testInterfaceFieldCompatibleMetaShare(boolean enableCodegen) {
Fory writer = foryBuilder().withRefTracking(true).withCodegen(enableCodegen).build();
Fory reader = foryBuilder().withRefTracking(true).withCodegen(enableCodegen).build();
InterfaceFieldOrder order = new InterfaceFieldOrder(1, new ImmutablePrice(100));
MetaWriteContext metaWriteContext = new MetaWriteContext();
MetaReadContext metaReadContext = new MetaReadContext();
setMetaContexts(writer, metaWriteContext, new MetaReadContext());
byte[] bytes = writer.serialize(order);
setMetaContexts(reader, new MetaWriteContext(), metaReadContext);
Object newOrder = reader.deserialize(bytes);
assertInterfaceFieldOrder(newOrder);
reader.ensureSerializersCompiled();
setMetaContexts(writer, metaWriteContext, new MetaReadContext());
bytes = writer.serialize(order);
setMetaContexts(reader, new MetaWriteContext(), metaReadContext);
newOrder = reader.deserialize(bytes);
assertInterfaceFieldOrder(newOrder);
}

private static void assertInterfaceFieldOrder(Object newOrder) {
Assert.assertEquals(((InterfaceFieldOrder) newOrder).id, 1);
Assert.assertEquals(((InterfaceFieldOrder) newOrder).price.getClass(), ImmutablePrice.class);
Assert.assertEquals(((InterfaceFieldOrder) newOrder).price.cents(), 100);
}

@Test(dataProvider = "config2")
public void testWriteCompatibleBasic(
boolean referenceTracking,
Expand Down
Loading