deserialize generic class using jackson-module-kotlin












0















I'm trying to use the jackson-kotlin integration. Mostly it works nice but I'm having trouble with deserializing generic types. I tried to adapt the answer to this question: Jackson - Deserialize using generic class



    // create an object mapper
val jsonFactory = JsonFactory()
jsonFactory.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false)
jsonFactory.configure(JsonParser.Feature.IGNORE_UNDEFINED, true)

val objectMapper = ObjectMapper(jsonFactory)
objectMapper.findAndRegisterModules()
objectMapper.propertyNamingStrategy = PropertyNamingStrategy.SnakeCaseStrategy()
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)

// simple generic type
data class Inner(val meaningOfLife: Int)
data class Outer<T>(val inner: T)

val outer = Outer(Inner(42))

val serialized = objectMapper.stringify(outer, true)
println(serialized)

// deserializing does not work using:
// https://stackoverflow.com/questions/11664894/jackson-deserialize-using-generic-class
val parsed = objectMapper.readValue<Outer<Inner>>(serialized, objectMapper.typeFactory.constructParametricType(Outer::class.java,Inner::class.java))


This throws an exception:



com.fasterxml.jackson.databind.JsonMappingException: Cannot deserialize Class io.inbot.common.ObjectMapperTest$should handle generics$Outer (of type local/anonymous) as a Bean
at [Source: (String)"{
"inner" : {
"meaning_of_life" : 42
}
}"; line: 1, column: 1]

at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:306)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:268)
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:477)
at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:4190)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4009)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3042)
at io.inbot.common.ObjectMapperTest.should handle generics(ObjectMapperTest.kt:22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:580)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:716)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:988)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:648)
at org.testng.TestRunner.run(TestRunner.java:505)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)
Caused by: java.lang.IllegalArgumentException: Cannot deserialize Class io.inbot.common.ObjectMapperTest$should handle generics$Outer (of type local/anonymous) as a Bean
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.isPotentialBeanType(BeanDeserializerFactory.java:877)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:131)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:411)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:349)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)
... 31 more


Obviously the jackson plugin for kotlin does not handle this. Is there a workaround for this or a different way of doing this?



BTW. the stringify function is a simple extension function I added for ObjectMapper that takes care of the boilerplate code:



/**
* Serializes [value] to a string. Pretty prints if [pretty] is set.
*/
fun <T> ObjectMapper.stringify(value: T, pretty: Boolean = false): String {
val bos = ByteArrayOutputStream()
val writer = OutputStreamWriter(bos, StandardCharsets.UTF_8)
if(pretty) {
writerWithDefaultPrettyPrinter().writeValue(writer,value)
} else {
writeValue(writer, value)
}
writer.flush()
bos.flush()
return bos.toByteArray().toString(StandardCharsets.UTF_8)
}


UPDATE The code in the answer by @jayson-minard works. It turns out that the key difference with my code was that I defined the data classes inside the test method. Moving them outside to the top level fixes things. Putting a dataclass in a function was a bad idea to begin with.










share|improve this question

























  • Have you tried this without your type factory call, and let the readValue extension function just infer the reified type?

    – Jayson Minard
    Nov 27 '18 at 12:32











  • What version of Jackson are you using? what version of the Jackson-Kotlin module are you using? what version of Kotlin?

    – Jayson Minard
    Nov 27 '18 at 13:13











  • 2.9.7 of both, type inference does not work here because jackson has no way of knowing what the type is. Also Java 8, kotlin 1.3.10

    – Jilles van Gurp
    Nov 27 '18 at 15:09
















0















I'm trying to use the jackson-kotlin integration. Mostly it works nice but I'm having trouble with deserializing generic types. I tried to adapt the answer to this question: Jackson - Deserialize using generic class



    // create an object mapper
val jsonFactory = JsonFactory()
jsonFactory.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false)
jsonFactory.configure(JsonParser.Feature.IGNORE_UNDEFINED, true)

val objectMapper = ObjectMapper(jsonFactory)
objectMapper.findAndRegisterModules()
objectMapper.propertyNamingStrategy = PropertyNamingStrategy.SnakeCaseStrategy()
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)

// simple generic type
data class Inner(val meaningOfLife: Int)
data class Outer<T>(val inner: T)

val outer = Outer(Inner(42))

val serialized = objectMapper.stringify(outer, true)
println(serialized)

// deserializing does not work using:
// https://stackoverflow.com/questions/11664894/jackson-deserialize-using-generic-class
val parsed = objectMapper.readValue<Outer<Inner>>(serialized, objectMapper.typeFactory.constructParametricType(Outer::class.java,Inner::class.java))


