简体   繁体   English

Jackson Scala模块:序列化枚举失败

[英]Jackson scala module: serialize Enumeration fails

Can someone explain me why this doesn't work? 有人可以解释一下为什么这行不通吗? I use the Scala module with Jackson. 我在Jackson上使用Scala模块。

My dependency is "com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.1.3" 我的依赖项是"com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.1.3"

My serializer is: 我的序列化器是:

import org.bson.types.ObjectId
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.module.scala.DefaultScalaModule

object CustomSerializer {

  val objectMapper = new ObjectMapper()

  val module = new SimpleModule("CustomSerializer")
  module.addSerializer(classOf[Throwable], new ThrowableSerializer)
  module.addSerializer(classOf[ObjectId], new ObjectIdSerializer)
  module.addDeserializer(classOf[ObjectId], new ObjectIdDeserializer)
  val scalaModule = DefaultScalaModule

  objectMapper.registerModule(scalaModule)
  objectMapper.registerModule(module)

  def serialize(obj: AnyRef): String = {
    objectMapper.writeValueAsString(obj)
  }

}

Nothing really fancy, I just add the Scala module to the default serializer + some serializers for MongoDB ObjectId class. 没什么好看的,我只是将Scala模块添加到默认的序列化器+一些MongoDB ObjectId类的序列化器。


Here's my simple test code: 这是我的简单测试代码:

@JsonIgnoreProperties(ignoreUnknown = true)
case class Relationship(
                         @Key("_id") id: ObjectId = new ObjectId,
                         fromUserId: ObjectId,
                         fromUserConfiguration: RelationshipConfiguration = new RelationshipConfiguration,
                         toUserId: ObjectId,
                         toUserConfiguration: RelationshipConfiguration = new RelationshipConfiguration,
                        status: RelationshipStatus.Value,
                         ) extends IdentifiableModel[Relationship] {

  ... some methods here
}

    case class SimpleCaseClass(string: String)
    case class SimpleCaseClassWithEnum(string: String,status: RelationshipStatus.Value)

    println(
      CustomSerializer.serialize( SimpleCaseClass("someString") )
    )
    println(
      CustomSerializer.serialize( SimpleCaseClassWithEnum("someString",RelationshipStatus.ACCEPTED) )
    )

    println(
      CustomSerializer.serialize(
        Relationship(
          fromUserId = new ObjectId("510f9398ed5080cb1265c8c2"),
          toUserId = new ObjectId("510f9398ed5080cb1265c8c2"),
          status = RelationshipStatus.ACCEPTED
        )
      )
    )

This produces the output: 产生输出:

{"string":"someString"}
{"string":"someString","status":{"enumClass":"models.RelationshipStatus","value":"ACCEPTED"}}
[21:35:58] ERROR application - 

! @6e03dp6pp - Internal server error, for (GET) [/me] ->

