FasterXML/jackson-module-scala (original) (raw)

Deserializing a tuple that contains Some values succeeds.
However, a MismatchedInputException will be thrown during deserialization If the tuple contains None values.

Version

Actual behavior

The test case "deserialize OptionalTupleHolder that has 'None' values" fails.

package com.example

import com.fasterxml.jackson.databind.json.JsonMapper import com.fasterxml.jackson.module.scala.DefaultScalaModule import org.scalatest.funsuite.AnyFunSuite import org.scalatest.matchers.should.Matchers

object JacksonScalaSpec { final case class OptionalTupleHolder(tuple: (Option[Int], Option[String])) }

class JacksonScalaSpec extends AnyFunSuite with Matchers { import JacksonScalaSpec._

private val mapper = JsonMapper .builder() .addModule(DefaultScalaModule) .build()

println(mapper.version())

test("deserialize OptionalTupleHolder that has 'Some' values") { val obj = OptionalTupleHolder((Option(1), Option("2"))) val json = mapper.writeValueAsString(obj) println(json) // {"tuple":[1,"2"]} val deserialized = mapper.reyadValue(json, classOf[OptionalTupleHolder]) println(deserialized)

obj should be(deserialized)
// pass

}

test("deserialize OptionalTupleHolder that has 'None' values") { val obj = OptionalTupleHolder((Option.empty, Option.empty)) val json = mapper.writeValueAsString(obj) println(json) // {"tuple":[null,null]} val deserialized = mapper.readValue(json, classOf[OptionalTupleHolder]) // throws com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type java.lang.String from Null value (token JsonToken.VALUE_NULL) println(deserialized)

obj should be(deserialized)

} }

Details of MismatchedInputException

Cannot deserialize value of type `java.lang.String` from Null value (token `JsonToken.VALUE_NULL`)
 at [Source: (String)"{"tuple":[null,null]}"; line: 1, column: 16] (through reference chain: com.example.JacksonScalaSpec$OptionalTupleHolder["tuple"])
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `java.lang.String` from Null value (token `JsonToken.VALUE_NULL`)
 at [Source: (String)"{"tuple":[null,null]}"; line: 1, column: 16] (through reference chain: com.example.JacksonScalaSpec$OptionalTupleHolder["tuple"])
    at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:59)
    at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1601)
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1375)
    at com.fasterxml.jackson.databind.DeserializationContext.handleUnexpectedToken(DeserializationContext.java:1280)
    at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:73)
    at com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:11)
    at com.fasterxml.jackson.module.scala.deser.OptionDeserializer.deserialize(OptionDeserializerModule.scala:61)
    at com.fasterxml.jackson.module.scala.deser.OptionDeserializer.deserialize(OptionDeserializerModule.scala:11)
    at com.fasterxml.jackson.module.scala.deser.TupleDeserializer.$anonfun$deserialize$1(TupleDeserializerModule.scala:48)
    at scala.collection.immutable.Vector1.map(Vector.scala:1886)
    at scala.collection.immutable.Vector1.map(Vector.scala:375)
    at com.fasterxml.jackson.module.scala.deser.TupleDeserializer.deserialize(TupleDeserializerModule.scala:45)
    at com.fasterxml.jackson.module.scala.deser.TupleDeserializer.deserialize(TupleDeserializerModule.scala:10)
    at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:542)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeWithErrorWrapping(BeanDeserializer.java:565)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:449)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1405)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:362)
    at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:195)
    at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:322)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4593)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3548)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3516)
    at com.example.JacksonScalaSpec.$anonfun$new$2(JacksonScalaSpec.scala:38)

Expected behavior

The json {"tuple":[null,null]} is deserialized to OptionalTupleHolder((None, None)) without any Exceptions.