This throws an exception:



com.fasterxml.jackson.databind.JsonMappingException: Cannot deserialize Class io.inbot.common.ObjectMapperTest$should handle generics$Outer (of type local/anonymous) as a Bean
at [Source: (String)"{
"inner" : {
"meaning_of_life" : 42
}
}"; line: 1, column: 1]

at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:306)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:268)
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:477)
at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:4190)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4009)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3042)
at io.inbot.common.ObjectMapperTest.should handle generics(ObjectMapperTest.kt:22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:580)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:716)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:988)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:648)
at org.testng.TestRunner.run(TestRunner.java:505)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)
Caused by: java.lang.IllegalArgumentException: Cannot deserialize Class io.inbot.common.ObjectMapperTest$should handle generics$Outer (of type local/anonymous) as a Bean
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.isPotentialBeanType(BeanDeserializerFactory.java:877)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:131)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:411)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:349)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)
... 31 more


Obviously the jackson plugin for kotlin does not handle this. Is there a workaround for this or a different way of doing this?



BTW. the stringify function is a simple extension function I added for ObjectMapper that takes care of the boilerplate code:



/**
* Serializes [value] to a string. Pretty prints if [pretty] is set.
*/
fun <T> ObjectMapper.stringify(value: T, pretty: Boolean = false): String {
val bos = ByteArrayOutputStream()
val writer = OutputStreamWriter(bos, StandardCharsets.UTF_8)
if(pretty) {
writerWithDefaultPrettyPrinter().writeValue(writer,value)
} else {
writeValue(writer, value)
}
writer.flush()
bos.flush()
return bos.toByteArray().toString(StandardCharsets.UTF_8)
}


UPDATE The code in the answer by @jayson-minard works. It turns out that the key difference with my code was that I defined the data classes inside the test method. Moving them outside to the top level fixes things. Putting a dataclass in a function was a bad idea to begin with.










share|improve this question

























  • Have you tried this without your type factory call, and let the readValue extension function just infer the reified type?

    – Jayson Minard
    Nov 27 '18 at 12:32











  • What version of Jackson are you using? what version of the Jackson-Kotlin module are you using? what version of Kotlin?

    – Jayson Minard
    Nov 27 '18 at 13:13











  • 2.9.7 of both, type inference does not work here because jackson has no way of knowing what the type is. Also Java 8, kotlin 1.3.10

    – Jilles van Gurp
    Nov 27 '18 at 15:09














0












0








0








I'm trying to use the jackson-kotlin integration. Mostly it works nice but I'm having trouble with deserializing generic types. I tried to adapt the answer to this question: Jackson - Deserialize using generic class



    // create an object mapper
val jsonFactory = JsonFactory()
jsonFactory.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false)
jsonFactory.configure(JsonParser.Feature.IGNORE_UNDEFINED, true)

val objectMapper = ObjectMapper(jsonFactory)
objectMapper.findAndRegisterModules()
objectMapper.propertyNamingStrategy = PropertyNamingStrategy.SnakeCaseStrategy()
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)

// simple generic type
data class Inner(val meaningOfLife: Int)
data class Outer<T>(val inner: T)

val outer = Outer(Inner(42))

val serialized = objectMapper.stringify(outer, true)
println(serialized)

// deserializing does not work using:
// https://stackoverflow.com/questions/11664894/jackson-deserialize-using-generic-class
val parsed = objectMapper.readValue<Outer<Inner>>(serialized, objectMapper.typeFactory.constructParametricType(Outer::class.java,Inner::class.java))


This throws an exception:



com.fasterxml.jackson.databind.JsonMappingException: Cannot deserialize Class io.inbot.common.ObjectMapperTest$should handle generics$Outer (of type local/anonymous) as a Bean
at [Source: (String)"{
"inner" : {
"meaning_of_life" : 42
}
}"; line: 1, column: 1]

at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:306)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:268)
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:477)
at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:4190)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4009)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3042)
at io.inbot.common.ObjectMapperTest.should handle generics(ObjectMapperTest.kt:22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:580)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:716)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:988)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:648)
at org.testng.TestRunner.run(TestRunner.java:505)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)
Caused by: java.lang.IllegalArgumentException: Cannot deserialize Class io.inbot.common.ObjectMapperTest$should handle generics$Outer (of type local/anonymous) as a Bean
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.isPotentialBeanType(BeanDeserializerFactory.java:877)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:131)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:411)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:349)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)
... 31 more


Obviously the jackson plugin for kotlin does not handle this. Is there a workaround for this or a different way of doing this?



