Skip to content
This repository was archived by the owner on Nov 28, 2017. It is now read-only.
This repository was archived by the owner on Nov 28, 2017. It is now read-only.

Json4sCodec deserializer expects an object to deserialize joda DateTime from #14

Open

Description

@divijan

Standalone DateTime value is serialized to string using a custom producer and deserialized back using a custom consumer just fine. However, when DateTime value is part of a case class, it is serialized to string, but fails to deserialize (causing the whole case class deserialization to fail) with a message:

MappingException: : Expected an object field for timestamp but found a JString (json4s_input.scala:44)

where timestamp is the name of the DateTime field.

Activity

  1. casualjim commented on Sep 3, 2014

    @casualjim
    Member

    do your formats include the joda time formats? This error suggests they don't

  2. casualjim commented on Sep 9, 2014

    @casualjim
    Member

    what's the source of DateTime? Is that the joda time one?
    Can you share a snippet to reproduce this behavior?

  3. divijan commented on Sep 9, 2014

    @divijan
    Author

    I'm sorry, notification for the first message wound up in spam.
    Yes, it is org.joda.time.DateTime. Here is the code ("StackEvt" should "serialize to string and deserialize back" fails):

    import muster.ast.{AstNode, TextNode}
    import muster.input.Consumer
    import muster.output.{Producer, OutputFormatter}
    import org.joda.time.{DateTimeZone, DateTime}
    import com.typesafe.scalalogging.LazyLogging
    import org.specs2.mutable._
    import org.json4s._
    import muster.codec.json4s._
    
    class LowLevelTest extends Specification with LazyLogging {
      case class StackEvt (timestamp: DateTime)
    
      implicit object DateTimeConsumer extends Consumer[DateTime] {
        def consume(node: AstNode[_]): DateTime = node match {
          case TextNode(value) =>
            val timeZone = DateTimeZone.getDefault
            DateTime.parse(value).withZone(timeZone) //otherwise the parsed DateTime won't equal the original
          case n => throw new MappingException("Can't parse timestamp from ${n.getClass}")
        }
      }
    
      implicit object DateTimeProducer extends Producer[DateTime] {
        def produce(value: DateTime, formatter: OutputFormatter[_]) = formatter.string(value.toString)
      }
    
      "Joda DateTime" should {
        "serialize to string and deserialize back" in {
          val now = new DateTime
          val nowSerialized = Json4sCodec.from(now)
    
          val back = Json4sCodec.as[DateTime](nowSerialized)
          /* Note: even if string representations of DateTime objects are the same, the objects may not be
             equal by hashcode. See
             http://stackoverflow.com/questions/21002385/datetime-does-not-equal-itself-after-unserialization
          */
          logger.debug("Joda DateTime now and back: " + now.toString + " " + back.toString)
          back shouldEqual now
        }
      }
    
      "StackEvt" should {
        "serialize to string and deserialize back" in {
          val testEvent = StackEvt (timestamp = new DateTime)
    
          val json = Json4sCodec.from(testEvent)
          val back = Json4sCodec.as[StackEvt](json)
    
          back shouldEqual testEvent
        }
      }
    }
    
  4. divijan commented on Sep 9, 2014

    @divijan
    Author

    Similar thing happens with Java Date, only in this case the deserializer expects a JString and fails when it gets anything else.

  5. divijan commented on Sep 12, 2014

    @divijan
    Author

    What are the fully qualified class names of formats you are referring to?

  6. casualjim commented on Sep 12, 2014

    @casualjim
    Member

    that was me being confused. I thought this was in the json4s repo not muster

  7. divijan commented on Sep 24, 2014

    @divijan
    Author

    I have put together a project to illustrate the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions