apollographql / apollo-kotlin

:rocket:  A strongly-typed, caching GraphQL client for the JVM, Android, and Kotlin multiplatform.
https://www.apollographql.com/docs/kotlin
MIT License
3.75k stars 651 forks source link

Out of memory error when downloading the schema #6198

Open marcherdiego opened 4 days ago

marcherdiego commented 4 days ago

Version

4.0.1

Summary

This issue is reproducible using v4 but it's not using v3

Task :commons:downloadApolloSchema FAILED

FAILURE: Build failed with an exception.

FAILURE: Build failed with an exception.

Steps to reproduce the behavior

No response

Logs

> Task :commons:downloadApolloSchema FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':commons:downloadApolloSchema'.
> java.lang.Exception: Response from https://staging-graphql.outerspatial.com/v1/graphql could not be parsed as a valid schema. Body:

* Try:
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.

* Exception is:
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':commons:downloadApolloSchema'.
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.lambda$executeIfValid$1(ExecuteActionsTaskExecuter.java:130)
        at org.gradle.internal.Try$Failure.ifSuccessfulOrElse(Try.java:282)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.executeIfValid(ExecuteActionsTaskExecuter.java:128)
        at org.gradle.api.internal.tasks.execution.ExecuteActionsTaskExecuter.execute(ExecuteActionsTaskExecuter.java:116)
        at org.gradle.api.internal.tasks.execution.FinalizePropertiesTaskExecuter.execute(FinalizePropertiesTaskExecuter.java:46)
        at org.gradle.api.internal.tasks.execution.ResolveTaskExecutionModeExecuter.execute(ResolveTaskExecutionModeExecuter.java:51)
        at org.gradle.api.internal.tasks.execution.SkipTaskWithNoActionsExecuter.execute(SkipTaskWithNoActionsExecuter.java:57)
        at org.gradle.api.internal.tasks.execution.SkipOnlyIfTaskExecuter.execute(SkipOnlyIfTaskExecuter.java:74)
        at org.gradle.api.internal.tasks.execution.CatchExceptionTaskExecuter.execute(CatchExceptionTaskExecuter.java:36)
        at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.executeTask(EventFiringTaskExecuter.java:77)
        at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:55)
        at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter$1.call(EventFiringTaskExecuter.java:52)
        at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:200)
        at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:195)
        at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
        at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
        at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:157)
        at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
        at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
        at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:73)
        at org.gradle.api.internal.tasks.execution.EventFiringTaskExecuter.execute(EventFiringTaskExecuter.java:52)
        at org.gradle.execution.plan.LocalTaskNodeExecutor.execute(LocalTaskNodeExecutor.java:42)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:331)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$InvokeNodeExecutorsAction.execute(DefaultTaskExecutionGraph.java:318)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.lambda$execute$0(DefaultTaskExecutionGraph.java:314)
        at org.gradle.internal.operations.CurrentBuildOperationRef.with(CurrentBuildOperationRef.java:80)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:314)
        at org.gradle.execution.taskgraph.DefaultTaskExecutionGraph$BuildOperationAwareExecutionAction.execute(DefaultTaskExecutionGraph.java:303)
        at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.execute(DefaultPlanExecutor.java:463)
        at org.gradle.execution.plan.DefaultPlanExecutor$ExecutorWorker.run(DefaultPlanExecutor.java:380)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
        at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
Caused by: org.gradle.internal.UncheckedException: java.lang.Exception: Response from https://staging-graphql.outerspatial.com/v1/graphql could not be parsed as a valid schema. Body:

FAILURE: Build failed with an exception.

* What went wrong:
Could not receive a message from the daemon.

* Try:
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.