BTW. the stringify function is a simple extension function I added for ObjectMapper that takes care of the boilerplate code:



/**
* Serializes [value] to a string. Pretty prints if [pretty] is set.
*/
fun <T> ObjectMapper.stringify(value: T, pretty: Boolean = false): String {
val bos = ByteArrayOutputStream()
val writer = OutputStreamWriter(bos, StandardCharsets.UTF_8)
if(pretty) {
writerWithDefaultPrettyPrinter().writeValue(writer,value)
} else {
writeValue(writer, value)
}
writer.flush()
bos.flush()
return bos.toByteArray().toString(StandardCharsets.UTF_8)
}


UPDATE The code in the answer by @jayson-minard works. It turns out that the key difference with my code was that I defined the data classes inside the test method. Moving them outside to the top level fixes things. Putting a dataclass in a function was a bad idea to begin with.










share|improve this question
















I'm trying to use the jackson-kotlin integration. Mostly it works nice but I'm having trouble with deserializing generic types. I tried to adapt the answer to this question: Jackson - Deserialize using generic class



    // create an object mapper
val jsonFactory = JsonFactory()
jsonFactory.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false)
jsonFactory.configure(JsonParser.Feature.IGNORE_UNDEFINED, true)

val objectMapper = ObjectMapper(jsonFactory)
objectMapper.findAndRegisterModules()
objectMapper.propertyNamingStrategy = PropertyNamingStrategy.SnakeCaseStrategy()
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)

// simple generic type
data class Inner(val meaningOfLife: Int)
data class Outer<T>(val inner: T)

val outer = Outer(Inner(42))

val serialized = objectMapper.stringify(outer, true)
println(serialized)

// deserializing does not work using:
// https://stackoverflow.com/questions/11664894/jackson-deserialize-using-generic-class
val parsed = objectMapper.readValue<Outer<Inner>>(serialized, objectMapper.typeFactory.constructParametricType(Outer::class.java,Inner::class.java))


This throws an exception:



com.fasterxml.jackson.databind.JsonMappingException: Cannot deserialize Class io.inbot.common.ObjectMapperTest$should handle generics$Outer (of type local/anonymous) as a Bean
at [Source: (String)"{
"inner" : {
"meaning_of_life" : 42
}
}"; line: 1, column: 1]

at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:306)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:268)
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:477)
at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:4190)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4009)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3042)
at io.inbot.common.ObjectMapperTest.should handle generics(ObjectMapperTest.kt:22)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:580)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:716)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:988)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:648)
at org.testng.TestRunner.run(TestRunner.java:505)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)
Caused by: java.lang.IllegalArgumentException: Cannot deserialize Class io.inbot.common.ObjectMapperTest$should handle generics$Outer (of type local/anonymous) as a Bean
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.isPotentialBeanType(BeanDeserializerFactory.java:877)
at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:131)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:411)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:349)
at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)
... 31 more


Obviously the jackson plugin for kotlin does not handle this. Is there a workaround for this or a different way of doing this?



BTW. the stringify function is a simple extension function I added for ObjectMapper that takes care of the boilerplate code:



/**
* Serializes [value] to a string. Pretty prints if [pretty] is set.
*/
fun <T> ObjectMapper.stringify(value: T, pretty: Boolean = false): String {
val bos = ByteArrayOutputStream()
val writer = OutputStreamWriter(bos, StandardCharsets.UTF_8)
if(pretty) {
writerWithDefaultPrettyPrinter().writeValue(writer,value)
} else {
writeValue(writer, value)
}
writer.flush()
bos.flush()
return bos.toByteArray().toString(StandardCharsets.UTF_8)
}


UPDATE The code in the answer by @jayson-minard works. It turns out that the key difference with my code was that I defined the data classes inside the test method. Moving them outside to the top level fixes things. Putting a dataclass in a function was a bad idea to begin with.







generics kotlin jackson






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 27 '18 at 15:21







Jilles van Gurp

















asked Nov 27 '18 at 12:11









Jilles van GurpJilles van Gurp

5,42732639




