Skip to content

Commit 7ce96a6

Browse files
author
PJ Fanning
committed
handle null pointer issue
1 parent 71f534a commit 7ce96a6

File tree

2 files changed

+32
-14
lines changed

2 files changed

+32
-14
lines changed

src/main/scala/com/fasterxml/jackson/module/scala/introspect/ScalaAnnotationIntrospectorModule.scala

+18-14
Original file line numberDiff line numberDiff line change
@@ -123,22 +123,26 @@ object ScalaAnnotationIntrospector extends NopAnnotationIntrospector with ValueI
123123

124124
class ScalaValueInstantiator(delegate: StdValueInstantiator, config: DeserializationConfig, descriptor: BeanDescriptor) extends StdValueInstantiator(delegate) {
125125

126-
private val overriddenConstructorArguments = {
126+
private val overriddenConstructorArguments: Array[SettableBeanProperty] = {
127127
val args = delegate.getFromObjectArguments(config)
128-
129-
args.map {
130-
case creator: CreatorProperty =>
131-
// Locate the constructor param that matches it
132-
descriptor.properties.find(_.param.exists(_.index == creator.getCreatorIndex)) match {
133-
case Some(PropertyDescriptor(name, Some(ConstructorParameter(_, _, Some(defaultValue))), _, _, _, _, _)) =>
134-
creator.withNullProvider(new NullValueProvider {
135-
override def getNullValue(ctxt: DeserializationContext): AnyRef = defaultValue()
136-
137-
override def getNullAccessPattern: AccessPattern = AccessPattern.DYNAMIC
138-
})
139-
case _ => creator
128+
Option(args) match {
129+
case Some(array) => {
130+
array.map {
131+
case creator: CreatorProperty =>
132+
// Locate the constructor param that matches it
133+
descriptor.properties.find(_.param.exists(_.index == creator.getCreatorIndex)) match {
134+
case Some(PropertyDescriptor(name, Some(ConstructorParameter(_, _, Some(defaultValue))), _, _, _, _, _)) =>
135+
creator.withNullProvider(new NullValueProvider {
136+
override def getNullValue(ctxt: DeserializationContext): AnyRef = defaultValue()
137+
138+
override def getNullAccessPattern: AccessPattern = AccessPattern.DYNAMIC
139+
})
140+
case _ => creator
141+
}
142+
case other => other
140143
}
141-
case other => other
144+
}
145+
case _ => Array.empty
142146
}
143147
}
144148

src/test/scala/com/fasterxml/jackson/module/scala/deser/CreatorTest.scala

+14
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,17 @@ object CreatorTest
3939
}
4040
}
4141

42+
sealed abstract class Struct1(val name: String, val classifier: String = "my_default_string") {
43+
override def toString: String = name
44+
}
45+
4246
case class ConstructorWithDefaultValues(s: String = "some string", i: Int = 10, dummy: String)
4347

4448
case class ConstructorWithOptionDefaultValues(s: Option[String] = None, i: Option[Int] = None, dummy: String)
4549

4650
case class ConstructorWithOptionSeqDefaultValues(s: Option[Seq[String]] = None)
51+
52+
case class ConstructorWithOptionStruct(s: Option[Struct1] = None)
4753
}
4854

4955

@@ -140,4 +146,12 @@ class CreatorTest extends DeserializationFixture {
140146
deser2.s shouldEqual Some(Seq("a", "b"))
141147
f.writeValueAsString(ConstructorWithOptionSeqDefaultValues()) shouldEqual """{"s":null}"""
142148
}
149+
150+
it should "support optional structs with default values" ignore { f =>
151+
val deser = f.readValue[ConstructorWithOptionStruct]("""{}""")
152+
deser.s shouldBe empty
153+
val deser2 = f.readValue[ConstructorWithOptionStruct]("""{"s":{"name":"name"}}""")
154+
deser2.s shouldEqual Some(new Struct1("name"){})
155+
f.writeValueAsString(ConstructorWithOptionStruct()) shouldEqual """{"s":null}"""
156+
}
143157
}

0 commit comments

Comments
 (0)