* Exception is:
org.gradle.launcher.daemon.client.DaemonConnectionException: Could not receive a message from the daemon.
        at org.gradle.launcher.daemon.client.DaemonClientConnection.receive(DaemonClientConnection.java:83)
        at org.gradle.launcher.daemon.client.DaemonClientConnection.receive(DaemonClientConnection.java:35)
        at org.gradle.launcher.daemon.client.DaemonClient.monitorBuild(DaemonClient.java:239)
        at org.gradle.launcher.daemon.client.DaemonClient.executeBuild(DaemonClient.java:201)
        at org.gradle.launcher.daemon.client.SingleUseDaemonClient.execute(SingleUseDaemonClient.java:54)
        at org.gradle.launcher.daemon.client.SingleUseDaemonClient.execute(SingleUseDaemonClient.java:37)
        at org.gradle.launcher.cli.RunBuildAction.run(RunBuildAction.java:57)
        at org.gradle.internal.Actions$RunnableActionAdapter.execute(Actions.java:167)
        at org.gradle.launcher.cli.DefaultCommandLineActionFactory$ParseAndBuildAction.execute(DefaultCommandLineActionFactory.java:259)
        at org.gradle.launcher.cli.DefaultCommandLineActionFactory$ParseAndBuildAction.execute(DefaultCommandLineActionFactory.java:230)
        at org.gradle.launcher.cli.DebugLoggerWarningAction.execute(DebugLoggerWarningAction.java:74)
        at org.gradle.launcher.cli.DebugLoggerWarningAction.execute(DebugLoggerWarningAction.java:30)
        at org.gradle.launcher.cli.WelcomeMessageAction.execute(WelcomeMessageAction.java:96)
        at org.gradle.launcher.cli.WelcomeMessageAction.execute(WelcomeMessageAction.java:40)
        at org.gradle.launcher.cli.NativeServicesInitializingAction.execute(NativeServicesInitializingAction.java:44)
        at org.gradle.launcher.cli.NativeServicesInitializingAction.execute(NativeServicesInitializingAction.java:26)
        at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:41)
        at org.gradle.launcher.cli.ExceptionReportingAction.execute(ExceptionReportingAction.java:26)
        at org.gradle.launcher.cli.DefaultCommandLineActionFactory$WithLogging.execute(DefaultCommandLineActionFactory.java:361)
        at org.gradle.launcher.Main.doAction(Main.java:35)
        at org.gradle.launcher.bootstrap.EntryPoint.run(EntryPoint.java:50)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:568)
        at org.gradle.launcher.bootstrap.ProcessBootstrap.runNoExit(ProcessBootstrap.java:60)
        at org.gradle.launcher.bootstrap.ProcessBootstrap.run(ProcessBootstrap.java:37)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:568)
        at org.gradle.launcher.GradleMain.main(GradleMain.java:34)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:568)
        at org.gradle.wrapper.BootstrapMainStarter.start(BootstrapMainStarter.java:35)
        at org.gradle.wrapper.WrapperExecutor.execute(WrapperExecutor.java:103)
        at org.gradle.wrapper.GradleWrapperMain.main(GradleWrapperMain.java:66)
Caused by: org.gradle.internal.remote.internal.MessageIOException: Could not read message from '/127.0.0.1:60814'.
        at org.gradle.internal.remote.internal.inet.SocketConnection.receive(SocketConnection.java:94)
        at org.gradle.launcher.daemon.client.DaemonClientConnection.receive(DaemonClientConnection.java:77)
        ... 38 more