5,42732639













  • Have you tried this without your type factory call, and let the readValue extension function just infer the reified type?

    – Jayson Minard
    Nov 27 '18 at 12:32











  • What version of Jackson are you using? what version of the Jackson-Kotlin module are you using? what version of Kotlin?

    – Jayson Minard
    Nov 27 '18 at 13:13











  • 2.9.7 of both, type inference does not work here because jackson has no way of knowing what the type is. Also Java 8, kotlin 1.3.10

    – Jilles van Gurp
    Nov 27 '18 at 15:09



















  • Have you tried this without your type factory call, and let the readValue extension function just infer the reified type?

    – Jayson Minard
    Nov 27 '18 at 12:32











  • What version of Jackson are you using? what version of the Jackson-Kotlin module are you using? what version of Kotlin?

    – Jayson Minard
    Nov 27 '18 at 13:13











  • 2.9.7 of both, type inference does not work here because jackson has no way of knowing what the type is. Also Java 8, kotlin 1.3.10

    – Jilles van Gurp
    Nov 27 '18 at 15:09

















Have you tried this without your type factory call, and let the readValue extension function just infer the reified type?

– Jayson Minard
Nov 27 '18 at 12:32





Have you tried this without your type factory call, and let the readValue extension function just infer the reified type?

– Jayson Minard
Nov 27 '18 at 12:32













What version of Jackson are you using? what version of the Jackson-Kotlin module are you using? what version of Kotlin?

– Jayson Minard
Nov 27 '18 at 13:13





What version of Jackson are you using? what version of the Jackson-Kotlin module are you using? what version of Kotlin?

– Jayson Minard
Nov 27 '18 at 13:13













2.9.7 of both, type inference does not work here because jackson has no way of knowing what the type is. Also Java 8, kotlin 1.3.10

– Jilles van Gurp
Nov 27 '18 at 15:09





2.9.7 of both, type inference does not work here because jackson has no way of knowing what the type is. Also Java 8, kotlin 1.3.10

– Jilles van Gurp
Nov 27 '18 at 15:09












1 Answer
1






active

oldest

votes


















1














Using 2.9.6 of Jackson and then also the master branch 2.9.8 of Jackson along with the current Jackson-Kotlin module, I added this test case which passes for both your version of the code, and the cleaner idiomatic version of the code.



Note that I updated the stringify method to be more idiomatic as well, but this would not affect the test.



Your call to readValue is also more complicated than neccessary. Change:





val parsed = objectMapper.readValue<Outer<Inner>>(serialized, objectMapper.typeFactory.constructParametricType(Outer::class.java, Inner::class.java))


to simply:



val parsed = objectMapper.readValue<Outer<Inner>>(serialized)    


This is the full passing tests:



class TestStackOverflow53499407 {
data class Inner(val meaningOfLife: Int)
data class Outer<T>(val inner: T)

fun <T> ObjectMapper.stringify(value: T, pretty: Boolean = false): String {
StringWriter().use { writer ->
if (pretty) {
writerWithDefaultPrettyPrinter().writeValue(writer, value)
} else {
writeValue(writer, value)
}
return writer.toString()
}
}

@Test
fun test53499407_cleanTest() {
val outer = Outer(Inner(42))
val objectMapper = jacksonObjectMapper()

val serialized = objectMapper.stringify(outer, true)
println(serialized)

val parsed = objectMapper.readValue<Outer<Inner>>(serialized)
assertEquals(42, parsed.inner.meaningOfLife)
}

@Test
fun test53499407_idiomatic_tweek() {
val outer = Outer(Inner(42))

val jsonFactory = JsonFactory()
jsonFactory.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false)
jsonFactory.configure(JsonParser.Feature.IGNORE_UNDEFINED, true)

val objectMapper = ObjectMapper(jsonFactory)
objectMapper.findAndRegisterModules()
objectMapper.propertyNamingStrategy = PropertyNamingStrategy.SnakeCaseStrategy()
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)

val serialized = objectMapper.stringify(outer, true)
println(serialized)

// This line changed to be idiomatic
val parsed = objectMapper.readValue<Outer<Inner>>(serialized)
assertEquals(42, parsed.inner.meaningOfLife)
}

@Test
fun test53499407_as_written_in_stackoverflow() {
val outer = Outer(Inner(42))

val jsonFactory = JsonFactory()
jsonFactory.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false)
jsonFactory.configure(JsonParser.Feature.IGNORE_UNDEFINED, true)

val objectMapper = ObjectMapper(jsonFactory)
objectMapper.findAndRegisterModules()
objectMapper.propertyNamingStrategy = PropertyNamingStrategy.SnakeCaseStrategy()
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)

val serialized = objectMapper.stringify(outer, true)
println(serialized)

// deserializing does not work using:
// https://stackoverflow.com/questions/11664894/jackson-deserialize-using-generic-class
val parsed = objectMapper.readValue<Outer<Inner>>(serialized, objectMapper.typeFactory.constructParametricType(Outer::class.java, Inner::class.java))
assertEquals(42, parsed.inner.meaningOfLife)
}
}


