Code Monkey home page Code Monkey logo

Comments (7)

bwzhang2011 avatar bwzhang2011 commented on September 15, 2024

@andot, if you have spare time, please share your idea to solve that. for my side to make it run, I just use kryo to serialize it to byte[] to make it run, but it's not the direct one. I hope some place could register the special serializer towards self-defined object.

from hprose-java.

andot avatar andot commented on September 15, 2024

Which fields or properties do you want to serialize?

If you want to serialize fields, the field must be public or set the HproseMode to FieldMode, in FieldMode, the private and protected field also can be serialized. but I found you have a Class<?> field, this type can't be serialized, because Class<?> can't be mapped to other languages.

If you want to serialize properties, the property must be public and have setter and getter method. I found your Class only have some readonly properties(only have getter).

So your Class can't be serialized as you wanted.

The easy way to enable serialize is that, add:

    void setIdentifier(String value);
    void setMetaData(MetaData value);
    void setPayload(T value);

to ITransferMsg<T> interface. and implements it in GenericTransferMsg<T>.

public interface ITransferMsg<T> extends java.io.Serializable {
    String getIdentifier();

    MetaData getMetaData();

    T getPayload();

    Class<?> getPayloadType();

    void setIdentifier(String value);

    void setMetaData(MetaData value);

    void setPayload(T value);

    ITransferMsg<T> withMetaData(Map<String, Object> metaData);

    ITransferMsg<T> andMetaData(Map<String, Object> metaData);

    Map<String,Object> getMetaValue();
}
public class GenericTransferMsg<T> implements ITransferMsg<T> {
    private static final long serialVersionUID = -2860606356253432506L;
    private String identifier;
    private MetaData metaData;
    private Class<?> payloadType;
    private T payload;

    // for kryo default constructor is needed
    public GenericTransferMsg() {
        identifier = null;
        metaData = MetaData.emptyInstance();
        payload = null;
        payloadType = Void.TYPE;
    }

    /**
     * Constructs a Message for the given 
     * <code>payload</code> using empty metadata.
     * 
     * @param payload The payload for the message
     */
    public GenericTransferMsg(T payload) {
        this(payload, MetaData.emptyValues());
    }

    /**
     * Constructs a Message for the given 
     * <code>payload</code> and <code>meta data</code>.
     * 
     * @param payload The payload for the message
     * @param metaData The meta data for the message
     */
    public GenericTransferMsg(T payload, Map<String, Object> metaData) {
        this(UUIDHelper.random().toString(), payload, metaData);
    }

    /**
     * @param payload
     * @param metData
     */
    public GenericTransferMsg(T payload, MetaData metData) {
        this(UUIDHelper.random().toString(), payload, metData);
    }

    /**
     * Constructor to reconstruct a Message using existing data.
     * 
     * @param identifier The identifier of the Message
     * @param payload The payload of the message
     * @param metaData The meta data of the message
     */
    public GenericTransferMsg(String identifier, T payload, Map<String, Object> metaData) {
        this(identifier, payload, MetaData.from(metaData));
    }

    /**
     * Constructor to reconstruct a Message using existing data.
     * 
     * @param identifier The identifier of the Message
     * @param payload The payload of the message
     * @param metaData The meta data of the message
     */
    public GenericTransferMsg(String identifier, T payload, MetaData metaData) {
        this.identifier = identifier;
        this.metaData = metaData;
        this.payload = payload;
        this.payloadType = payload.getClass();
    }

    protected GenericTransferMsg(GenericTransferMsg<T> original, Map<String, Object> metaData) {
        this(original, MetaData.from(metaData));
    }

    protected GenericTransferMsg(GenericTransferMsg<T> original, MetaData metaData) {
        this.identifier = original.getIdentifier();
        this.payload = original.getPayload();
        this.payloadType = payload.getClass();
        this.metaData = metaData;
    }

    @Override
    public String getIdentifier() {
        return identifier;
    }

    @Override
    public MetaData getMetaData() {
        return metaData;
    }

    @Override
    public T getPayload() {
        return payload;
    }

    @Override
    public Class<?> getPayloadType() {
        return payloadType;
    }

    @Override
    public void setIdentifier(String value) {
        identifier = value;
    }

    @Override
    public void setMetaData(MetaData value) {
        metaData = value;
    }

    @Override
    public void setPayload(T value) {
        payload = value;
        payloadType = payload.getClass();
    }

    @Override
    public GenericTransferMsg<T> withMetaData(Map<String, Object> newMetaData) {
        return this.metaData.getValues().equals(newMetaData) ? this : new GenericTransferMsg<T>(this, newMetaData);
    }

    @Override
    public GenericTransferMsg<T> andMetaData(Map<String, Object> additionalMetaData) {
        return additionalMetaData.isEmpty() ? this : new GenericTransferMsg<T>(this, this.metaData.mergedWith(additionalMetaData));
    }

    @Override
    public Map<String, Object> getMetaValue() {
        return this.metaData.getValues();
    }


}

BTW, the MetaData type must be defined like this, too.

from hprose-java.

andot avatar andot commented on September 15, 2024

There's another point to pay attention is that, the interface type can't be used as the return type in client, and can't be used as the parameter type in service method. because unserialize an object need a type which can be instantiated, but the interface type can't be instantiated.

from hprose-java.

bwzhang2011 avatar bwzhang2011 commented on September 15, 2024

@andot, it was just for remote calling not for return type in client, maybe the method like this
boolean transfer(GenericTransferMsg transferMsg). but I tried it with kryo and it was ok for serialize and deserialize for the msg.

from hprose-java.

andot avatar andot commented on September 15, 2024

Kryo is designed for Java only, it does not consider cross language, so it can serialize Class<?> type field. although later there are some other language implementations from the third party, but they have some functional limitation or another JVM language.

Hprose is designed for cross language, so the transfer data should be converted between the different languages. You don't need to change more things, only need to add the setters for the serializable properties.

    void setIdentifier(String value);
    void setMetaData(MetaData value);
    void setPayload(T value);

from hprose-java.

andot avatar andot commented on September 15, 2024

If you don't want to add setters, and you only need to use this Type data in client parameters (If you also use it in server, setter definition is better). You can add transient keyword to payloadType field:

public class GenericTransferMsg<T> implements ITransferMsg<T> {
    private static final long serialVersionUID = -2860606356253432506L;
    private final String identifier;
    private final MetaData metaData;
    private final transient Class<?> payloadType;
    private final T payload;
...
}

because hprose do not serialize transient field like Java.

Then you can define the calling interface like this:

public interface MyRemoteCall {

    boolean transfer(ITransferMsg transferMsg);
}

and create client like this:

HproseClient client = HproseClient.create(uri, HproseMode.FieldMode);
MyRemoteCall rc = client.useService(MyRemoteCall.class);
...

you should create HproseClient with HproseMode.FieldMode, only in this mode, the private fields can be serialized.

from hprose-java.

bwzhang2011 avatar bwzhang2011 commented on September 15, 2024

thanks. I will have a try and it works and now I decided to give up the interface way for transferMsg itself better not bring in the interface. thanks a lot.

from hprose-java.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.