in java/fury-core/src/main/java/org/apache/fury/resolver/ClassResolver.java [908:1043]
public Class<? extends Serializer> getSerializerClass(Class<?> cls, boolean codegen) {
if (!cls.isEnum() && (ReflectionUtils.isAbstract(cls) || cls.isInterface())) {
throw new UnsupportedOperationException(
String.format("Class %s doesn't support serialization.", cls));
}
Class<? extends Serializer> serializerClass = getSerializerClassFromGraalvmRegistry(cls);
if (serializerClass != null) {
return serializerClass;
}
cls = TypeUtils.boxedType(cls);
ClassInfo classInfo = classInfoMap.get(cls);
if (classInfo != null && classInfo.serializer != null) {
// Note: need to check `classInfo.serializer != null`, because sometimes `cls` is already
// serialized, which will create a class info with serializer null, see `#writeClassInternal`
return classInfo.serializer.getClass();
} else {
if (getSerializerFactory() != null) {
Serializer serializer = getSerializerFactory().createSerializer(fury, cls);
if (serializer != null) {
return serializer.getClass();
}
}
if (NonexistentClass.isNonexistent(cls)) {
return NonexistentClassSerializers.getSerializer(fury, "Unknown", cls).getClass();
}
if (cls.isArray()) {
return ArraySerializers.ObjectArraySerializer.class;
} else if (cls.isEnum()) {
return EnumSerializer.class;
} else if (Enum.class.isAssignableFrom(cls) && cls != Enum.class) {
// handles an enum value that is an inner class. Eg: enum A {b{}};
return EnumSerializer.class;
} else if (EnumSet.class.isAssignableFrom(cls)) {
return CollectionSerializers.EnumSetSerializer.class;
} else if (Charset.class.isAssignableFrom(cls)) {
return Serializers.CharsetSerializer.class;
} else if (Functions.isLambda(cls)) {
return LambdaSerializer.class;
} else if (ReflectionUtils.isJdkProxy(cls)) {
if (JavaSerializer.getWriteReplaceMethod(cls) != null) {
return ReplaceResolveSerializer.class;
} else {
return JdkProxySerializer.class;
}
} else if (Calendar.class.isAssignableFrom(cls)) {
return TimeSerializers.CalendarSerializer.class;
} else if (ZoneId.class.isAssignableFrom(cls)) {
return TimeSerializers.ZoneIdSerializer.class;
} else if (TimeZone.class.isAssignableFrom(cls)) {
return TimeSerializers.TimeZoneSerializer.class;
} else if (ByteBuffer.class.isAssignableFrom(cls)) {
return BufferSerializers.ByteBufferSerializer.class;
}
if (shimDispatcher.contains(cls)) {
return shimDispatcher.getSerializer(cls).getClass();
}
if (fury.getConfig().checkJdkClassSerializable()) {
if (cls.getName().startsWith("java") && !(Serializable.class.isAssignableFrom(cls))) {
throw new UnsupportedOperationException(
String.format("Class %s doesn't support serialization.", cls));
}
}
if (fury.getConfig().isScalaOptimizationEnabled()
&& ReflectionUtils.isScalaSingletonObject(cls)) {
if (isCollection(cls)) {
return SingletonCollectionSerializer.class;
} else if (isMap(cls)) {
return SingletonMapSerializer.class;
} else {
return SingletonObjectSerializer.class;
}
}
if (isCollection(cls)) {
// Serializer of common collection such as ArrayList/LinkedList should be registered
// already.
serializerClass = ChildContainerSerializers.getCollectionSerializerClass(cls);
if (serializerClass != null) {
return serializerClass;
}
if (requireJavaSerialization(cls) || useReplaceResolveSerializer(cls)) {
return CollectionSerializers.JDKCompatibleCollectionSerializer.class;
}
if (fury.getLanguage() == Language.JAVA) {
return CollectionSerializers.DefaultJavaCollectionSerializer.class;
} else {
return CollectionSerializer.class;
}
} else if (isMap(cls)) {
// Serializer of common map such as HashMap/LinkedHashMap should be registered already.
serializerClass = ChildContainerSerializers.getMapSerializerClass(cls);
if (serializerClass != null) {
return serializerClass;
}
if (requireJavaSerialization(cls) || useReplaceResolveSerializer(cls)) {
return MapSerializers.JDKCompatibleMapSerializer.class;
}
if (fury.getLanguage() == Language.JAVA) {
return MapSerializers.DefaultJavaMapSerializer.class;
} else {
return MapSerializer.class;
}
}
if (fury.getLanguage() != Language.JAVA) {
LOG.warn("Class {} isn't supported for cross-language serialization.", cls);
}
if (useReplaceResolveSerializer(cls)) {
return ReplaceResolveSerializer.class;
}
if (Externalizable.class.isAssignableFrom(cls)) {
return ExternalizableSerializer.class;
}
if (requireJavaSerialization(cls)) {
return getJavaSerializer(cls);
}
Class<?> clz = cls;
return getObjectSerializerClass(
cls,
metaContextShareEnabled,
codegen,
new JITContext.SerializerJITCallback<Class<? extends Serializer>>() {
@Override
public void onSuccess(Class<? extends Serializer> result) {
setSerializer(clz, Serializers.newSerializer(fury, clz, result));
if (classInfoCache.cls == clz) {
classInfoCache = NIL_CLASS_INFO; // clear class info cache
}
Preconditions.checkState(getSerializer(clz).getClass() == result);
}
@Override
public Object id() {
return clz;
}
});
}
}