question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Cannot use untyped informers along with typed API

See original GitHub issue

Describe the bug

Using informers for GenericKubernetesResources along with accesses to the typed API result in deserialization errors (of the GenericKubernetesResource) showing that the typed Deserializer has been invoked.

Fabric8 Kubernetes Client version

next (development version)

Steps to reproduce

(with access to a cluster e.g. minikube):

  1. Clone https://github.com/andreaTP/repro_GenericKubernetesResource_deser
  2. mvn clean compile
  3. kubectl apply -f target/classes/META-INF/fabric8/examples.org.example-v1.yml
  4. mvn clean compile exec:java

Expected behavior

The informer should deserialize the GenericKubernetesResource without trying to use the “typed” deserializer.

Runtime

Kubernetes (vanilla), minikube, other (please specify in additional context)

Kubernetes API Server version

next (development version)

Environment

macOS

Fabric8 Kubernetes Client Logs

2022-01-25 14:42:22,600 ERROR [AbstractWatchManager] - Unhandled exception encountered in watcher event handler
io.fabric8.kubernetes.client.KubernetesClientException: An error has occurred.
        at io.fabric8.kubernetes.client.KubernetesClientException.launderThrowable(KubernetesClientException.java:103)
        at io.fabric8.kubernetes.client.KubernetesClientException.launderThrowable(KubernetesClientException.java:97)
        at io.fabric8.kubernetes.client.utils.Serialization.unmarshal(Serialization.java:319)
        at io.fabric8.kubernetes.client.utils.Serialization.unmarshal(Serialization.java:240)
        at io.fabric8.kubernetes.client.utils.Serialization.unmarshal(Serialization.java:226)
        at io.fabric8.kubernetes.client.dsl.internal.AbstractWatchManager.readWatchEvent(AbstractWatchManager.java:237)
        at io.fabric8.kubernetes.client.dsl.internal.AbstractWatchManager.onMessage(AbstractWatchManager.java:262)
        at io.fabric8.kubernetes.client.dsl.internal.WatcherWebSocketListener.onMessage(WatcherWebSocketListener.java:68)
        at io.fabric8.kubernetes.client.okhttp.OkHttpWebSocketImpl$BuilderImpl$1.onMessage(OkHttpWebSocketImpl.java:96)
        at okhttp3.internal.ws.RealWebSocket.onReadMessage(RealWebSocket.java:323)
        at okhttp3.internal.ws.WebSocketReader.readMessageFrame(WebSocketReader.java:219)
        at okhttp3.internal.ws.WebSocketReader.processNextFrame(WebSocketReader.java:105)
        at okhttp3.internal.ws.RealWebSocket.loopReader(RealWebSocket.java:274)
        at okhttp3.internal.ws.RealWebSocket$2.onResponse(RealWebSocket.java:214)
        at okhttp3.RealCall$AsyncCall.execute(RealCall.java:203)
        at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:829)
