Hi All,I created some case class and serialize it , everything is OK on Sun JDK but I got error on Android when there are more than two field with different type.
Caused by: java.lang.RuntimeException: Cannot automatically determine case class field names and order for 'com.lifecosys.toolkit.Color', please use the 'jsonFormat' overload with explicit field name specification
The problem is that we pair fields and copy method within ProductFormats.extractFieldNames, the copyDefaultMethods is sorted, but the fields is consistent with it, so the validation failed and throw error. Seems everything is OK after I override the extractFieldNames and comment the validation.One issue for this temporary patch is that the key order of generated json string is different with the case class constructor, but IMHO this is not a big issue.Generated json for case class Color(red: Int = 0, green: Float = 0, blue: Double = 0):{"blue": 0,"green": 0.0,"red": 0.0}Besides, I also checkout spray-json and comment the code, all test case is OK.Anyone has better solution for this issue?Below is the demo code:import spray.json._case class Location(x: Int = 0, y: Float = 0)
case class Color(red: Int = 0, green: Float = 0, blue: Double = 0)case class Distance(x1: Int = 0, y1: Float = 0, x2: Double = 0, y2: Int = 0)object TestJsonProtocol extends DefaultJsonProtocol {implicit val LocationJsonFormat = jsonFormat2(Location)implicit val ColorJsonFormat = jsonFormat3(Color)implicit val DistanceJsonFormat = jsonFormat4(Distance)override protected def extractFieldNames(classManifest: ClassManifest[_]): Array[String] = {val clazz = classManifest.erasuretry {// copy methods have the form copy$default$N(), we need to sort them in order, but must account for the fact// that lexical sorting of ...8(), ...9(), ...10() is not correct, so we extract N and sort by N.toIntval copyDefaultMethods = clazz.getMethods.filter(_.getName.startsWith("copy$default$")).sortBy(_.getName.drop("copy$default$".length).takeWhile(_ != '(').toInt)val fields = clazz.getDeclaredFields.filterNot(_.getName.startsWith("$"))if (copyDefaultMethods.length != fields.length)sys.error("Case class " + clazz.getName + " declares additional fields")//Comment type validation to avoid the error// if (fields.zip(copyDefaultMethods).exists { case (f, m) => f.getType != m.getReturnType })// sys.error("Cannot determine field order of case class " + clazz.getName)fields.map(_.getName)} catch {case ex => throw new RuntimeException("Cannot automatically determine case class field names and order " +"for '" + clazz.getName + "', please use the 'jsonFormat' overload with explicit field name specification", ex)}}}class BookReader extends Activity {override def onCreate(savedInstanceState: Bundle) {super.onCreate(savedInstanceState)import TestJsonProtocol._}}--Please be free to contact with me for any question or suggestion.
Thanks & Best Regards,
Young Gu | Software Engineer | www.infor.com
Sorry for late reply, the problem is that the order of the fields is not same as the copy default methods on Android, for example, the generated fields for class Color is blue, red, green, but it must be red, green ,blue t pass the validation.
Maybe we can try to use scala reflection to fix it.
--
You received this message because you are subscribed to the Google Groups "spray.io User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to spray-user+...@googlegroups.com.
Visit this group at https://groups.google.com/group/spray-user.
To view this discussion on the web visit https://groups.google.com/d/msgid/spray-user/b12783a0-e03a-4f91-872d-ff3dd969c437%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.