-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Description
Describe the bug
I'm using the jackson-module-kotlin, registered in KubernetesSerialization
. When deserializing a kotlin object, the SettableBeanPropertyDelegate
that is added here does not properly delegate some functions from jackson (in this case, getCreatorIndex()
). These are implemented with a default value by jackson, but they can be overridden by special properties, like kotlin constructor properties.
Fabric8 Kubernetes Client version
6.13.3
Steps to reproduce
- Have a CRD represented by a kotlin data class
- Try to serialize/deserialize that resource using the KubernetesSerialization
Expected behavior
I think this is a simple oversight, and the delegate is probably supposed implement and delegate all the functions.
Runtime
other (please specify in additional context)
Kubernetes API Server version
other (please specify in additional context)
Environment
other (please specify in additional context)
Fabric8 Kubernetes Client Logs
io.fabric8.kubernetes.client.KubernetesClientException: An error has occurred.
at io.fabric8.kubernetes.client.KubernetesClientException.launderThrowable(KubernetesClientException.java:129)
at io.fabric8.kubernetes.client.KubernetesClientException.launderThrowable(KubernetesClientException.java:122)
at io.fabric8.kubernetes.client.utils.KubernetesSerialization.unmarshal(KubernetesSerialization.java:261)
at io.fabric8.kubernetes.client.dsl.internal.OperationSupport.lambda$handleResponse$0(OperationSupport.java:551)
at java.base/java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:646)
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2179)
at io.fabric8.kubernetes.client.http.StandardHttpClient.lambda$completeOrCancel$10(StandardHttpClient.java:142)
at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863)
at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:841)
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2179)
at io.fabric8.kubernetes.client.http.ByteArrayBodyHandler.onBodyDone(ByteArrayBodyHandler.java:51)
at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:863)
at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:841)
at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:510)
at java.base/java.util.concurrent.CompletableFuture.complete(CompletableFuture.java:2179)
at io.fabric8.kubernetes.client.okhttp.OkHttpClientImpl$OkHttpAsyncBody.doConsume(OkHttpClientImpl.java:136)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Internal error: no creator index for property 'enabled' (of type io.fabric8.kubernetes.model.jackson.SettableBeanPropertyDelegate) (through reference chain: ...)
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:402)
at com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:361)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.wrapAndThrow(BeanDeserializerBase.java:1964)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeWithErrorWrapping(BeanDeserializer.java:580)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:447)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1497)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:348)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:185)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
at io.fabric8.kubernetes.model.jackson.SettableBeanPropertyDelegate.deserializeAndSet(SettableBeanPropertyDelegate.java:134)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:310)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:177)
at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:342)
at com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:2125)
at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1501)
at io.fabric8.kubernetes.client.utils.KubernetesSerialization.unmarshal(KubernetesSerialization.java:257)
... 18 more
Caused by: java.lang.IllegalStateException: Internal error: no creator index for property 'enabled' (of type io.fabric8.kubernetes.model.jackson.SettableBeanPropertyDelegate)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.getCreatorIndex(SettableBeanProperty.java:450)
at com.fasterxml.jackson.databind.deser.impl.PropertyValueBuffer.assignParameter(PropertyValueBuffer.java:327)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeUsingPropertyBased(BeanDeserializer.java:449)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:1497)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:348)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:185)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:543)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeWithErrorWrapping(BeanDeserializer.java:578)
... 30 more
Additional context
This is happening anywhere and is not really platform-dependent.
Jackson provides SettableBeanProperty.Delegating
for reliably delegating all properties, and using it as a supertype I fixed the issue (although registering this was a bit hacky). The delegate I'm using instead of SettableBeanPropertyDelegate looks like this:
open class JacksonSettableBeanPropertyDelegate(
delegate: SettableBeanProperty,
private val anySetter: SettableAnyProperty?,
private val useAnySetter: BooleanSupplier,
) : SettableBeanProperty.Delegating(delegate) {
override fun withDelegate(d: SettableBeanProperty): SettableBeanProperty {
return JacksonSettableBeanPropertyDelegate(d, anySetter, useAnySetter)
}
@Throws(IOException::class)
override fun deserializeAndSet(p: JsonParser, ctxt: DeserializationContext?, instance: Any?) {
try {
delegate.deserializeAndSet(p, ctxt, instance)
} catch (ex: MismatchedInputException) {
if (shouldUseAnySetter()) {
anySetter!![instance, delegate.name] = p.text
} else {
throw ex
}
}
}
@Throws(IOException::class)
override fun deserializeSetAndReturn(p: JsonParser?, ctxt: DeserializationContext?, instance: Any?): Any? {
try {
return delegate.deserializeSetAndReturn(p, ctxt, instance)
} catch (ex: MismatchedInputException) {
deserializeAndSet(p!!, ctxt, instance)
}
return null
}
private fun shouldUseAnySetter(): Boolean {
if (anySetter == null) {
return false
}
return useAnySetter.asBoolean
}
}