enter image description here






share|improve this answer


























  • Thanks for looking into this. I tried doing what you do with some variations of object mapper config and your nicer stringify but I always get this weird exception: java.lang.reflect.GenericSignatureFormatError: Signature Parse error: expected '<' or ';' but got Remaining input: handle generics$Outer<Lio/inbot/common/ObjectMapperTest$should handle generics$Inner;>;>; Deserializing to a non generic class works, i.e. nothing wrong with the string. So what's different on your setup? Java 8/kotlin 1.3.10 here.

    – Jilles van Gurp
    Nov 27 '18 at 15:08











  • I figured out the difference, putting the data class defiinitions in the test method as I did does not work. Moving them outside the function scope fixes things. Even my original version works that way. So it matters where you put the class definitions for deserialization.

    – Jilles van Gurp
    Nov 27 '18 at 15:15











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53499407%2fdeserialize-generic-class-using-jackson-module-kotlin%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









1














Using 2.9.6 of Jackson and then also the master branch 2.9.8 of Jackson along with the current Jackson-Kotlin module, I added this test case which passes for both your version of the code, and the cleaner idiomatic version of the code.



Note that I updated the stringify method to be more idiomatic as well, but this would not affect the test.



Your call to readValue is also more complicated than neccessary. Change:





val parsed = objectMapper.readValue<Outer<Inner>>(serialized, objectMapper.typeFactory.constructParametricType(Outer::class.java, Inner::class.java))


to simply:



val parsed = objectMapper.readValue<Outer<Inner>>(serialized)    


This is the full passing tests:



class TestStackOverflow53499407 {
data class Inner(val meaningOfLife: Int)
data class Outer<T>(val inner: T)

fun <T> ObjectMapper.stringify(value: T, pretty: Boolean = false): String {
StringWriter().use { writer ->
if (pretty) {
writerWithDefaultPrettyPrinter().writeValue(writer, value)
} else {
writeValue(writer, value)
}
return writer.toString()
}
}

@Test
fun test53499407_cleanTest() {
val outer = Outer(Inner(42))
val objectMapper = jacksonObjectMapper()

val serialized = objectMapper.stringify(outer, true)
println(serialized)

val parsed = objectMapper.readValue<Outer<Inner>>(serialized)
assertEquals(42, parsed.inner.meaningOfLife)
}

@Test
fun test53499407_idiomatic_tweek() {
val outer = Outer(Inner(42))

val jsonFactory = JsonFactory()
jsonFactory.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false)
jsonFactory.configure(JsonParser.Feature.IGNORE_UNDEFINED, true)

val objectMapper = ObjectMapper(jsonFactory)
objectMapper.findAndRegisterModules()
objectMapper.propertyNamingStrategy = PropertyNamingStrategy.SnakeCaseStrategy()
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)

val serialized = objectMapper.stringify(outer, true)
println(serialized)

// This line changed to be idiomatic
val parsed = objectMapper.readValue<Outer<Inner>>(serialized)
assertEquals(42, parsed.inner.meaningOfLife)
}

@Test
fun test53499407_as_written_in_stackoverflow() {
val outer = Outer(Inner(42))

val jsonFactory = JsonFactory()
jsonFactory.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false)
jsonFactory.configure(JsonParser.Feature.IGNORE_UNDEFINED, true)

val objectMapper = ObjectMapper(jsonFactory)
objectMapper.findAndRegisterModules()
objectMapper.propertyNamingStrategy = PropertyNamingStrategy.SnakeCaseStrategy()
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)

val serialized = objectMapper.stringify(outer, true)
println(serialized)

// deserializing does not work using:
// https://stackoverflow.com/questions/11664894/jackson-deserialize-using-generic-class
val parsed = objectMapper.readValue<Outer<Inner>>(serialized, objectMapper.typeFactory.constructParametricType(Outer::class.java, Inner::class.java))
assertEquals(42, parsed.inner.meaningOfLife)
}
}


enter image description here






share|improve this answer


























  • Thanks for looking into this. I tried doing what you do with some variations of object mapper config and your nicer stringify but I always get this weird exception: java.lang.reflect.GenericSignatureFormatError: Signature Parse error: expected '<' or ';' but got Remaining input: handle generics$Outer<Lio/inbot/common/ObjectMapperTest$should handle generics$Inner;>;>; Deserializing to a non generic class works, i.e. nothing wrong with the string. So what's different on your setup? Java 8/kotlin 1.3.10 here.

    – Jilles van Gurp
    Nov 27 '18 at 15:08











  • I figured out the difference, putting the data class defiinitions in the test method as I did does not work. Moving them outside the function scope fixes things. Even my original version works that way. So it matters where you put the class definitions for deserialization.

    – Jilles van Gurp
    Nov 27 '18 at 15:15
















