Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client can't deserialize GraphQL response #850

Closed
hrkfdn opened this issue Aug 28, 2020 · 15 comments · Fixed by #898
Closed

Client can't deserialize GraphQL response #850

hrkfdn opened this issue Aug 28, 2020 · 15 comments · Fixed by #898
Labels
status: blocked upstream We can not resolve until another outside issue is complete type: bug Something isn't working

Comments

@hrkfdn
Copy link

hrkfdn commented Aug 28, 2020

Hi, I'm having some trouble with the GraphQL client (version 3.6.1). I'm getting an exception when GraphQLClient is trying to deserialize the response data to GraphQLResponse<HubCheckOut.Result>. The model itself looks fine and matches the JSON, but for some reason Jackson is not able to map it.

If I use a debugger to manually serialize to Map<String, Any> with the mapper it works, so the JSON is fine. Any ideas?

This is the generated model class:

const val HUB_CHECK_OUT: String =
    "mutation HubCheckOut(${'$'}hubID: ID!, ${'$'}employeeID: ID!) {\n    insertHubCheckedOutLogRecord(input: {hubId: ${'$'}hubID, employeeId: ${'$'}employeeID}) {\n        record {\n            shiftId\n        }\n    }\n}"

class HubCheckOut(
  private val graphQLClient: GraphQLClient<*>
) {
  suspend fun execute(variables: HubCheckOut.Variables, requestBuilder: HttpRequestBuilder.() ->
      Unit = {}): GraphQLResponse<HubCheckOut.Result> = graphQLClient.execute(HUB_CHECK_OUT,
      "HubCheckOut", variables, requestBuilder)

  data class Variables(
    val hubID: ID,
    val employeeID: ID
  )

  data class ShiftStateHubLogRecord(
    val shiftId: ID?
  )

  data class InsertHubLogCheckedOutRecordResponse(
    val record: HubCheckOut.ShiftStateHubLogRecord
  )

  data class Result(
    val insertHubCheckedOutLogRecord: HubCheckOut.InsertHubLogCheckedOutRecordResponse?
  )
}

And the exception:

Strange Map type java.util.Map: cannot determine type parameters
 at [Source: (String)"{"data":{"insertHubCheckedOutLogRecord":{"record":{"shiftId":"6387e498-2ac2-3c76-9b9e-f5248a348f8b"}}}}"; line: 1, column: 1]
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Strange Map type java.util.Map: cannot determine type parameters
 at [Source: (String)"{"data":{"insertHubCheckedOutLogRecord":{"record":{"shiftId":"6387e498-2ac2-3c76-9b9e-f5248a348f8b"}}}}"; line: 1, column: 1]
	at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:62)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:227)
	at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:143)
	at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:414)
	at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:349)
	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:491)
	at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:4711)
	at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4520)
	at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3466)
	at com.expediagroup.graphql.client.GraphQLClient.execute$suspendImpl(GraphQLClient.kt:91)
	at com.expediagroup.graphql.client.GraphQLClient$execute$1.invokeSuspend(GraphQLClient.kt)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(PipelineContext.kt:216)
	at io.ktor.util.pipeline.SuspendFunctionGun.loop(PipelineContext.kt:172)
	at io.ktor.util.pipeline.SuspendFunctionGun.access$loop(PipelineContext.kt:67)
	at io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(PipelineContext.kt:122)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
	at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(PipelineContext.kt:216)
	at io.ktor.util.pipeline.SuspendFunctionGun.loop(PipelineContext.kt:172)
	at io.ktor.util.pipeline.SuspendFunctionGun.access$loop(PipelineContext.kt:67)
	at io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(PipelineContext.kt:122)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
	at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(PipelineContext.kt:216)
	at io.ktor.util.pipeline.SuspendFunctionGun.loop(PipelineContext.kt:172)
	at io.ktor.util.pipeline.SuspendFunctionGun.access$loop(PipelineContext.kt:67)
	at io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(PipelineContext.kt:122)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
	at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(PipelineContext.kt:216)
	at io.ktor.util.pipeline.SuspendFunctionGun.loop(PipelineContext.kt:172)
	at io.ktor.util.pipeline.SuspendFunctionGun.access$loop(PipelineContext.kt:67)
	at io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(PipelineContext.kt:122)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
	at io.ktor.util.pipeline.SuspendFunctionGun.resumeRootWith(PipelineContext.kt:216)
	at io.ktor.util.pipeline.SuspendFunctionGun.loop(PipelineContext.kt:172)
	at io.ktor.util.pipeline.SuspendFunctionGun.access$loop(PipelineContext.kt:67)
	at io.ktor.util.pipeline.SuspendFunctionGun$continuation$1.resumeWith(PipelineContext.kt:122)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:46)
	at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
	at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:274)
	at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:84)
	at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
	at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source)
	at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
	at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source)
	at io.moia.driver.shift.validation.apitest.TestRun.start(TestRun.kt:94)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:686)
	at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
	at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
	at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
	at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
	at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
	at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:212)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:208)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:137)
	at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:71)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
	at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
	at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
	at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
	at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
	at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
	at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:220)
	at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:188)
	at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:202)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:181)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
	at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
	at com.sun.proxy.$Proxy5.stop(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:132)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182)
	at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164)
	at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:412)
	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)
	at java.base/java.lang.Thread.run(Thread.java:834)
