json4s
json4s copied to clipboard
Extraction.decompose fails on case class with secondary implicit arguments list : org.json4s.package$MappingException: Can't find constructor
json4s version
3.6.9
scala version
2.13.3
jdk version
11.0.7
Extraction.decompose successes with :
case class CheckedValue[NUM](
value: NUM,
isPrime: Boolean,
digitCount: Long,
nth: NUM)
Extraction.decompose fails with :
case class CheckedValue[NUM](
value: NUM,
isPrime: Boolean,
digitCount: Long,
nth: NUM)(implicit numops: Integral[NUM])
Raised exception :
- should be possible to serialize / deserialize complex types with implicits *** FAILED ***
org.json4s.package$MappingException: Can't find constructor for CheckedValue
at org.json4s.reflect.package$.fail(package.scala:95)
at org.json4s.reflect.ScalaSigReader$.$anonfun$readConstructor$3(ScalaSigReader.scala:26)
at scala.Option.getOrElse(Option.scala:201)
at org.json4s.reflect.ScalaSigReader$.readConstructor(ScalaSigReader.scala:26)
at org.json4s.reflect.Reflector$ClassDescriptorBuilder.ctorParamType(Reflector.scala:93)
at org.json4s.reflect.Reflector$ClassDescriptorBuilder.$anonfun$createConstructorDescriptors$7(Reflector.scala:182)
at scala.collection.immutable.ArraySeq.$anonfun$map$1(ArraySeq.scala:71)
at scala.collection.immutable.ArraySeq.$anonfun$map$1$adapted(ArraySeq.scala:71)
at scala.collection.immutable.ArraySeq$.tabulate(ArraySeq.scala:192)
at scala.collection.immutable.ArraySeq$.tabulate(ArraySeq.scala:171)
test snippet :
import org.json4s.native.Serialization.write
import org.json4s.DefaultFormats
import org.json4s.Extraction, Extraction.decompose
implicit val formats = DefaultFormats
val something1 = CheckedValue(value=7L, isPrime=true, digitCount=1, nth=4)
val jvalue = decompose(something1)
write(jvalue) shouldBe """{"value":7,"isPrime":true,"digitCount":1,"nth":4}"""
Json4s uses the old reflection features of pre-2.9 Scala and cannot distinguish between implicit parameters.
To do this, we need to replace the Json4s code base with the new reflection features introduced in Scala 2.10 and later, but this will require a complete rewrite of the code.
To do this, we need to replace the Json4s code base with the new reflection features introduced in Scala 2.10 and later
I don't think so
This used to work on 3.5.4 (maybe accidentally). I think it works on 3.5.5 but definitely broke on 3.6.0 (I didn't check the release cadidates). Is there going to be any progress on fixing it?
I'm seeing the same thing while trying to serialize Algebird's Moments class. I can reproduce the behavior with the following case class:
case class SimpleCaseClass(
x1: Long,
x2: Double,
x3: Double
)
object SimpleCaseClass {
def apply[V : Numeric](x1: Long, x2: V, x3: V)(implicit num: Numeric[V]): SimpleCaseClass = {
new SimpleCaseClass(x1, num.toDouble(x2), num.toDouble(x3))
}
}
The serialization succeeds with scala 2.11 and json4s 3.5.3, but breaks with scala 2.12. I haven't found a version of json4s for which this works while using scala 2.12.
This is a blocker as we are trying to migrate transmogrif.ai to scala 2.12 and we depend on both json4s and algebird.
I'm seeing the same thing while trying to serialize Algebird's Moments class. I can reproduce the behavior with the following case class:
case class SimpleCaseClass( x1: Long, x2: Double, x3: Double ) object SimpleCaseClass { def apply[V : Numeric](x1: Long, x2: V, x3: V)(implicit num: Numeric[V]): SimpleCaseClass = { new SimpleCaseClass(x1, num.toDouble(x2), num.toDouble(x3)) } }
The serialization succeeds with scala 2.11 and json4s 3.5.3, but breaks with scala 2.12. I haven't found a version of json4s for which this works while using scala 2.12.
This is a blocker as we are trying to migrate transmogrif.ai to scala 2.12 and we depend on both json4s and algebird.
When I ran into this issue I had to rename my apply
methods with implicit parameters to something else other than apply
. I would suggest trying that
I'm unfortunately not in control of this code, and we need to use a build that exists in the Maven repo. Getting Algebird to change their API might be even more difficult than fixing the issue in json4s.
Even assuming I have control of the source code, I can't be sure I've renamed apply
for all the relevant types (i.e. I'm not sure what types with problematic apply
s will get serialized). To be sure I'd have to rename all apply
methods, and that also means adding an explicit method call in all places where objects are created using those apply
methods.