How to serialize JSON document using Messagepack (Cannot find template for class java.lang.Object)?

5k views Asked by At

I am planning to use Messagepack in our project. Currently, we are using JSON in our project and we are writing serialize JSON document into Cassandra. Now we are thinking to use Messagepack which is an efficient binary serialization format.

I am trying to find a good example which shows me to use Messagepack on JSON document but I am not able to find it yet.

Below is my main class code which will use Value class to make a JSON document using Jackson and then serialize the JSON using ObjectMapper.

public static void main(String[] args) {

    Map<String, Object> properties = new HashMap<String, Object>();
    properties.put("id", 123);
    properties.put("test", 200);
    properties.put("marks", 100);

    Value val = new Value();
    val.setProperties(properties);

    MessagePack msgpack = new MessagePack();
    // Serialize
    byte[] raw = msgpack.write(av);

    System.out.println(raw);

            // deserialize
    Value actual = new MessagePack().read(raw, Value.class);

    System.out.println(actual);
}

Below is my Value class which is using Jackson to make a JSON document and will use ObjectMapper to serialize the document and also using Messagepack.

@JsonPropertyOrder(value = { "v" })
@Message
public class Value {

    private Map<String, Object> properties;

    /**
     * Default constructor.
     */
    @JsonCreator
    public Value() {
        properties = new HashMap<String, Object>();
    }


    /**
     * Gets the properties of this attribute value.
     * @return the properties of this attribute value.
     */
    @JsonProperty("v")
    public Map<String, Object> getProperties() {
        return properties;
    }

    /**
     * Sets the properties of this attribute value.
     * @param v the properties of this attribute value to set
     */
    @JsonProperty("v")
    public void setProperties(Map<String, Object> v) {
        properties = v;
    }


    @Override
    public String toString() {
        try {
            return new ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(this);
        } catch (Exception e) {
            // log exception
        }

        return ToStringBuilder.reflectionToString(this);
    }    
}

But, I am not sure how to use Messagepack on this JSON document? Can anyone give me some example on this?

But I thought, let's give a try on this and whenever I am trying to use Messagepack like this in my above code-

    MessagePack msgpack = new MessagePack();
    // Serialize
    byte[] raw = msgpack.write(av);

I always get an exception like below-

Exception in thread "main" org.msgpack.MessageTypeException: Cannot find template for class java.lang.Object class.  Try to add @Message annotation to the class or call MessagePack.register(Type).

And I believe MessagePack doesn't allow users to serialize variables of java.lang.Object type but in my case, it is not possible to replace the type of properties to some primitive types.

I am using Object in my HashMap and I need it to be like that..

1

There are 1 answers

2
StaxMan On BEST ANSWER

Instead of trying MessagePack, have you considered using Smile, which is efficient, 100% JSON API compatible binary data format. It should match or exceed MessagePack speed, and produce slightly more compact output. Jackson has implementation at:

https://github.com/FasterXML/jackson-dataformat-smile

which will "just work" with object format. So instead of:

String json = new ObjectMapper().writeValueAsString(value);

you would use

byte[] smileEncoded = new ObjectMapper(new SmileFactory()).writeValueAsBytes(value);

All Jackson code works similar to JSON, including JAX-RS providers, datatypes (Guava, Joda, Hibernate etc etc) and such. So you don't lose convenience of JSON (except like all binary formats, Smile is not as readable as JSON), but gain storage and performance efficiency.