From bedcaabbcee6212e6dfb664b899096d97ecd9daa Mon Sep 17 00:00:00 2001 From: chaokunyang Date: Fri, 3 May 2024 13:49:20 +0800 Subject: [PATCH] fix get classdef thread safety --- .../apache/fury/builder/BaseObjectCodecBuilder.java | 11 ++++------- .../apache/fury/builder/CompatibleCodecBuilder.java | 9 ++------- .../org/apache/fury/builder/ObjectCodecBuilder.java | 9 ++++++--- .../src/main/java/org/apache/fury/meta/ClassDef.java | 8 ++++++++ .../java/org/apache/fury/resolver/ClassResolver.java | 2 +- .../apache/fury/serializer/MetaSharedSerializer.java | 9 --------- 6 files changed, 21 insertions(+), 27 deletions(-) diff --git a/java/fury-core/src/main/java/org/apache/fury/builder/BaseObjectCodecBuilder.java b/java/fury-core/src/main/java/org/apache/fury/builder/BaseObjectCodecBuilder.java index d0112d0c5a..4dd315d2c6 100644 --- a/java/fury-core/src/main/java/org/apache/fury/builder/BaseObjectCodecBuilder.java +++ b/java/fury-core/src/main/java/org/apache/fury/builder/BaseObjectCodecBuilder.java @@ -189,7 +189,7 @@ public String codecQualifiedClassName(Class beanClass) { protected abstract String codecSuffix(); - T visitFury(Function function) { + protected T visitFury(Function function) { return fury.getJITContext().asyncVisitFury(function); } @@ -441,8 +441,7 @@ protected Expression writeForNotNullNonFinalObject( classInfo, inlineInvoke(classResolverRef, "getClassInfo", classInfoTypeRef, clsExpr)))); } - writeClassAndObject.add( - fury.getClassResolver().writeClassExpr(classResolverRef, buffer, classInfo)); + writeClassAndObject.add(classResolver.writeClassExpr(classResolverRef, buffer, classInfo)); writeClassAndObject.add( new Invoke( inlineInvoke(classInfo, "getSerializer", SERIALIZER_TYPE), @@ -659,8 +658,7 @@ protected Expression serializeForCollection( new Assign( classInfo, inlineInvoke(classResolverRef, "getClassInfo", classInfoTypeRef, clsExpr)))); - writeClassAction.add( - fury.getClassResolver().writeClassExpr(classResolverRef, buffer, classInfo)); + writeClassAction.add(classResolver.writeClassExpr(classResolverRef, buffer, classInfo)); serializer = new Invoke(classInfo, "getSerializer", "serializer", SERIALIZER_TYPE, false); serializer = new Cast(serializer, TypeRef.of(AbstractCollectionSerializer.class)); writeClassAction.add(serializer, new Return(serializer)); @@ -965,8 +963,7 @@ protected Expression serializeForMap( classInfo, inlineInvoke(classResolverRef, "getClassInfo", classInfoTypeRef, clsExpr)))); // Note: writeClassExpr is thread safe. - writeClassAction.add( - fury.getClassResolver().writeClassExpr(classResolverRef, buffer, classInfo)); + writeClassAction.add(classResolver.writeClassExpr(classResolverRef, buffer, classInfo)); serializer = new Invoke(classInfo, "getSerializer", "serializer", SERIALIZER_TYPE, false); serializer = new Cast(serializer, TypeRef.of(AbstractMapSerializer.class)); writeClassAction.add(serializer, new Return(serializer)); diff --git a/java/fury-core/src/main/java/org/apache/fury/builder/CompatibleCodecBuilder.java b/java/fury-core/src/main/java/org/apache/fury/builder/CompatibleCodecBuilder.java index 445a425e80..92c79527e4 100644 --- a/java/fury-core/src/main/java/org/apache/fury/builder/CompatibleCodecBuilder.java +++ b/java/fury-core/src/main/java/org/apache/fury/builder/CompatibleCodecBuilder.java @@ -41,7 +41,6 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; import org.apache.fury.Fury; import org.apache.fury.builder.Generated.GeneratedCompatibleSerializer; import org.apache.fury.codegen.CodegenContext; @@ -97,10 +96,6 @@ public CompatibleCodecBuilder( super(beanType, fury, superSerializerClass); this.fieldResolver = fieldResolver; if (isRecord) { - List fieldNames = - fieldResolver.getAllFieldsList().stream() - .map(FieldResolver.FieldInfo::getName) - .collect(Collectors.toList()); recordReversedMapping = RecordUtils.buildFieldToComponentMapping(beanClass); } ctx.reserveName(FIELD_RESOLVER_NAME); @@ -879,7 +874,7 @@ protected Expression writeFinalClassInfo(Expression buffer, Class cls) { Preconditions.checkArgument(ReflectionUtils.isMonomorphic(cls)); ClassInfo classInfo = visitFury(f -> f.getClassResolver().getClassInfo(cls, false)); if (classInfo != null && classInfo.getClassId() != ClassResolver.NO_CLASS_ID) { - return fury.getClassResolver().writeClassExpr(buffer, classInfo.getClassId()); + return classResolver.writeClassExpr(buffer, classInfo.getClassId()); } Expression classInfoExpr = getFinalClassInfo(cls); return new Invoke(classResolverRef, "writeClass", buffer, classInfoExpr); @@ -889,7 +884,7 @@ protected Expression skipFinalClassInfo(Class cls, Expression buffer) { Preconditions.checkArgument(ReflectionUtils.isMonomorphic(cls)); ClassInfo classInfo = visitFury(f -> f.getClassResolver().getClassInfo(cls, false)); if (classInfo != null && classInfo.getClassId() != ClassResolver.NO_CLASS_ID) { - return fury.getClassResolver().skipRegisteredClassExpr(buffer); + return classResolver.skipRegisteredClassExpr(buffer); } // read `ClassInfo` is not used, set `inlineReadClassInfo` false, // to avoid read doesn't happen in generated code. diff --git a/java/fury-core/src/main/java/org/apache/fury/builder/ObjectCodecBuilder.java b/java/fury-core/src/main/java/org/apache/fury/builder/ObjectCodecBuilder.java index dede004386..2e2df420cb 100644 --- a/java/fury-core/src/main/java/org/apache/fury/builder/ObjectCodecBuilder.java +++ b/java/fury-core/src/main/java/org/apache/fury/builder/ObjectCodecBuilder.java @@ -56,7 +56,6 @@ import org.apache.fury.codegen.Expression.StaticInvoke; import org.apache.fury.codegen.ExpressionVisitor; import org.apache.fury.memory.Platform; -import org.apache.fury.meta.ClassDef; import org.apache.fury.reflect.TypeRef; import org.apache.fury.serializer.ObjectSerializer; import org.apache.fury.serializer.PrimitiveSerializers.LongSerializer; @@ -91,8 +90,12 @@ public ObjectCodecBuilder(Class beanClass, Fury fury) { Collection descriptors; boolean shareMeta = fury.getConfig().shareMetaContext(); if (shareMeta) { - ClassDef classDef = classResolver.getClassDef(beanClass, true); - descriptors = classDef.getDescriptors(classResolver, beanClass); + descriptors = + visitFury( + f -> + f.getClassResolver() + .getClassDef(beanClass, true) + .getDescriptors(classResolver, beanClass)); } else { descriptors = fury.getClassResolver().getAllDescriptorsMap(beanClass, true).values(); } diff --git a/java/fury-core/src/main/java/org/apache/fury/meta/ClassDef.java b/java/fury-core/src/main/java/org/apache/fury/meta/ClassDef.java index 53e73844a5..24897ae1d0 100644 --- a/java/fury-core/src/main/java/org/apache/fury/meta/ClassDef.java +++ b/java/fury-core/src/main/java/org/apache/fury/meta/ClassDef.java @@ -203,6 +203,14 @@ public static ClassDef readClassDef( return ClassDefDecoder.decodeClassDef(classResolver, buffer, header); } + /** + * Consolidate fields of classDef with cls. If some field exists in + * cls but not in classDef, it won't be returned in final collection. If + * some field exists in classDef but not in cls, it will be added to + * final collection. + * + * @param cls class load in current process. + */ public List getDescriptors(ClassResolver resolver, Class cls) { if (descriptors == null) { SortedMap allDescriptorsMap = resolver.getAllDescriptorsMap(cls, true); diff --git a/java/fury-core/src/main/java/org/apache/fury/resolver/ClassResolver.java b/java/fury-core/src/main/java/org/apache/fury/resolver/ClassResolver.java index e44af81090..7e45b1a0b3 100644 --- a/java/fury-core/src/main/java/org/apache/fury/resolver/ClassResolver.java +++ b/java/fury-core/src/main/java/org/apache/fury/resolver/ClassResolver.java @@ -510,7 +510,7 @@ public List> getRegisteredClasses() { /** * Mark non-inner registered final types as non-final to write class def for those types. Note if * a class is registered but not an inner class with inner serializer, it will still be taken as - * non-final to write class def, so that it can be deserialized by the peer still.. + * non-final to write class def, so that it can be deserialized by the peer still. */ public boolean isMonomorphic(Class clz) { if (fury.getConfig().shareMetaContext()) { diff --git a/java/fury-core/src/main/java/org/apache/fury/serializer/MetaSharedSerializer.java b/java/fury-core/src/main/java/org/apache/fury/serializer/MetaSharedSerializer.java index 87f1a91b61..6d2c38c6c1 100644 --- a/java/fury-core/src/main/java/org/apache/fury/serializer/MetaSharedSerializer.java +++ b/java/fury-core/src/main/java/org/apache/fury/serializer/MetaSharedSerializer.java @@ -287,15 +287,6 @@ static boolean skipPrimitiveFieldValueFailed(Fury fury, short classId, MemoryBuf } } - /** - * Consolidate fields of classDef with cls. If some field exists in - * cls but not in classDef, it won't be returned in final collection. If - * some field exists in classDef but not in cls, it will be added to - * final collection. - * - * @param cls class load in current process. - * @param classDef class definition sent from peer. - */ public static Collection consolidateFields( ClassResolver classResolver, Class cls, ClassDef classDef) { return classDef.getDescriptors(classResolver, cls);