Search code examples
javaserializationjmskryoserialversionuid

How to send Kryo serialized objects over JMS?


I would like to use Kryo to (de-)serialize objects and send/receive them via JMS.

The problem I'm having is that both sides, sender and receiver, must register the classes with the same ID.

Kryo has a method register (Class type, int id) that I use. Unfortunately id is an int (as compared to long serialVersionUID used by the Serializable interface). It would be nice if I could use serialVersionUID to register classes.

How do you guys use Kryo over the network?


Solution

  • You don't have to register explicitly every class you want to serialize with Kryo. The main benefit of registering classes are :

    • Performances : The first time Kryo see a class, it generates an ID and send this ID in the serialized stream with the name of the class. The next times, Kryo send only the ID, without the name. If the class is explicitly registered, the ID is already known, and Kryo never sends the name of the class : You gain some bytes in the output stream
    • Some "security": If you set the "registration required" flags, Kryo will not send class it didn't know about. You can then filters data you send over the network

    However, when you register a class, you must register exactly the same classes in the same order everywhere. It's not always possible.

    In your case, the JMS spec doesn't define anything about the serialization of the classes. It will depend on the implementation you use. If you want something portable, you can do this in the application layer :

    • Serialize your classes with Kryo to a byte array
    • Send this byte array over JMS with a BytesMessage
    • In your MessageListener deserialize the message with Kryo

    As you can control who serialize/deserialize, you can register the classes you use here, or just let Kryo generates itself the IDs

    ActiveMQ doesn't support a custom serialization hook. You can't plug your own implementation of serialization, and so can't tell to ActiveMQ to use Kryo when it send ObjectMessage (see ActiveMQObjectMessage). You must use this BytesMessage. Maybe others JMS providers provide such feature (JMS is just an API Spec, it doesn't define how messages should be sent/serialized, only the API accessible)