play.api.UnexpectedException: Unexpected exception[RuntimeException: Cannot resolve type alias Value in models.RelationshipStatus]
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$1.apply(ApplicationProvider.scala:142) ~[play_2.10.jar:2.1.0]
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$1.apply(ApplicationProvider.scala:106) ~[play_2.10.jar:2.1.0]
    at scala.Option.map(Option.scala:145) ~[scala-library.jar:na]
    at play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:106) ~[play_2.10.jar:2.1.0]
    at play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:104) ~[play_2.10.jar:2.1.0]
    at scala.util.Either$RightProjection.flatMap(Either.scala:523) [scala-library.jar:na]
    at play.core.ReloadableApplication.get(ApplicationProvider.scala:104) ~[play_2.10.jar:2.1.0]
    at play.core.server.Server$class.sendHandler$1(Server.scala:56) [play_2.10.jar:2.1.0]
    at play.core.server.Server$$anonfun$getHandlerFor$4.apply(Server.scala:88) [play_2.10.jar:2.1.0]
    at play.core.server.Server$$anonfun$getHandlerFor$4.apply(Server.scala:87) [play_2.10.jar:2.1.0]
    at scala.util.Either$RightProjection.flatMap(Either.scala:523) [scala-library.jar:na]
    at play.core.server.Server$class.getHandlerFor(Server.scala:87) [play_2.10.jar:2.1.0]
    at play.core.server.NettyServer.getHandlerFor(NettyServer.scala:34) [play_2.10.jar:2.1.0]
    at play.core.server.netty.PlayDefaultUpstreamHandler.messageReceived(PlayDefaultUpstreamHandler.scala:103) [play_2.10.jar:2.1.0]
    at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:75) [netty.jar:na]
    at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:565) [netty.jar:na]
    at org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:793) [netty.jar:na]
    at org.jboss.netty.handler.codec.http.HttpContentDecoder.messageReceived(HttpContentDecoder.java:104) [netty.jar:na]
    at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:75) [netty.jar:na]
    at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:565) [netty.jar:na]
    at org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:793) [netty.jar:na]
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296) [netty.jar:na]
    at org.jboss.netty.handler.codec.frame.FrameDecoder.unfoldAndFireMessageReceived(FrameDecoder.java:455) [netty.jar:na]
    at org.jboss.netty.handler.codec.replay.ReplayingDecoder.callDecode(ReplayingDecoder.java:538) [netty.jar:na]
    at org.jboss.netty.handler.codec.replay.ReplayingDecoder.messageReceived(ReplayingDecoder.java:437) [netty.jar:na]
    at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:75) [netty.jar:na]
    at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:565) [netty.jar:na]
    at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:560) [netty.jar:na]
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268) [netty.jar:na]
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255) [netty.jar:na]
    at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:84) [netty.jar:na]
    at org.jboss.netty.channel.socket.nio.AbstractNioWorker.processSelectedKeys(AbstractNioWorker.java:472) [netty.jar:na]
    at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:333) [netty.jar:na]
    at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:35) [netty.jar:na]
    at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:102) [netty.jar:na]
    at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42) [netty.jar:na]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) [na:1.7.0_01]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) [na:1.7.0_01]
    at java.lang.Thread.run(Thread.java:722) [na:1.7.0_01]