Caused by: java.lang.OutOfMemoryError: Java heap space
        at java.base/java.lang.Integer.valueOf(Integer.java:1081)
        at java.base/sun.nio.ch.KQueueSelectorImpl.processEvents(KQueueSelectorImpl.java:219)
        at java.base/sun.nio.ch.KQueueSelectorImpl.doSelect(KQueueSelectorImpl.java:139)
        at java.base/sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:129)
        at java.base/sun.nio.ch.SelectorImpl.select(SelectorImpl.java:146)
        at org.gradle.internal.remote.internal.inet.SocketConnection$SocketInputStream.read(SocketConnection.java:185)
        at com.esotericsoftware.kryo.io.Input.fill(Input.java:146)
        at com.esotericsoftware.kryo.io.Input.require(Input.java:178)
        at com.esotericsoftware.kryo.io.Input.readUtf8_slow(Input.java:542)
        at com.esotericsoftware.kryo.io.Input.readUtf8(Input.java:535)
        at com.esotericsoftware.kryo.io.Input.readString(Input.java:465)
        at org.gradle.internal.serialize.kryo.KryoBackedDecoder.readNullableString(KryoBackedDecoder.java:183)
        at org.gradle.internal.serialize.kryo.KryoBackedDecoder.readString(KryoBackedDecoder.java:177)
        at org.gradle.internal.logging.serializer.SpanSerializer.read(SpanSerializer.java:40)
        at org.gradle.internal.logging.serializer.SpanSerializer.read(SpanSerializer.java:25)
        at org.gradle.internal.serialize.AbstractCollectionSerializer.read(AbstractCollectionSerializer.java:58)
        at org.gradle.internal.serialize.AbstractCollectionSerializer.read(AbstractCollectionSerializer.java:23)
        at org.gradle.internal.logging.serializer.StyledTextOutputEventSerializer.read(StyledTextOutputEventSerializer.java:57)
        at org.gradle.internal.logging.serializer.StyledTextOutputEventSerializer.read(StyledTextOutputEventSerializer.java:28)
        at org.gradle.internal.serialize.DefaultSerializerRegistry$TaggedTypeSerializer.read(DefaultSerializerRegistry.java:164)
        at org.gradle.launcher.daemon.protocol.DaemonMessageSerializer$OutputMessageSerializer.read(DaemonMessageSerializer.java:243)
        at org.gradle.launcher.daemon.protocol.DaemonMessageSerializer$OutputMessageSerializer.read(DaemonMessageSerializer.java:229)
        at org.gradle.internal.serialize.DefaultSerializerRegistry$TaggedTypeSerializer.read(DefaultSerializerRegistry.java:164)
        at org.gradle.internal.serialize.Serializers$StatefulSerializerAdapter$1.read(Serializers.java:36)
        at org.gradle.internal.remote.internal.inet.SocketConnection.receive(SocketConnection.java:81)
        at org.gradle.launcher.daemon.client.DaemonClientConnection.receive(DaemonClientConnection.java:77)
        at org.gradle.launcher.daemon.client.DaemonClientConnection.receive(DaemonClientConnection.java:35)
        at org.gradle.launcher.daemon.client.DaemonClient.monitorBuild(DaemonClient.java:239)
        at org.gradle.launcher.daemon.client.DaemonClient.executeBuild(DaemonClient.java:201)
        at org.gradle.launcher.daemon.client.SingleUseDaemonClient.execute(SingleUseDaemonClient.java:54)
        at org.gradle.launcher.daemon.client.SingleUseDaemonClient.execute(SingleUseDaemonClient.java:37)
        at org.gradle.launcher.cli.RunBuildAction.run(RunBuildAction.java:57)
martinbonnin commented 4 days ago

Hi 👋

Can you try increasing your heap size? https://docs.gradle.org/current/userguide/performance.html#increase_the_heap_size

marcherdiego commented 4 days ago

Yeah, I tried but no luck, if you want I might send you privately the schema url and the token to fetch it

martinbonnin commented 4 days ago

That'd be helpful, thanks. You can send them to martin@apollographql.com

martinbonnin commented 4 days ago

Actually looks like I can run introspection without a token. I get this error:

Unexpected JSON token at offset 7638653: Expected valid boolean literal prefix, but had 'null' at path: $.data.__schema.directives[0].isRepeatable
JSON input: .....ue":null}],"isRepeatable":null},{"name":"skip","description".....

Looks like it crashes with an OOM trying to display the error because the JSON itself is 16MB (this doesn't seem that huge to me but 🤷 )

Your server is returning null for isRepeatable, which is defined as Boolean!. May I ask what server it is?

marcherdiego commented 4 days ago

The server is Hasura

martinbonnin commented 4 days ago

Interesting. I would have expected them to use graphql-js which should support this. Let me try graphql-js quickly

martinbonnin commented 4 days ago

graphql-js works fine:

const typeDefs = `
    type Query {
      hello: String
    }
`

graphql({
    schema: buildSchema(typeDefs),
    rootValue: {},
    source: "{ __schema { directives { name isRepeatable } } }",
}).then(response => {
    console.log(JSON.stringify(response))
})
{"data":{"__schema":{"directives":[{"name":"include","isRepeatable":false},{"name":"skip","isRepeatable":false},{"name":"deprecated","isRepeatable":false},{"name":"specifiedBy","isRepeatable":false},{"name":"oneOf","isRepeatable":false}]}}}

I would file a bug to hasura. null is not a valid value for isRepeatable

nateirwin commented 22 hours ago

We filed a bug with Hasura, and they're going to patch this issue in a coming release.