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

AOT: No JSON Encoder error using GraphlQL client #825

Closed
scmdmo opened this issue Sep 22, 2023 · 3 comments
Closed

AOT: No JSON Encoder error using GraphlQL client #825

scmdmo opened this issue Sep 22, 2023 · 3 comments
Assignees
Labels
in: core Issues related to config and core support status: backported An issue that has been backported to maintenance branches type: bug A general bug
Milestone

Comments

@scmdmo
Copy link

scmdmo commented Sep 22, 2023

Following comment in #495 (comment)

I'm using Spring Boot 3.1.3 together with Graalvm 22.3.1. Use GraphQL from client side app compiled in native, as indicated in docs (https://docs.spring.io/spring-graphql/reference/graalvm-native.html#graalvm.client) I included @RegisterReflectionForBinding with my DTO type

However still get a No JSON Encoder error

Attached, I provide a sample app to reproduce error get in my main app.
It was build in Windows

graphql-client-native.zip

Steps to reproduce the issue:
1 - compile in native
2 - start app

Full stack trace got:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'accountService': Unsatisfied dependency expressed through constructor parameter 0: Error creating bean with name 'accountGraphApiClient': Instantiation of supplied bean failed
        at org.springframework.beans.factory.aot.BeanInstanceSupplier.resolveArgument(BeanInstanceSupplier.java:317) ~[na:na]
        at org.springframework.beans.factory.aot.BeanInstanceSupplier.resolveArguments(BeanInstanceSupplier.java:260) ~[na:na]
        at org.springframework.beans.factory.aot.BeanInstanceSupplier.get(BeanInstanceSupplier.java:200) ~[na:na]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.obtainInstanceFromSupplier(DefaultListableBeanFactory.java:947) ~[graphql-client-native.exe:6.0.11]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1214) ~[graphql-client-native.exe:6.0.11]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1158) ~[graphql-client-native.exe:6.0.11]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:560) ~[graphql-client-native.exe:6.0.11]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) ~[graphql-client-native.exe:6.0.11]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[graphql-client-native.exe:6.0.11]       
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[graphql-client-native.exe:6.0.11]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[graphql-client-native.exe:6.0.11]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[graphql-client-native.exe:6.0.11]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:973) ~[graphql-client-native.exe:6.0.11]
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:942) ~[graphql-client-native.exe:6.0.11]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:608) ~[graphql-client-native.exe:6.0.11]
        at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:66) ~[graphql-client-native.exe:3.1.3]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) ~[graphql-client-native.exe:3.1.3]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:436) ~[graphql-client-native.exe:3.1.3]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:312) ~[graphql-client-native.exe:3.1.3]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) ~[graphql-client-native.exe:3.1.3]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) ~[graphql-client-native.exe:3.1.3]
        at com.sample.graphqlclientnative.Application.main(Application.java:10) ~[graphql-client-native.exe:na]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'accountGraphApiClient': Instantiation of supplied bean failed    
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1220) ~[graphql-client-native.exe:6.0.11]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1158) ~[graphql-client-native.exe:6.0.11]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:560) ~[graphql-client-native.exe:6.0.11]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) ~[graphql-client-native.exe:6.0.11]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[graphql-client-native.exe:6.0.11]       
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[graphql-client-native.exe:6.0.11]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[graphql-client-native.exe:6.0.11]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[graphql-client-native.exe:6.0.11]
        at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254) ~[graphql-client-native.exe:6.0.11]        
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1417) ~[graphql-client-native.exe:6.0.11]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1337) ~[graphql-client-native.exe:6.0.11]
        at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:888) ~[na:na]
        at org.springframework.beans.factory.support.RegisteredBean.resolveAutowiredArgument(RegisteredBean.java:228) ~[graphql-client-native.exe:6.0.11]
        at org.springframework.beans.factory.aot.BeanInstanceSupplier.resolveArgument(BeanInstanceSupplier.java:314) ~[na:na]
        ... 21 common frames omitted