Caused by: java.lang.RuntimeException: Cannot resolve type alias Value in models.RelationshipStatus
    at org.scalastuff.scalabeans.sig.ScalaTypeCompiler.resolveTypeAlias(ScalaTypeCompiler.scala:202) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at org.scalastuff.scalabeans.sig.ScalaTypeCompiler.getTypeDecl$1(ScalaTypeCompiler.scala:159) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at org.scalastuff.scalabeans.sig.ScalaTypeCompiler.resolveScalaType(ScalaTypeCompiler.scala:167) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at org.scalastuff.scalabeans.sig.ScalaTypeCompiler$$anonfun$3.apply(ScalaTypeCompiler.scala:146) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at org.scalastuff.scalabeans.sig.ScalaTypeCompiler$$anonfun$3.apply(ScalaTypeCompiler.scala:145) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) ~[scala-library.jar:na]
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) ~[scala-library.jar:na]
    at scala.collection.mutable.ResizableArray$class.foreach(ResizableArray.scala:59) ~[scala-library.jar:na]
    at scala.collection.mutable.ArrayBuffer.foreach(ArrayBuffer.scala:47) ~[scala-library.jar:na]
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:244) ~[scala-library.jar:na]
    at scala.collection.AbstractTraversable.map(Traversable.scala:105) ~[scala-library.jar:na]
    at org.scalastuff.scalabeans.sig.ScalaTypeCompiler.compile(ScalaTypeCompiler.scala:145) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at org.scalastuff.scalabeans.sig.ScalaTypeCompiler$$anonfun$1$$anonfun$apply$2.apply(ScalaTypeCompiler.scala:51) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at org.scalastuff.scalabeans.sig.ScalaTypeCompiler$$anonfun$1$$anonfun$apply$2.apply(ScalaTypeCompiler.scala:48) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at scala.Option$WithFilter.map(Option.scala:206) ~[scala-library.jar:na]
    at org.scalastuff.scalabeans.sig.ScalaTypeCompiler$$anonfun$1.apply(ScalaTypeCompiler.scala:48) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at org.scalastuff.scalabeans.sig.ScalaTypeCompiler$$anonfun$1.apply(ScalaTypeCompiler.scala:47) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at scala.Option.flatMap(Option.scala:170) ~[scala-library.jar:na]
    at org.scalastuff.scalabeans.sig.ScalaTypeCompiler$.classInfoOf(ScalaTypeCompiler.scala:47) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at org.scalastuff.scalabeans.PropertyDescriptor$$anonfun$4.apply(PropertyDescriptor.scala:225) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at org.scalastuff.scalabeans.PropertyDescriptor$$anonfun$4.apply(PropertyDescriptor.scala:224) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at scala.Option.flatMap(Option.scala:170) ~[scala-library.jar:na]
    at org.scalastuff.scalabeans.PropertyDescriptor$.apply(PropertyDescriptor.scala:224) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at com.fasterxml.jackson.module.scala.util.SmarterBeanIntrospector$.com$fasterxml$jackson$module$scala$util$SmarterBeanIntrospector$$createPropertyDescriptor$1(ScalaBeansUtil.scala:68) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at com.fasterxml.jackson.module.scala.util.SmarterBeanIntrospector$$anonfun$5$$anonfun$apply$5.apply(ScalaBeansUtil.scala:103) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at com.fasterxml.jackson.module.scala.util.SmarterBeanIntrospector$$anonfun$5$$anonfun$apply$5.apply(ScalaBeansUtil.scala:94) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) ~[scala-library.jar:na]
    at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:244) ~[scala-library.jar:na]
    at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33) ~[scala-library.jar:na]
    at scala.collection.mutable.ArrayOps$ofRef.foreach(ArrayOps.scala:105) ~[scala-library.jar:na]
    at scala.collection.TraversableLike$class.map(TraversableLike.scala:244) ~[scala-library.jar:na]
    at scala.collection.mutable.ArrayOps$ofRef.map(ArrayOps.scala:105) ~[scala-library.jar:na]
    at com.fasterxml.jackson.module.scala.util.SmarterBeanIntrospector$$anonfun$5.apply(ScalaBeansUtil.scala:94) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at com.fasterxml.jackson.module.scala.util.SmarterBeanIntrospector$$anonfun$5.apply(ScalaBeansUtil.scala:93) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:251) ~[scala-library.jar:na]
    at scala.collection.TraversableLike$$anonfun$flatMap$1.apply(TraversableLike.scala:251) ~[scala-library.jar:na]
    at scala.collection.immutable.List.foreach(List.scala:309) ~[scala-library.jar:na]
    at scala.collection.TraversableLike$class.flatMap(TraversableLike.scala:251) ~[scala-library.jar:na]
    at scala.collection.AbstractTraversable.flatMap(Traversable.scala:105) ~[scala-library.jar:na]
    at com.fasterxml.jackson.module.scala.util.SmarterBeanIntrospector$.apply(ScalaBeansUtil.scala:93) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at com.fasterxml.jackson.module.scala.util.ScalaBeansUtil$.propertiesOf(ScalaBeansUtil.scala:166) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at com.fasterxml.jackson.module.scala.deser.CaseClassAnnotationIntrospector$.findConstructorParamName(CaseClassDeserializerModule.scala:51) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at com.fasterxml.jackson.module.scala.deser.CaseClassAnnotationIntrospector$.findDeserializationName(CaseClassDeserializerModule.scala:41) ~[jackson-module-scala_2.10-2.1.3.jar:na]
    at com.fasterxml.jackson.databind.AnnotationIntrospector.findNameForDeserialization(AnnotationIntrospector.java:915) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair.findNameForDeserialization(AnnotationIntrospectorPair.java:606) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector._addCreators(POJOPropertiesCollector.java:405) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.collect(POJOPropertiesCollector.java:233) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.introspect.BasicClassIntrospector.collectProperties(BasicClassIntrospector.java:142) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.introspect.BasicClassIntrospector.forSerialization(BasicClassIntrospector.java:68) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.introspect.BasicClassIntrospector.forSerialization(BasicClassIntrospector.java:11) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.SerializationConfig.introspect(SerializationConfig.java:490) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.ser.BeanSerializerFactory.createSerializer(BeanSerializerFactory.java:131) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.ser.SerializerFactory.createSerializer(SerializerFactory.java:53) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.SerializerProvider._createUntypedSerializer(SerializerProvider.java:935) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.SerializerProvider._createAndCacheUntypedSerializer(SerializerProvider.java:892) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.SerializerProvider.findValueSerializer(SerializerProvider.java:429) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.SerializerProvider.findTypedValueSerializer(SerializerProvider.java:520) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:99) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.ObjectMapper._configAndWriteValue(ObjectMapper.java:2627) ~[jackson-databind-2.1.2.jar:2.1.2]
    at com.fasterxml.jackson.databind.ObjectMapper.writeValueAsString(ObjectMapper.java:2119) ~[jackson-databind-2.1.2.jar:2.1.2]
    at utils.CustomSerializer$.serialize(CustomSerializer.scala:24) ~[na:na]
    at Global$.onStart(Global.scala:36) ~[na:na]
    at play.api.GlobalPlugin.onStart(GlobalSettings.scala:175) ~[play_2.10.jar:2.1.0]
    at play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:63) ~[play_2.10.jar:2.1.0]
    at play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:63) ~[play_2.10.jar:2.1.0]
    at scala.collection.immutable.List.foreach(List.scala:309) ~[scala-library.jar:na]
    at play.api.Play$$anonfun$start$1.apply$mcV$sp(Play.scala:63) ~[play_2.10.jar:2.1.0]
    at play.api.Play$$anonfun$start$1.apply(Play.scala:63) ~[play_2.10.jar:2.1.0]
    at play.api.Play$$anonfun$start$1.apply(Play.scala:63) ~[play_2.10.jar:2.1.0]
    at play.utils.Threads$.withContextClassLoader(Threads.scala:18) ~[play_2.10.jar:2.1.0]
    at play.api.Play$.start(Play.scala:62) ~[play_2.10.jar:2.1.0]
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$1.apply(ApplicationProvider.scala:133) ~[play_2.10.jar:2.1.0]
    ... 38 common frames omitted