1














Using 2.9.6 of Jackson and then also the master branch 2.9.8 of Jackson along with the current Jackson-Kotlin module, I added this test case which passes for both your version of the code, and the cleaner idiomatic version of the code.



Note that I updated the stringify method to be more idiomatic as well, but this would not affect the test.



Your call to readValue is also more complicated than neccessary. Change:





val parsed = objectMapper.readValue<Outer<Inner>>(serialized, objectMapper.typeFactory.constructParametricType(Outer::class.java, Inner::class.java))


to simply:



val parsed = objectMapper.readValue<Outer<Inner>>(serialized)    


This is the full passing tests:



class TestStackOverflow53499407 {
data class Inner(val meaningOfLife: Int)
data class Outer<T>(val inner: T)

fun <T> ObjectMapper.stringify(value: T, pretty: Boolean = false): String {
StringWriter().use { writer ->
if (pretty) {
writerWithDefaultPrettyPrinter().writeValue(writer, value)
} else {
writeValue(writer, value)
}
return writer.toString()
}
}

@Test
fun test53499407_cleanTest() {
val outer = Outer(Inner(42))
val objectMapper = jacksonObjectMapper()

val serialized = objectMapper.stringify(outer, true)
println(serialized)

val parsed = objectMapper.readValue<Outer<Inner>>(serialized)
assertEquals(42, parsed.inner.meaningOfLife)
}

@Test
fun test53499407_idiomatic_tweek() {
val outer = Outer(Inner(42))

val jsonFactory = JsonFactory()
jsonFactory.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false)
jsonFactory.configure(JsonParser.Feature.IGNORE_UNDEFINED, true)

val objectMapper = ObjectMapper(jsonFactory)
objectMapper.findAndRegisterModules()
objectMapper.propertyNamingStrategy = PropertyNamingStrategy.SnakeCaseStrategy()
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)

val serialized = objectMapper.stringify(outer, true)
println(serialized)

// This line changed to be idiomatic
val parsed = objectMapper.readValue<Outer<Inner>>(serialized)
assertEquals(42, parsed.inner.meaningOfLife)
}

@Test
fun test53499407_as_written_in_stackoverflow() {
val outer = Outer(Inner(42))

val jsonFactory = JsonFactory()
jsonFactory.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false)
jsonFactory.configure(JsonParser.Feature.IGNORE_UNDEFINED, true)

val objectMapper = ObjectMapper(jsonFactory)
objectMapper.findAndRegisterModules()
objectMapper.propertyNamingStrategy = PropertyNamingStrategy.SnakeCaseStrategy()
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)

val serialized = objectMapper.stringify(outer, true)
println(serialized)

// deserializing does not work using:
// https://stackoverflow.com/questions/11664894/jackson-deserialize-using-generic-class
val parsed = objectMapper.readValue<Outer<Inner>>(serialized, objectMapper.typeFactory.constructParametricType(Outer::class.java, Inner::class.java))
assertEquals(42, parsed.inner.meaningOfLife)
}
}


enter image description here






share|improve this answer


























  • Thanks for looking into this. I tried doing what you do with some variations of object mapper config and your nicer stringify but I always get this weird exception: java.lang.reflect.GenericSignatureFormatError: Signature Parse error: expected '<' or ';' but got Remaining input: handle generics$Outer<Lio/inbot/common/ObjectMapperTest$should handle generics$Inner;>;>; Deserializing to a non generic class works, i.e. nothing wrong with the string. So what's different on your setup? Java 8/kotlin 1.3.10 here.

    – Jilles van Gurp
    Nov 27 '18 at 15:08











  • I figured out the difference, putting the data class defiinitions in the test method as I did does not work. Moving them outside the function scope fixes things. Even my original version works that way. So it matters where you put the class definitions for deserialization.

    – Jilles van Gurp
    Nov 27 '18 at 15:15














1












1








1







Using 2.9.6 of Jackson and then also the master branch 2.9.8 of Jackson along with the current Jackson-Kotlin module, I added this test case which passes for both your version of the code, and the cleaner idiomatic version of the code.



Note that I updated the stringify method to be more idiomatic as well, but this would not affect the test.



Your call to readValue is also more complicated than neccessary. Change:





val parsed = objectMapper.readValue<Outer<Inner>>(serialized, objectMapper.typeFactory.constructParametricType(Outer::class.java, Inner::class.java))