Caused by: java.lang.IllegalArgumentException: No JSON Encoder
        at org.springframework.graphql.client.CodecDelegate.lambda$findJsonEncoder$5(CodecDelegate.java:85) ~[na:na]
        at [email protected]/java.util.Optional.orElseThrow(Optional.java:403) ~[graphql-client-native.exe:na]
        at org.springframework.graphql.client.CodecDelegate.findJsonEncoder(CodecDelegate.java:85) ~[na:na]
        at org.springframework.graphql.client.CodecDelegate.findJsonEncoder(CodecDelegate.java:62) ~[na:na]
        at org.springframework.graphql.client.DefaultHttpGraphQlClientBuilder.lambda$build$0(DefaultHttpGraphQlClientBuilder.java:110) ~[graphql-client-native.exe:1.2.2]
        at org.springframework.web.reactive.function.client.DefaultExchangeStrategiesBuilder.codecs(DefaultExchangeStrategiesBuilder.java:63) ~[na:na]
        at org.springframework.web.reactive.function.client.DefaultWebClientBuilder.lambda$codecs$0(DefaultWebClientBuilder.java:257) ~[na:na]
        at org.springframework.web.reactive.function.client.DefaultWebClientBuilder.lambda$initExchangeStrategies$1(DefaultWebClientBuilder.java:361) ~[na:na]      
        at [email protected]/java.util.ArrayList.forEach(ArrayList.java:1511) ~[graphql-client-native.exe:na]
        at org.springframework.web.reactive.function.client.DefaultWebClientBuilder.initExchangeStrategies(DefaultWebClientBuilder.java:361) ~[na:na]
        at org.springframework.web.reactive.function.client.DefaultWebClientBuilder.build(DefaultWebClientBuilder.java:314) ~[na:na]
        at org.springframework.graphql.client.DefaultHttpGraphQlClientBuilder.build(DefaultHttpGraphQlClientBuilder.java:113) ~[graphql-client-native.exe:1.2.2]    
        at com.sample.graphqlclientnative.adapter.AccountGraphApiClientConfig.accountGraphApiClient(AccountGraphApiClientConfig.java:25) ~[graphql-client-native.exe:na]
        at com.sample.graphqlclientnative.adapter.AccountGraphApiClientConfig__BeanDefinitions.lambda$getAccountGraphApiClientInstanceSupplier$0(AccountGraphApiClientConfig__BeanDefinitions.java:28) ~[na:na]
        at org.springframework.util.function.ThrowingBiFunction.apply(ThrowingBiFunction.java:68) ~[graphql-client-native.exe:6.0.11]
        at org.springframework.util.function.ThrowingBiFunction.apply(ThrowingBiFunction.java:54) ~[graphql-client-native.exe:6.0.11]
        at org.springframework.beans.factory.aot.BeanInstanceSupplier.lambda$get$2(BeanInstanceSupplier.java:202) ~[na:na]
        at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58) ~[graphql-client-native.exe:6.0.11]
        at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46) ~[graphql-client-native.exe:6.0.11]
        at org.springframework.beans.factory.aot.BeanInstanceSupplier.invokeBeanSupplier(BeanInstanceSupplier.java:214) ~[na:na]
        at org.springframework.beans.factory.aot.BeanInstanceSupplier.get(BeanInstanceSupplier.java:202) ~[na:na]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.obtainInstanceFromSupplier(DefaultListableBeanFactory.java:947) ~[graphql-client-native.exe:6.0.11]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.obtainFromSupplier(AbstractAutowireCapableBeanFactory.java:1214) ~[graphql-client-native.exe:6.0.11]
        ... 34 common frames omitted

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Sep 22, 2023
@scmdmo
Copy link
Author

scmdmo commented Sep 22, 2023

@bclozel

@bclozel bclozel self-assigned this Oct 13, 2023
@bclozel bclozel added type: bug A general bug in: core Issues related to config and core support and removed status: waiting-for-triage An issue we've not yet triaged labels Oct 13, 2023
@bclozel bclozel added this to the 1.2.4 milestone Oct 13, 2023
@bclozel bclozel added the for: backport-to-1.2.x Marks an issue as a candidate for backport to 1.2.x label Oct 13, 2023
@github-actions github-actions bot removed the for: backport-to-1.2.x Marks an issue as a candidate for backport to 1.2.x label Oct 13, 2023
@bclozel bclozel added the for: backport-to-1.2.x Marks an issue as a candidate for backport to 1.2.x label Oct 13, 2023
@github-actions github-actions bot added status: backported An issue that has been backported to maintenance branches and removed for: backport-to-1.2.x Marks an issue as a candidate for backport to 1.2.x labels Oct 13, 2023
@bclozel
Copy link
Member

bclozel commented Oct 13, 2023

Sorry for the late reply @scmdmo and thanks for the repro project.
This has been now fixed in the 1.2.4-SNAPSHOT and 1.1.8-SNAPSHOT.

You can locally fix that in your application by adding this content in the src/main/resources/META-INF/native-image/org.springframework.graphql/spring-graphql-bug/reflect-config.json:

[
  {
    "name":"org.springframework.graphql.server.support.GraphQlWebSocketMessage",
    "allDeclaredFields":true,
    "allDeclaredMethods":true,
    "allDeclaredConstructors":true,
    "condition": {
      "typeReachable": "org.springframework.graphql.client.AbstractGraphQlClientBuilder"
    }
  }
]

@scmdmo
Copy link
Author

scmdmo commented Oct 18, 2023

Hi @bclozel, thank you very much. I tried in my local test project and the fix works perfectly. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: core Issues related to config and core support status: backported An issue that has been backported to maintenance branches type: bug A general bug
Projects
None yet
Development

No branches or pull requests

3 participants