I'm using Kryo, and that's working reasonably well so far, but it's not trivial to set up. As I have time, I'm gradually
writing that up, but it's only half-done. Happy to answer questions if you want to explore that route.
My general impression is that protobuf is the well-established route, and the one that most people are using, but that does involve some duplication of information. (Or generating the case classes from the protobuf IDL.) I don't much care for that, which is why I went for Kryo; the end result is broadly similar in terms of the amount of effort, I believe, but with the serialization information encoded directly into the classes themselves.