@dariuszkuc dariuszkuc added type: bug Something isn't working and removed type: question labels Aug 28, 2020
@dariuszkuc
Copy link
Collaborator

Hello! Thanks for raising this, indeed this is a bug - there appears to be a change in behavior between Jackson 2.11.1 and 2.11.2 see FasterXML/jackson-databind#2821

In 3.6.1 we are using version 2.11.0 so can you verify whether you are pulling in newer Jackson dependencies? (if yes you will need to explicitly downgrade)

@hrkfdn
Copy link
Author

hrkfdn commented Aug 28, 2020

Yes, the project uses 2.11.2.

Edit: Thanks, force-downgrading fixed the issue.

@smyrick smyrick added the status: blocked upstream We can not resolve until another outside issue is complete label Aug 28, 2020
@angelu25
Copy link

How did you do the force-downgrading?

@hrkfdn
Copy link
Author

hrkfdn commented Aug 31, 2020

How did you do the force-downgrading?

I added this explicit import in my build.gradle:

implementation('com.fasterxml.jackson.core:jackson-databind:2.11.1') {
    version {
        strictly "2.11.1"
    }
}

@angelu25
Copy link

angelu25 commented Sep 1, 2020

image

Error:
image

Still not working. This is my Gradle. Could you help me there?

@angelu25
Copy link

angelu25 commented Sep 1, 2020

A simplified version:
image
Now dependencies seems to be 2.11.0 for Jackson (no matter if I force or not), but still receiving above issue :(

It is when trying to consume a generated client which is based on https://countries-274616.ew.r.appspot.com/?query=query%20%7B%0A%09Country%20%7B%0A%20%20%20%20name%0A%20%20%20%20%23%20check%20the%20docs%20for%20more%20info%0A%20%20%7D%0A%7D%0A

Any help?

@angelu25
Copy link

angelu25 commented Sep 1, 2020

If I do try with another query which is not exposing a List then it will work, but why is it failing for lists? The above link is the example which is failing.

Example working:
https://countries.trevorblades.com
{
country(code:"DE") {
name
}
}

Example failing:
https://countries-274616.ew.r.appspot.com/
query {
Country {
name
}
}

@dariuszkuc
Copy link
Collaborator

@angelu25 can you provide a sample project that reproduces the issue? Your gradle file looks correct.

I've updated client examples to verify that lists works as expected -> #859

@angelu25
Copy link

angelu25 commented Sep 2, 2020

If you just build a quick client against above endpoints then it should give the same issue there

@smyrick
Copy link
Contributor

smyrick commented Sep 3, 2020

@angelu25 Can you provide an example repo with a branch where we can debug the issue locally.

dariuszkuc added a commit to dariuszkuc/graphql-kotlin that referenced this issue Oct 6, 2020
Also updates Jackson dependency to `2.11.3`.

Resolves: ExpediaGroup#850
smyrick pushed a commit that referenced this issue Oct 7, 2020
* [server] update to SpringBoot 2.3

Also updates Jackson dependency to `2.11.3`.

Resolves: #850

* add missing validation dependency and cleanup spark dependencies
huehnerlady pushed a commit to huehnerlady/graphql-kotlin that referenced this issue Oct 16, 2020
* [server] update to SpringBoot 2.3

Also updates Jackson dependency to `2.11.3`.

Resolves: ExpediaGroup#850

* add missing validation dependency and cleanup spark dependencies
nutgaard added a commit to navikt/modiapersonoversikt-api that referenced this issue Oct 19, 2020
spring-boot-dependencies setter jackson til 2.11.2 som inneholder en liten bugg.
buggen gjør at deserialisering av graphqlResponses ikke fungerer som forventet.
Les mer;
ExpediaGroup/graphql-kotlin#850
FasterXML/jackson-databind#2821
@ValentinaBaranova
Copy link

Works with Jackson 2.11.3 too

@arshtepe
Copy link

arshtepe commented Dec 25, 2020

I still have same issue with jackson 2.11.3 and gql kotlin 4.0.0-alpha.8 . I made demo to reproduce it. Instead of gql server it returns same json as I am receiving from shopify https://github.com/arshtepe/bug-demo

@smyrick
Copy link
Contributor

smyrick commented Dec 26, 2020

@arshtepe Can you try using Jackson 2.11.2

@dariuszkuc
Copy link
Collaborator

@arshtepe as mentioned above, the underlying issue is with jackson-databind version 2.11.2. Even though you explicitly bring in the new Kotlin Jackson module, if you look at your project dependencies you will notice that it still uses old version of jackson-databind (most likely its managed by Spring).

You can either try upgrading to Spring Boot 2.4.0+ which bumps Jackson to 2.11.3 or explicitly add Jackson dependency to your project (i.e. implementation("com.fasterxml.jackson.core", "jackson-databind", "2.11.3") or newer) and it should work.

@arshtepe
Copy link

@dariuszkuc it helped, thanks

implementation("com.fasterxml.jackson.core", "jackson-databind", "2.11.3")

dariuszkuc added a commit to dariuszkuc/graphql-kotlin that referenced this issue Aug 5, 2022
* [server] update to SpringBoot 2.3

Also updates Jackson dependency to `2.11.3`.

Resolves: ExpediaGroup#850

* add missing validation dependency and cleanup spark dependencies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: blocked upstream We can not resolve until another outside issue is complete type: bug Something isn't working
Development

Successfully merging a pull request may close this issue.

6 participants