So only the 3rd serialization fail. 因此,只有第三个序列化失败。

My Enumeration is basic: 我的枚举是基本的:

object RelationshipStatus extends Enumeration {
  val PENDING = Value("PENDING")
  val ACCEPTED = Value("ACCEPTED")
  val REJECTED = Value("REJECTED")
  val IGNORED = Value("IGNORED")
}

Any idea??? 任何想法??? I don't define any type alias in my Enumeration, so why this error? 我没有在枚举中定义任何类型别名,那么为什么会出现此错误? why on the 3rd attempt and not on the 2nd which has the same enum? 为什么在第三次尝试中而不是在第二次尝试中具有相同的枚举?

By the way, is it possible to have: 顺便说一句,可能有:

{"string":"someString","status":"ACCEPTED"}

Instead of: 代替:

{"string":"someString","status":{"enumClass":"models.RelationshipStatus","value":"ACCEPTED"}}

You have two different questions: 您有两个不同的问题:

  1. Why is this code throwing an exception? 为什么此代码引发异常?

    I don't know, other than to say that scalabeans , a library that the 2.1 series of the Jackson Scala module depends, looks like it's having trouble with Enumerations, possibly specifically under Scala 2.10. 我不知道,除了说scalabeans (Jackson Scala模块的2.1系列所依赖的一个库)看起来好像在枚举方面遇到了麻烦,可能特别是在Scala 2.10中。 I'll track this defect in the related github issue . 我将在相关的github问题中跟踪此缺陷。

  2. Can Enumerations not have to convey their type when serialized? 枚举序列化时是否可以不必传达其类型?

    Not yet. 还没。 Details why are in the relevant github issue ; 为何在相关的github问题中详细说明; the gist is that since the Value types for Enumerations are just type alias and not types, every value of every Enumeration-derived class has the same runtime type under Java erasure. 要点在于,由于Enumerations的Value类型只是类型别名而不是类型,因此在Java擦除下,每个Enumeration派生类的每个值都具有相同的运行时类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM