Closed pjfanning closed 3 years ago
Jackson 2 logging (with additional stacktaces) - the 2nd call never happens in Jackson 3.
So for some reason, jackson-databind neglects to get the scala class information for the MetricPath class. And then, jackson 3 is unable to deserialize any json for Metrics because it doesn't know how deserialize MetricPaths. For some reason, Jackson 3 does not properly analyse classes that are the types of object members.
java.lang.Exception: >>>> class com.fasterxml.jackson.module.scala.deser.CaseClassDeserializerTest$Metric
| => jat com.fasterxml.jackson.module.scala.introspect.BeanIntrospector$.apply(BeanIntrospector.scala:227)
at com.fasterxml.jackson.module.scala.introspect.ScalaAnnotationIntrospector$._descriptorFor(ScalaAnnotationIntrospectorModule.scala:154)
at com.fasterxml.jackson.module.scala.introspect.ScalaAnnotationIntrospector$.fieldName(ScalaAnnotationIntrospectorModule.scala:165)
at com.fasterxml.jackson.module.scala.introspect.ScalaAnnotationIntrospector$.findImplicitPropertyName(ScalaAnnotationIntrospectorModule.scala:46)
at com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair.findImplicitPropertyName(AnnotationIntrospectorPair.java:501)
at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector._addFields(POJOPropertiesCollector.java:530)
at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.collectAll(POJOPropertiesCollector.java:421)
at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.getPropertyMap(POJOPropertiesCollector.java:386)
at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.getProperties(POJOPropertiesCollector.java:233)
at com.fasterxml.jackson.databind.introspect.BasicBeanDescription._properties(BasicBeanDescription.java:164)
at com.fasterxml.jackson.databind.introspect.BasicBeanDescription.findProperties(BasicBeanDescription.java:239)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._findCreatorsFromProperties(BasicDeserializerFactory.java:328)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._constructDefaultValueInstantiator(BasicDeserializerFactory.java:272)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findValueInstantiator(BasicDeserializerFactory.java:223)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:261)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:150)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:415)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:350)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:591)
at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:4725)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4595)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3551)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3519)
at com.fasterxml.jackson.module.scala.deser.DeserializerTest.deserialize(DeserializerTest.scala:18)
at com.fasterxml.jackson.module.scala.deser.DeserializerTest.deserialize$(DeserializerTest.scala:17)
at com.fasterxml.jackson.module.scala.deser.CaseClassDeserializerTest.deserialize(CaseClassDeserializerTest.scala:61)
at com.fasterxml.jackson.module.scala.deser.CaseClassDeserializerTest.$anonfun$new$2(CaseClassDeserializerTest.scala:72)
at org.scalatest.OutcomeOf.outcomeOf(OutcomeOf.scala:85)
at org.scalatest.OutcomeOf.outcomeOf$(OutcomeOf.scala:83)
at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
at org.scalatest.Transformer.apply(Transformer.scala:22)
at org.scalatest.Transformer.apply(Transformer.scala:20)
at org.scalatest.flatspec.AnyFlatSpecLike$$anon$5.apply(AnyFlatSpecLike.scala:1684)
at org.scalatest.TestSuite.withFixture(TestSuite.scala:196)
at org.scalatest.TestSuite.withFixture$(TestSuite.scala:195)
at org.scalatest.flatspec.AnyFlatSpec.withFixture(AnyFlatSpec.scala:1685)
at org.scalatest.flatspec.AnyFlatSpecLike.invokeWithFixture$1(AnyFlatSpecLike.scala:1682)
at org.scalatest.flatspec.AnyFlatSpecLike.$anonfun$runTest$1(AnyFlatSpecLike.scala:1694)
at org.scalatest.SuperEngine.runTestImpl(Engine.scala:306)
at org.scalatest.flatspec.AnyFlatSpecLike.runTest(AnyFlatSpecLike.scala:1694)
at org.scalatest.flatspec.AnyFlatSpecLike.runTest$(AnyFlatSpecLike.scala:1676)
at org.scalatest.flatspec.AnyFlatSpec.runTest(AnyFlatSpec.scala:1685)
at org.scalatest.flatspec.AnyFlatSpecLike.$anonfun$runTests$1(AnyFlatSpecLike.scala:1752)
at org.scalatest.SuperEngine.$anonfun$runTestsInBranch$1(Engine.scala:413)
at scala.collection.immutable.List.foreach(List.scala:333)
at org.scalatest.SuperEngine.traverseSubNodes$1(Engine.scala:401)
at org.scalatest.SuperEngine.runTestsInBranch(Engine.scala:390)
at org.scalatest.SuperEngine.$anonfun$runTestsInBranch$1(Engine.scala:427)
at scala.collection.immutable.List.foreach(List.scala:333)
at org.scalatest.SuperEngine.traverseSubNodes$1(Engine.scala:401)
at org.scalatest.SuperEngine.runTestsInBranch(Engine.scala:396)
at org.scalatest.SuperEngine.runTestsImpl(Engine.scala:475)
at org.scalatest.flatspec.AnyFlatSpecLike.runTests(AnyFlatSpecLike.scala:1752)
at org.scalatest.flatspec.AnyFlatSpecLike.runTests$(AnyFlatSpecLike.scala:1751)
at org.scalatest.flatspec.AnyFlatSpec.runTests(AnyFlatSpec.scala:1685)
at org.scalatest.Suite.run(Suite.scala:1112)
at org.scalatest.Suite.run$(Suite.scala:1094)
at org.scalatest.flatspec.AnyFlatSpec.org$scalatest$flatspec$AnyFlatSpecLike$$super$run(AnyFlatSpec.scala:1685)
at org.scalatest.flatspec.AnyFlatSpecLike.$anonfun$run$1(AnyFlatSpecLike.scala:1797)
at org.scalatest.SuperEngine.runImpl(Engine.scala:535)
at org.scalatest.flatspec.AnyFlatSpecLike.run(AnyFlatSpecLike.scala:1797)
at org.scalatest.flatspec.AnyFlatSpecLike.run$(AnyFlatSpecLike.scala:1795)
at org.scalatest.flatspec.AnyFlatSpec.run(AnyFlatSpec.scala:1685)
at org.scalatest.tools.Framework.org$scalatest$tools$Framework$$runSuite(Framework.scala:318)
at org.scalatest.tools.Framework$ScalaTestTask.execute(Framework.scala:513)
at sbt.TestRunner.runTest$1(TestFramework.scala:139)
at sbt.TestRunner.run(TestFramework.scala:154)
at sbt.TestFramework$$anon$3$$anonfun$$lessinit$greater$1.$anonfun$apply$1(TestFramework.scala:317)
at sbt.TestFramework$.sbt$TestFramework$$withContextLoader(TestFramework.scala:277)
at sbt.TestFramework$$anon$3$$anonfun$$lessinit$greater$1.apply(TestFramework.scala:317)
at sbt.TestFramework$$anon$3$$anonfun$$lessinit$greater$1.apply(TestFramework.scala:317)
at sbt.TestFunction.apply(TestFramework.scala:329)
at sbt.Tests$.$anonfun$toTask$1(Tests.scala:422)
at sbt.std.Transform$$anon$3.$anonfun$apply$2(Transform.scala:46)
at sbt.std.Transform$$anon$4.work(Transform.scala:68)
at sbt.Execute.$anonfun$submit$2(Execute.scala:282)
at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:23)
at sbt.Execute.work(Execute.scala:291)
at sbt.Execute.$anonfun$submit$1(Execute.scala:282)
at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:265)
at sbt.CompletionService$$anon$2.call(CompletionService.scala:64)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
java.lang.Exception: >>>> class com.fasterxml.jackson.module.scala.deser.CaseClassDeserializerTest$MetricPath
at com.fasterxml.jackson.module.scala.introspect.BeanIntrospector$.apply(BeanIntrospector.scala:227)
at com.fasterxml.jackson.module.scala.introspect.ScalaAnnotationIntrospector$._descriptorFor(ScalaAnnotationIntrospectorModule.scala:154)
at com.fasterxml.jackson.module.scala.introspect.ScalaAnnotationIntrospector$.fieldName(ScalaAnnotationIntrospectorModule.scala:165)
at com.fasterxml.jackson.module.scala.introspect.ScalaAnnotationIntrospector$.findImplicitPropertyName(ScalaAnnotationIntrospectorModule.scala:46)
at com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair.findImplicitPropertyName(AnnotationIntrospectorPair.java:501)
at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector._addFields(POJOPropertiesCollector.java:530)
at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.collectAll(POJOPropertiesCollector.java:421)
at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.getPropertyMap(POJOPropertiesCollector.java:386)
at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.getProperties(POJOPropertiesCollector.java:233)
at com.fasterxml.jackson.databind.introspect.BasicBeanDescription._properties(BasicBeanDescription.java:164)
at com.fasterxml.jackson.databind.introspect.BasicBeanDescription.findProperties(BasicBeanDescription.java:239)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._findCreatorsFromProperties(BasicDeserializerFactory.java:328)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._constructDefaultValueInstantiator(BasicDeserializerFactory.java:272)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findValueInstantiator(BasicDeserializerFactory.java:223)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:261)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:150)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:415)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:350)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
at com.fasterxml.jackson.databind.DeserializationContext.findNonContextualValueDeserializer(DeserializationContext.java:581)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.resolve(BeanDeserializerBase.java:539)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:294)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:591)
at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:4725)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4595)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3551)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3519)
at com.fasterxml.jackson.module.scala.deser.DeserializerTest.deserialize(DeserializerTest.scala:18)
at com.fasterxml.jackson.module.scala.deser.DeserializerTest.deserialize$(DeserializerTest.scala:17)
at com.fasterxml.jackson.module.scala.deser.CaseClassDeserializerTest.deserialize(CaseClassDeserializerTest.scala:61)
at com.fasterxml.jackson.module.scala.deser.CaseClassDeserializerTest.$anonfun$new$2(CaseClassDeserializerTest.scala:72)
at org.scalatest.OutcomeOf.outcomeOf(OutcomeOf.scala:85)
at org.scalatest.OutcomeOf.outcomeOf$(OutcomeOf.scala:83)
at org.scalatest.OutcomeOf$.outcomeOf(OutcomeOf.scala:104)
at org.scalatest.Transformer.apply(Transformer.scala:22)
at org.scalatest.Transformer.apply(Transformer.scala:20)
at org.scalatest.flatspec.AnyFlatSpecLike$$anon$5.apply(AnyFlatSpecLike.scala:1684)
at org.scalatest.TestSuite.withFixture(TestSuite.scala:196)
at org.scalatest.TestSuite.withFixture$(TestSuite.scala:195)
at org.scalatest.flatspec.AnyFlatSpec.withFixture(AnyFlatSpec.scala:1685)
at org.scalatest.flatspec.AnyFlatSpecLike.invokeWithFixture$1(AnyFlatSpecLike.scala:1682)
at org.scalatest.flatspec.AnyFlatSpecLike.$anonfun$runTest$1(AnyFlatSpecLike.scala:1694)
at org.scalatest.SuperEngine.runTestImpl(Engine.scala:306)
at org.scalatest.flatspec.AnyFlatSpecLike.runTest(AnyFlatSpecLike.scala:1694)
at org.scalatest.flatspec.AnyFlatSpecLike.runTest$(AnyFlatSpecLike.scala:1676)
at org.scalatest.flatspec.AnyFlatSpec.runTest(AnyFlatSpec.scala:1685)
at org.scalatest.flatspec.AnyFlatSpecLike.$anonfun$runTests$1(AnyFlatSpecLike.scala:1752)
at org.scalatest.SuperEngine.$anonfun$runTestsInBranch$1(Engine.scala:413)
at scala.collection.immutable.List.foreach(List.scala:333)
at org.scalatest.SuperEngine.traverseSubNodes$1(Engine.scala:401)
at org.scalatest.SuperEngine.runTestsInBranch(Engine.scala:390)
at org.scalatest.SuperEngine.$anonfun$runTestsInBranch$1(Engine.scala:427)
at scala.collection.immutable.List.foreach(List.scala:333)
at org.scalatest.SuperEngine.traverseSubNodes$1(Engine.scala:401)
at org.scalatest.SuperEngine.runTestsInBranch(Engine.scala:396)
at org.scalatest.SuperEngine.runTestsImpl(Engine.scala:475)
at org.scalatest.flatspec.AnyFlatSpecLike.runTests(AnyFlatSpecLike.scala:1752)
at org.scalatest.flatspec.AnyFlatSpecLike.runTests$(AnyFlatSpecLike.scala:1751)
at org.scalatest.flatspec.AnyFlatSpec.runTests(AnyFlatSpec.scala:1685)
at org.scalatest.Suite.run(Suite.scala:1112)
at org.scalatest.Suite.run$(Suite.scala:1094)
at org.scalatest.flatspec.AnyFlatSpec.org$scalatest$flatspec$AnyFlatSpecLike$$super$run(AnyFlatSpec.scala:1685)
at org.scalatest.flatspec.AnyFlatSpecLike.$anonfun$run$1(AnyFlatSpecLike.scala:1797)
at org.scalatest.SuperEngine.runImpl(Engine.scala:535)
at org.scalatest.flatspec.AnyFlatSpecLike.run(AnyFlatSpecLike.scala:1797)
at org.scalatest.flatspec.AnyFlatSpecLike.run$(AnyFlatSpecLike.scala:1795)
at org.scalatest.flatspec.AnyFlatSpec.run(AnyFlatSpec.scala:1685)
at org.scalatest.tools.Framework.org$scalatest$tools$Framework$$runSuite(Framework.scala:318)
at org.scalatest.tools.Framework$ScalaTestTask.execute(Framework.scala:513)
at sbt.TestRunner.runTest$1(TestFramework.scala:139)
at sbt.TestRunner.run(TestFramework.scala:154)
at sbt.TestFramework$$anon$3$$anonfun$$lessinit$greater$1.$anonfun$apply$1(TestFramework.scala:317)
at sbt.TestFramework$.sbt$TestFramework$$withContextLoader(TestFramework.scala:277)
at sbt.TestFramework$$anon$3$$anonfun$$lessinit$greater$1.apply(TestFramework.scala:317)
at sbt.TestFramework$$anon$3$$anonfun$$lessinit$greater$1.apply(TestFramework.scala:317)
at sbt.TestFunction.apply(TestFramework.scala:329)
at sbt.Tests$.$anonfun$toTask$1(Tests.scala:422)
at sbt.std.Transform$$anon$3.$anonfun$apply$2(Transform.scala:46)
at sbt.std.Transform$$anon$4.work(Transform.scala:68)
at sbt.Execute.$anonfun$submit$2(Execute.scala:282)
at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:23)
at sbt.Execute.work(Execute.scala:291)
at sbt.Execute.$anonfun$submit$1(Execute.scala:282)
at sbt.ConcurrentRestrictions$$anon$4.$anonfun$submitValid$1(ConcurrentRestrictions.scala:265)
at sbt.CompletionService$$anon$2.call(CompletionService.scala:64)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Jackson 3 seems to do value instantiation first
java.lang.Exception: >>>> class com.fasterxml.jackson.module.scala.deser.CaseClassDeserializerTest$Metric
| => cat com.fasterxml.jackson.module.scala.introspect.BeanIntrospector$.apply(BeanIntrospector.scala:227)
at com.fasterxml.jackson.module.scala.introspect.ScalaAnnotationIntrospector$._descriptorFor(ScalaAnnotationIntrospectorModule.scala:164)
at com.fasterxml.jackson.module.scala.introspect.ScalaAnnotationIntrospector$.findValueInstantiator(ScalaAnnotationIntrospectorModule.scala:149)
at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findValueInstantiator(BasicDeserializerFactory.java:172)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:255)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:150)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:393)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:330)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:244)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:225)
at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:146)
at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:637)
So the "missing" method would be findImplicitPropertyName()
?
findImplicitPropertyName is implemented in the ScalaAnnotationIntrospector and gets call correctly for Metric but not for the MetricPath class. I've been trying to step though jackson-databind but the jackson-databind code is not something I really understand. I can see the jackson-databind code does look at the properties of Metric class including the property with MetricPath type but gives up and never calls findImplicitPropertyName for the MetricPath class.
Is it possible that jackson 3 requires ScalaAnnotationIntrospector to implement more methods? - right now it is only overrides a small number of methods on NopAnnotationIntrospector
Ok. It is possible other things might be needed. But another thing is that introspection may also be little bit asynchronous, in that order in which things go may be different.
Perhaps debug statements in POJOPropertiesCollector
could show if MetricPath
even gets introspected.
POJOPropertiesCollector never gets instantiated for MetricPath (in jackson 3). It does for Metric class.
I'm debugging code in IntelliJ - it is easy to get IntelliJ to debug the jackson-module-scala tests - it's just that I simply do not understand the code in jackson-databind, so I do not know what to look for in order to explain why jackson 3 and not jackson 2 refuses to introspect the MetricPath class.
jackson-module-scala is unusable if it cannot handle classes like Metric.
@pjfanning Is there something special about MetricPath
? I could try to troubleshoot this if I can somehow recreate the type... skipping of POJOPropertiesCollector would likely be due to either deserializer being created using some other mechanism (it's taken to be some other "well-known" type, like if if it was an Enum), or if it was not yet needed.
Too bad jackson-integration-tests
is just for 2.x at this point. I wonder if it'd be worth creating 2.x branches and make master
be for 3.0; that way it'd be slightly easier for me to debug some Scala cases. Unfortunately I haven't been able to (in the past at least) get jackson-module-scala (or, jackson-module-kotlin for that matter) to load up successfully on Eclipse. I sometimes use IntelliJ but on that my problem is that unlike with Eclipse I cannot actually get it to debug through local snapshot version for some reason (on Eclipse if I have snapshot version open it gets properly associated so I can get matching versions to run, add breakpoints etc).
There is nothing special about Metric - it is as plain a class as you could possibly have in Scala.
_createAndCache2 in DeserializerCache - this code in Jackson2 works perfectly -
if (deser instanceof ResolvableDeserializer) {
this._incompleteDeserializers.put(type, deser);
((ResolvableDeserializer)deser).resolve(ctxt);
this._incompleteDeserializers.remove(type);
}
The resolve on BeanDeserializerBase walks the object graph - picking up all the type information for the class and the classes of its members.
The new code in jackson 3 does not even try to read the class information for the classes of the members.
@pjfanning Right I would be surprised if resolution did not proceed. What I am trying to think of is where between locating a deserialization and introspection properties things get derailed. (delegation for Java beans works fine in that there are no failure cases there for 3.0)
What is the fail message again? Presumable a deserializer (but not functioning one) gets created or... ?
in jackson 3 BeanDeserializerFactory addBeanProps, the code just simply fails to get the creator property for the 'path' property that had MetricPath type
@cowtowncoder test fails with https://github.com/FasterXML/jackson-module-scala/issues/431#issuecomment-775584637
Ok, perhaps it'd be simpler to troubleshoot direct deserialization of MetricPath
type: I assume that would fail as well but perhaps show direct stack trace (as opposed to indirect via Metric
).
I think I incorrectly referred to Metric
earlier as well.
Oh, wait, perhaps not. If the inner type (MetricPath
, right?) is passed as creator parameter of outer type (Metric
), the lack of introspection of the inner type may be simply due to failure earlier.
Until deserializer is assigned, all that is needed is type resolution (to get JavaType
).
If so it would be due to missing linkage when resolving pieces of Metric
and nothing to do with MetricPath
-- deserializer for latter is not yet needed: it would be, at a later point, but deserializer building code is missing link between "regular" and Creator property for path
(of Metric
).
That is a problem on its own but not showing an issue with introspection.
At least if I am understanding the situation better now.
MetricPath deserializes ok if it is deserialized by itself - the issue is when it is the type of a member of another class.
Ok that makes sense. The problem seems to be that introspection does not find creator property for some reason. Not MetricPath
type itself. In fact it would seem that it could as well be any other type (String
) and same should occur?
At this point, would it make sense to create a new issue for this one problem. Not sure if there are other ones, but discussion here has gotten bit long and covers a few different issues, most resolved?
I found some code in the Scala annotation classes that is not behaving as it does in Jackson 2 - let me investigate this - it could be the cause of the issue here
@cowtowncoder a possible/probable cause is that the jackson-module-scala was modified in jackson 3 because the interface in jackson-databind changed.
ValueInstantiators findValueInstantiator(DeserializationConfig var1, BeanDescription var2, ValueInstantiator var3) has dropped the final param - the defaultValueInstantiator
The scala code now struggles to replace that default. Any suggestions as to how to get a default instantiator in jackson 3?
@pjfanning Let me see, I think this was just split in two parts or so.
Ok, yes; so, there is new modifyValueInstantiator()
which is what you want to use in case you want to use the default one: so existing findValueInstantiator()
is meant for full override case; and then modifyValueInstantiator()
for things like delegation.
I have no value instantiator so can't modify it. Is there any way to create a new default instantiator that has all the creator properties calculated - that's what I get in jackson 2 - automatically but now I am left with no instantiator and need to create from scratch .
findValueInstantiator(config: DeserializationConfig, ...) -- because this method does not give access to a full DeserializationContext, it is hard to try BeanDeserializerBuilder to try to get a value instantiator from it
Please look at signature:
default ValueInstantiator modifyValueInstantiator(DeserializationConfig config,
BeanDescription beanDesc, ValueInstantiator defaultInstantiator);
you are given the default instantiator UNLESS earlier call to
public ValueInstantiator findValueInstantiator(DeserializationConfig config,
BeanDescription beanDesc);
already returned a ValueInstantiator
.
So basically earlier single call was split in two parts: one to ask for instantiator, and if none given, a default POJO instantiator is created and passed to give another chance for custom variants.
So if you want to use that default instantiator it is given and you may return it as-is, or create different one based on it (or just ignore).
default ValueInstantiator modifyValueInstantiator(DeserializationConfig config,
BeanDescription beanDesc, ValueInstantiator defaultInstantiator) {
return defaultInstantiator;
}
I have no defaultInstantiator to pass in
Ok now I am confused. This is a callback method of ValueInstantiators
interface.
Scala module should not usually be calling it.... it is called by Jackson databind (specifically BasicDeserializerFactory
). Modules would implement ValueInstantiators
callback to be able to provide alternative instantiator. That handling was split from 1 to 2 methods.
If Scala module does need to call it, where is the code? Maybe I can help with it.
In jackson 2, the perfect value instantiator is created in BasicDeserializer.findValueInstantiator -- and specifically when this is called instantiator = this._constructDefaultValueInstantiator(ctxt, beanDesc);
This instantiator is then used when the call to the old ValueInstantiators findValueInstantiator(DeserializationConfig var1, BeanDescription var2, ValueInstantiator var3)
function is called
I think I fixed it - I made the findValueInstantiator return null so now the modifyValueInstantiator is called with the instantiator created in the BasicDeserializer
We're now down to 2 or 3 commented out tests in master that pass in jackson v2 and that fail in v3 - today's fix fixed about 5 broken tests
@pjfanning Ok good, yes, findValueInstantiator()
should return null
to indicate "go ahead construct default one" and then that one will be passed for possible modification/replacement. So fix makes sense.
Getting very close to parity which is good!
created https://github.com/FasterXML/jackson-module-scala/issues/536 for follow on work
Compilation fails due to major changes in jackson-databind
https://travis-ci.org/FasterXML/jackson-module-scala/jobs/588055923