arangodb / java-velocypack-module-scala

Apache License 2.0
6 stars 3 forks source link

StackOverflowError when serializing Scala enum #13

Open wajda opened 4 years ago

wajda commented 4 years ago
object TestEnum extends Enumeration {
  type TestEnum = Value
  val Foo: TestEnum = Value("foo")
  val Bar: TestEnum = Value("bar")
}

new VPack.Builder()
  .registerModule(new VPackScalaModule)
  .build()
  .serialize(TestEnum.Foo)

produces

java.lang.StackOverflowError
    at java.util.ArrayList.grow(ArrayList.java:260)
    at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:241)
    at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:233)
    at java.util.ArrayList.add(ArrayList.java:464)
    at com.arangodb.velocypack.VPackBuilder.reportAdd(VPackBuilder.java:872)
    at com.arangodb.velocypack.VPackBuilder.addInternal(VPackBuilder.java:647)
    at com.arangodb.velocypack.VPackBuilder.addInternal(VPackBuilder.java:632)
    at com.arangodb.velocypack.VPackBuilder.add(VPackBuilder.java:413)
    at com.arangodb.velocypack.internal.VPackSerializers$1.serialize(VPackSerializers.java:55)
    at com.arangodb.velocypack.internal.VPackSerializers$1.serialize(VPackSerializers.java:48)
    at com.arangodb.velocypack.VPack.addValue(VPack.java:858)
    at com.arangodb.velocypack.VPack.serializeField(VPack.java:839)
    at com.arangodb.velocypack.VPack.serializeFields(VPack.java:816)
    at com.arangodb.velocypack.VPack.serializeObject(VPack.java:803)
    at com.arangodb.velocypack.VPack.addValue(VPack.java:882)
    at com.arangodb.velocypack.VPack.addValue(VPack.java:879)
    at com.arangodb.velocypack.VPack.serializeField(VPack.java:839)
    at com.arangodb.velocypack.VPack.serializeFields(VPack.java:816)
    at com.arangodb.velocypack.VPack.serializeObject(VPack.java:803)
    at com.arangodb.velocypack.VPack.addValue(VPack.java:882)
    at com.arangodb.velocypack.VPack.addValue(VPack.java:879)
    at com.arangodb.velocypack.VPack.serializeField(VPack.java:839)
    at com.arangodb.velocypack.VPack.serializeFields(VPack.java:816)
    at com.arangodb.velocypack.VPack.serializeObject(VPack.java:803)
    at com.arangodb.velocypack.VPack.addValue(VPack.java:882)
    at com.arangodb.velocypack.VPack.addValue(VPack.java:879)
    at com.arangodb.velocypack.VPack.serializeField(VPack.java:839)
    at com.arangodb.velocypack.VPack.serializeFields(VPack.java:816)
    at com.arangodb.velocypack.VPack.serializeObject(VPack.java:803)
    at com.arangodb.velocypack.VPack.addValue(VPack.java:882)
    at com.arangodb.velocypack.VPack.addValue(VPack.java:879)
    at com.arangodb.velocypack.VPack.serializeField(VPack.java:839)
    at com.arangodb.velocypack.VPack.serializeFields(VPack.java:816)
    at com.arangodb.velocypack.VPack.serializeObject(VPack.java:803)
    at com.arangodb.velocypack.VPack.addValue(VPack.java:882)
    at com.arangodb.velocypack.VPack.addValue(VPack.java:879)
    at com.arangodb.velocypack.VPack.serializeField(VPack.java:839)
    at com.arangodb.velocypack.VPack.serializeFields(VPack.java:816)
    at com.arangodb.velocypack.VPack.serializeObject(VPack.java:803)
    at com.arangodb.velocypack.VPack.addValue(VPack.java:882)
        ...
rashtao commented 4 years ago

Thanks for reporting this issue! Serializing and deserializing scala enums is not trivial to implement, here you can find some details: https://github.com/FasterXML/jackson-module-scala/wiki/Enumerations

As a temporary workaround I would suggest you using:

rashtao commented 4 years ago

Alternatively, you can use jackson-dataformat-velocypack in combination with jackson-module-scala. It (partially) supports scala enumeration mapping, as documented here: https://github.com/FasterXML/jackson-module-scala/wiki/Enumerations

Eg. something like this:

import com.arangodb.jackson.dataformat.velocypack.VPackMapper
import com.fasterxml.jackson.core.`type`.TypeReference
import com.fasterxml.jackson.module.scala.{DefaultScalaModule, JsonScalaEnumeration}

object Weekday extends Enumeration {
  type Weekday = Value
  val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value
}

class WeekdayType extends TypeReference[Weekday.type]

case class WeekdayHolder(@JsonScalaEnumeration(classOf[WeekdayType]) weekday: Weekday.Weekday)

object HelloWorld {

  def main(args: Array[String]): Unit = {
    val obj = WeekdayHolder(Weekday.Fri)
    val mapper = new VPackMapper().registerModule(DefaultScalaModule)
    val bytes = mapper.writeValueAsBytes(obj)
    val decodedBytes: WeekdayHolder = mapper.readValue(bytes, classOf[WeekdayHolder])
    assert(decodedBytes.weekday == Weekday.Fri)
  }

}
wajda commented 4 years ago

thanks, will take look.