fury icon indicating copy to clipboard operation
fury copied to clipboard

[Java] Custom Serializer for fields

Open miladamery opened this issue 1 year ago • 5 comments

Hi. When using Akka toolkit you need to serialize objects for persistence and clustering. Akka gives you the option for providing your own serializer. The problem is, in akka you have something called ActorRef. this class is used for replying to actors that send commands. but this ActorRef serialization/deserialization is special in Akka. Here describes how you can serizlize/deserialize ActorRef. Fury provides custom serializers for whole class according to here. Here is my implementation for serializing ActorRef (I appreciate it if some one can say if this is correct)

import akka.actor.typed.ActorRef;
import akka.actor.typed.ActorRefResolver;
import org.apache.fury.Fury;
import org.apache.fury.memory.MemoryBuffer;
import org.apache.fury.serializer.Serializer;

public class FuryActorRefSerializer extends Serializer<ActorRef> {

    private final ActorRefResolver actorRefResolver;

    public FuryActorRefSerializer(Fury fury, ActorRefResolver actorRefResolver) {
        super(fury, ActorRef.class);
        this.actorRefResolver = actorRefResolver;
    }

    @Override
    public void write(MemoryBuffer buffer, ActorRef value) {
       // toSerializationFormat returns String
        var serialized = actorRefResolver.toSerializationFormat(value).getBytes();
        buffer.writeInt32(serialized.length);
        buffer.writeBytes(serialized);
    }

    @Override
    public ActorRef read(MemoryBuffer buffer) {
        var length = buffer.readInt32();
        var ref = buffer.readBytes(length);
        return actorRefResolver.resolveActorRef(new String(ref));
    }
}

but this ActorRef discussed earlier is usually used as a field in commands(which are Java Records) not as a standalone class. Because creating a custom serializer for each Record of my project is not logical Is there a way that Fury support this? I mean writing a serializer like above and fury understands class field it is serializing and use appropriate serializer for that field?

miladamery avatar Aug 16 '24 19:08 miladamery

Hi @miladamery , you are right. If you register a serializer for a type, the serialization for fields of this type will use this serializer too

chaokunyang avatar Aug 17 '24 02:08 chaokunyang

@chaokunyang Thanks for your reply, i really appreciate it. The serializer mentioned in issue didn't work so I though problem is that fury doesn't respect custom serializers for fields which was wrong. By debugging I found what the problem was. ActorRef is an interface not the implementation, on serializing/deserializing fury was checking the actual implementation type which was ActorRefAdapter and was choosing the general serializer for ActorRefAdapter not the custom one provided. So i changed FuryActorRefSerializer type from ActorRef to ActorRefAdapter and everything works now. But my question is shouldn't fury pick the custom serializer for interface and its implementations?

miladamery avatar Aug 18 '24 08:08 miladamery

Hi @miladamery , Fury should pick customized serializer for interface. It should get serializer for concrete type first. If It doesn't exist, it should pick serializer for its inferface. Would you like to contribute this feature?

chaokunyang avatar Aug 18 '24 10:08 chaokunyang

@chaokunyang Hi, I will try to see if i can do it

miladamery avatar Aug 21 '24 10:08 miladamery

Hi @miladamery , the serializer dispatch For interface has been supportted since 0.11.0. Could you try 0.12.1 out you zee whether it works for you?

chaokunyang avatar Sep 05 '25 05:09 chaokunyang