to simply:



val parsed = objectMapper.readValue<Outer<Inner>>(serialized)    


This is the full passing tests:



class TestStackOverflow53499407 {
data class Inner(val meaningOfLife: Int)
data class Outer<T>(val inner: T)

fun <T> ObjectMapper.stringify(value: T, pretty: Boolean = false): String {
StringWriter().use { writer ->
if (pretty) {
writerWithDefaultPrettyPrinter().writeValue(writer, value)
} else {
writeValue(writer, value)
}
return writer.toString()
}
}

@Test
fun test53499407_cleanTest() {
val outer = Outer(Inner(42))
val objectMapper = jacksonObjectMapper()

val serialized = objectMapper.stringify(outer, true)
println(serialized)

val parsed = objectMapper.readValue<Outer<Inner>>(serialized)
assertEquals(42, parsed.inner.meaningOfLife)
}

@Test
fun test53499407_idiomatic_tweek() {
val outer = Outer(Inner(42))

val jsonFactory = JsonFactory()
jsonFactory.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false)
jsonFactory.configure(JsonParser.Feature.IGNORE_UNDEFINED, true)

val objectMapper = ObjectMapper(jsonFactory)
objectMapper.findAndRegisterModules()
objectMapper.propertyNamingStrategy = PropertyNamingStrategy.SnakeCaseStrategy()
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)

val serialized = objectMapper.stringify(outer, true)
println(serialized)

// This line changed to be idiomatic
val parsed = objectMapper.readValue<Outer<Inner>>(serialized)
assertEquals(42, parsed.inner.meaningOfLife)
}

@Test
fun test53499407_as_written_in_stackoverflow() {
val outer = Outer(Inner(42))

val jsonFactory = JsonFactory()
jsonFactory.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false)
jsonFactory.configure(JsonParser.Feature.IGNORE_UNDEFINED, true)

val objectMapper = ObjectMapper(jsonFactory)
objectMapper.findAndRegisterModules()
objectMapper.propertyNamingStrategy = PropertyNamingStrategy.SnakeCaseStrategy()
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)

val serialized = objectMapper.stringify(outer, true)
println(serialized)

// deserializing does not work using:
// https://stackoverflow.com/questions/11664894/jackson-deserialize-using-generic-class
val parsed = objectMapper.readValue<Outer<Inner>>(serialized, objectMapper.typeFactory.constructParametricType(Outer::class.java, Inner::class.java))
assertEquals(42, parsed.inner.meaningOfLife)
}
}


enter image description here






share|improve this answer















Using 2.9.6 of Jackson and then also the master branch 2.9.8 of Jackson along with the current Jackson-Kotlin module, I added this test case which passes for both your version of the code, and the cleaner idiomatic version of the code.



Note that I updated the stringify method to be more idiomatic as well, but this would not affect the test.



Your call to readValue is also more complicated than neccessary. Change:





val parsed = objectMapper.readValue<Outer<Inner>>(serialized, objectMapper.typeFactory.constructParametricType(Outer::class.java, Inner::class.java))


to simply:



val parsed = objectMapper.readValue<Outer<Inner>>(serialized)    


This is the full passing tests:



class TestStackOverflow53499407 {
data class Inner(val meaningOfLife: Int)
data class Outer<T>(val inner: T)

fun <T> ObjectMapper.stringify(value: T, pretty: Boolean = false): String {
StringWriter().use { writer ->
if (pretty) {
writerWithDefaultPrettyPrinter().writeValue(writer, value)
} else {
writeValue(writer, value)
}
return writer.toString()
}
}

@Test
fun test53499407_cleanTest() {
val outer = Outer(Inner(42))
val objectMapper = jacksonObjectMapper()

val serialized = objectMapper.stringify(outer, true)
println(serialized)

val parsed = objectMapper.readValue<Outer<Inner>>(serialized)
assertEquals(42, parsed.inner.meaningOfLife)
}

@Test
fun test53499407_idiomatic_tweek() {
val outer = Outer(Inner(42))

val jsonFactory = JsonFactory()
jsonFactory.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false)
jsonFactory.configure(JsonParser.Feature.IGNORE_UNDEFINED, true)

val objectMapper = ObjectMapper(jsonFactory)
objectMapper.findAndRegisterModules()
objectMapper.propertyNamingStrategy = PropertyNamingStrategy.SnakeCaseStrategy()
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)

val serialized = objectMapper.stringify(outer, true)
println(serialized)

// This line changed to be idiomatic
val parsed = objectMapper.readValue<Outer<Inner>>(serialized)
assertEquals(42, parsed.inner.meaningOfLife)
}