Caused by: com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `int` from String "hello": not a valid `int` value
 at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: io.fabric8.kubernetes.api.model.WatchEvent["object"]->org.test.v1alpha1.crd.Example["spec"]->org.test.v1alpha1.crd.ExampleSpec["foo"])
        at com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:67)
        at com.fasterxml.jackson.databind.DeserializationContext.weirdStringException(DeserializationContext.java:1991)
        at com.fasterxml.jackson.databind.DeserializationContext.handleWeirdStringValue(DeserializationContext.java:1219)
        at com.fasterxml.jackson.databind.deser.std.StdDeserializer._parseIntPrimitive(StdDeserializer.java:768)
        at com.fasterxml.jackson.databind.deser.std.StdDeserializer._parseIntPrimitive(StdDeserializer.java:747)
        at com.fasterxml.jackson.databind.deser.std.NumberDeserializers$IntegerDeserializer.deserialize(NumberDeserializers.java:529)
        at com.fasterxml.jackson.databind.deser.std.NumberDeserializers$IntegerDeserializer.deserialize(NumberDeserializers.java:506)
        at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:138)
        at io.fabric8.kubernetes.client.utils.serialization.SettableBeanPropertyDelegate.deserializeAndSet(SettableBeanPropertyDelegate.java:131)
        at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:313)
        at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:176)
        at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
        at io.fabric8.kubernetes.client.utils.serialization.SettableBeanPropertyDelegate.deserializeAndSet(SettableBeanPropertyDelegate.java:131)
        at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:313)
        at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:176)
        at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:322)
        at com.fasterxml.jackson.databind.ObjectMapper._readValue(ObjectMapper.java:4650)
        at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2831)
        at com.fasterxml.jackson.databind.ObjectMapper.treeToValue(ObjectMapper.java:3295)
        at io.fabric8.kubernetes.internal.KubernetesDeserializer.fromObjectNode(KubernetesDeserializer.java:99)
        at io.fabric8.kubernetes.internal.KubernetesDeserializer.deserialize(KubernetesDeserializer.java:63)
        at io.fabric8.kubernetes.internal.KubernetesDeserializer.deserialize(KubernetesDeserializer.java:45)
        at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:129)
        at io.fabric8.kubernetes.client.utils.serialization.SettableBeanPropertyDelegate.deserializeAndSet(SettableBeanPropertyDelegate.java:131)
        at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:313)
        at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:176)
        at com.fasterxml.jackson.databind.deser.DefaultDeserializationContext.readRootValue(DefaultDeserializationContext.java:322)
        at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4674)
        at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3674)
        at io.fabric8.kubernetes.client.utils.Serialization.unmarshal(Serialization.java:317)
        ... 16 common frames omitted

Additional context

Found this issue while trying to support multiple CRD versions in the JO SDK. It’s extremely nasty to debug since removing the access to the “typed” API everything works as expected.

cc. @shawkins @metacosm @csviri

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:7 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
shawkinscommented, Jan 25, 2022

It doesn’t seem possible in general to bring a typed api into this scenario as it won’t be handled as expected.

If you enable trace you see:

POST https://192.168.39.42:8443/apis/org.example/v2alpha1/namespaces/default/examples -- to create the v2alpha1 entry

If you run again, the list operation from the watch or the typed api call, will issue a get:

https://192.168.39.42:8443/apis/org.example/v1alpha1/namespaces/default/examples 

That response contains:

INFO: {"apiVersion":"org.example/v1alpha1","items":[{"apiVersion":"org.example/v1alpha1","kind":"Example","metadata":{"creationTimestamp":"2022-01-25T19:03:26Z","generation":1,"managedFields":[{"apiVersion":"org.example/v2alpha1","fieldsType":"FieldsV1","fieldsV1":{"f:spec":{".":{},"f:bar":{},"f:baz":{},"f:foo":{}}},"manager":"okhttp","operation":"Update","time":"2022-01-25T19:03:26Z"}],"name":"test-example-v2alpha1","namespace":"default","resourceVersion":"761207","uid":"ca50ae40-4b95-4157-b61c-4ca4ed001fce"},"spec":{"bar":123456,"foo":"hello"}}],"kind":"ExampleList","metadata":{"continue":"","resourceVersion":"761282"}}

Which is reportedly v1alpha1, but the content is invalid for v1alpha1. This seems expected when you request the non-stored version and there is no conversion strategy.

0reactions
shawkinscommented, Mar 1, 2022

Resolved with #3786

Read more comments on GitHub >

github_iconTop Results From Across the Web

Bountysource
Cannot use untyped informers along with typed API.
Read more >
kubernetes-client/CHANGELOG.md at master - GitHub
Java client for Kubernetes & OpenShift . Contribute to fabric8io/kubernetes-client development by creating an account on GitHub.
Read more >
Cannot convert (untyped string constant) to *string [duplicate]
You cannot get the address of a string constant/literal, but if you have a string local variable (set to the value you want)...
Read more >
Update Informer for CLI Applications Written In Rust - Morioh
In this library, We will share the archive for Update informer for CLI Applications Written In Rust. It checks for a new version...
Read more >
Generics are overrated. - Google Groups
You cannot achieve generic behavior without some form of generics. Look at sync.Map it's not compile time type safe. With generics it would...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found