Trying to find the right software library is always an interesting problem. Sometimes there are only a few choices, and your constraints dictate what you use, but this week I was looking for a library to solve a rather common problem. With so many options, I had to research and prototype with a few of the more promising ones and see how they play out. It’s fun to compare the different approaches and find the right tool for the job.
My primary goals were:
- To serialize existing data objects in my Scala program
- Into a text-based format (JSON or XML) for easier debugging; size and speed were not an issue
- With a minimum amount of pain and effort; I don’t need much control over the format
I started with some simple web searching and reading other people’s comparisons of the libraries. I found several promising options, focusing first on JSON because it’s the slimmer and hipper format. I spent quite a bit of time on lift-json because it seemed to be a mature and popular Scala option, and it handled some simple cases rather nicely. Unfortunately, it choked on several use cases in my program. For one thing, it requires Maps to have String keys. I found a supposed workaround that only handled serializing and not deserializing. This wasn’t the last time I had trouble round-tripping data in one of these libraries. It also struggled with complex case classes, even though it advertised support for case classes, regardless of how I configured it. And it had some Twilight Zone caching problems in sbt. So I also tried jackson and Google’s gson. Again, they seemed to work in simple cases, but as soon as I threw a “complex” case class composed of other case classes and maps at them, they couldn’t serialize and then deserialize.
Finally I landed on XStream, a mature Java library for serializing any Java object to XML and back. Thank goodness Scala lives in the Java universe. Despite the intricacies of Scala, XStream had no trouble sending an object to XML and back with a single line of code and no configuration. The resulting XML is slightly more ugly than XML normally is, but as you see from my goals listed above, I don’t really care. Even so, it’s not too difficult to add in some extensions similar to mixedbits-webframework and get cleaner XML.
Sometimes an older solution works perfectly well. I wanted to believe in the JSON libraries, but they weren’t quite up to the task. I was particularly annoyed to keep running across surprising API limitations; personally I think any exception to an advertised function should be clearly documented, as XStream does. If you say you support case classes and maps, either support them 100% or precisely specify which kinds you don’t support. Don’t make me install the library and play around with it to learn the truth; it breaks my trust in the software. XStream was a delightful contrast. It just worked out-of-the-box, even for complex cases. And if my needs were more complex, I now trust XStream enough to invest the time to learn its API and write extensions.