@Test
fun test53499407_as_written_in_stackoverflow() {
val outer = Outer(Inner(42))

val jsonFactory = JsonFactory()
jsonFactory.configure(JsonGenerator.Feature.AUTO_CLOSE_TARGET, false)
jsonFactory.configure(JsonParser.Feature.IGNORE_UNDEFINED, true)

val objectMapper = ObjectMapper(jsonFactory)
objectMapper.findAndRegisterModules()
objectMapper.propertyNamingStrategy = PropertyNamingStrategy.SnakeCaseStrategy()
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)

val serialized = objectMapper.stringify(outer, true)
println(serialized)

// deserializing does not work using:
// https://stackoverflow.com/questions/11664894/jackson-deserialize-using-generic-class
val parsed = objectMapper.readValue<Outer<Inner>>(serialized, objectMapper.typeFactory.constructParametricType(Outer::class.java, Inner::class.java))
assertEquals(42, parsed.inner.meaningOfLife)
}
}


enter image description here







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 27 '18 at 13:25

























answered Nov 27 '18 at 13:20









Jayson MinardJayson Minard

40.5k17114174




40.5k17114174













  • Thanks for looking into this. I tried doing what you do with some variations of object mapper config and your nicer stringify but I always get this weird exception: java.lang.reflect.GenericSignatureFormatError: Signature Parse error: expected '<' or ';' but got Remaining input: handle generics$Outer<Lio/inbot/common/ObjectMapperTest$should handle generics$Inner;>;>; Deserializing to a non generic class works, i.e. nothing wrong with the string. So what's different on your setup? Java 8/kotlin 1.3.10 here.

    – Jilles van Gurp
    Nov 27 '18 at 15:08











  • I figured out the difference, putting the data class defiinitions in the test method as I did does not work. Moving them outside the function scope fixes things. Even my original version works that way. So it matters where you put the class definitions for deserialization.

    – Jilles van Gurp
    Nov 27 '18 at 15:15



















  • Thanks for looking into this. I tried doing what you do with some variations of object mapper config and your nicer stringify but I always get this weird exception: java.lang.reflect.GenericSignatureFormatError: Signature Parse error: expected '<' or ';' but got Remaining input: handle generics$Outer<Lio/inbot/common/ObjectMapperTest$should handle generics$Inner;>;>; Deserializing to a non generic class works, i.e. nothing wrong with the string. So what's different on your setup? Java 8/kotlin 1.3.10 here.

    – Jilles van Gurp
    Nov 27 '18 at 15:08











  • I figured out the difference, putting the data class defiinitions in the test method as I did does not work. Moving them outside the function scope fixes things. Even my original version works that way. So it matters where you put the class definitions for deserialization.

    – Jilles van Gurp
    Nov 27 '18 at 15:15

















Thanks for looking into this. I tried doing what you do with some variations of object mapper config and your nicer stringify but I always get this weird exception: java.lang.reflect.GenericSignatureFormatError: Signature Parse error: expected '<' or ';' but got Remaining input: handle generics$Outer<Lio/inbot/common/ObjectMapperTest$should handle generics$Inner;>;>; Deserializing to a non generic class works, i.e. nothing wrong with the string. So what's different on your setup? Java 8/kotlin 1.3.10 here.

– Jilles van Gurp
Nov 27 '18 at 15:08





Thanks for looking into this. I tried doing what you do with some variations of object mapper config and your nicer stringify but I always get this weird exception: java.lang.reflect.GenericSignatureFormatError: Signature Parse error: expected '<' or ';' but got Remaining input: handle generics$Outer<Lio/inbot/common/ObjectMapperTest$should handle generics$Inner;>;>; Deserializing to a non generic class works, i.e. nothing wrong with the string. So what's different on your setup? Java 8/kotlin 1.3.10 here.

– Jilles van Gurp
Nov 27 '18 at 15:08













I figured out the difference, putting the data class defiinitions in the test method as I did does not work. Moving them outside the function scope fixes things. Even my original version works that way. So it matters where you put the class definitions for deserialization.

– Jilles van Gurp
Nov 27 '18 at 15:15





I figured out the difference, putting the data class defiinitions in the test method as I did does not work. Moving them outside the function scope fixes things. Even my original version works that way. So it matters where you put the class definitions for deserialization.

– Jilles van Gurp
Nov 27 '18 at 15:15




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53499407%2fdeserialize-generic-class-using-jackson-module-kotlin%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

Calculate evaluation metrics using cross_val_predict sklearn

Insert data from modal to MySQL (multiple modal on website)