Quy Tang Quy Tang - 1 month ago 17
Scala Question

json4s Serialize and deserialize generic type

Because I am dealing with generic type therefore I can't use specific case classes. Then I created a generic util which serializes and deserializes generic object.

import org.json4s
import org.json4s.Formats._
import org.json4s.native.JsonMethods._

object JsonHelper {
def json2Object[O](input: String) : O = {
parse(json4s.string2JsonInput(input)).asInstanceOf[O]
}
def object2Json[O](input: O) : String = {
write(input).toString
}
}


The compiler throws the error:


No JSON serializer found for type O. Try to implement an implicit Writer or JsonFormat for this type.
write(input).toString


This should be thrown at runtime but why it thrown at compile time?

Answer

In a comment above, you asked "So how jackson can work with java object? It use reflection right? And why it's different from Scala?", which gets to the heart of this question.

The json4s "native" serializer you have imported uses compile-time reflection to create the Writer.

Jackson uses run-time reflection to do the same.

The compile-time version is more efficient; the run-time version is more flexible.

To use the compile-time version, you need to let the compiler have enough information to choose the correct Writer based on the declared type of the object to be serialized. This will rule out very generic writer methods like the one you propose. See @TimP's answer for how to fix your code for that version.

To use the run-time version, you can use Jackson via the org.json4s.jackson.JsonMethods._ package. See https://github.com/json4s/json4s#jackson

Comments