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

GraalVM / GraphQL Expediagroup #1441

Closed
fmorissette-equisoft opened this issue May 10, 2022 · 10 comments
Closed

GraalVM / GraphQL Expediagroup #1441

fmorissette-equisoft opened this issue May 10, 2022 · 10 comments
Labels
type: bug Something isn't working

Comments

@fmorissette-equisoft
Copy link

Library Version
com.expediagroup:graphql-kotlin-schema-generator:5.3.2

Describe the bug
Everything work has expected when comes the time to run it using GraalVM. The schema generator is crashing with this:

Caused by: io.github.classgraph.ClassGraphException: Uncaught exception during scan
at io.github.classgraph.ClassGraph.scan(ClassGraph.java:1606)
at io.github.classgraph.ClassGraph.scan(ClassGraph.java:1623)
at io.github.classgraph.ClassGraph.scan(ClassGraph.java:1636)
at com.expediagroup.graphql.generator.internal.state.ClassScanner.(ClassScanner.kt:36)
at com.expediagroup.graphql.generator.SchemaGenerator.(SchemaGenerator.kt:52)

The issue occurs during the call to toFederatedSchema(config, queries, emptyList())

The reflection causes the problem at runtime. Tried to setup GraalVM with build-time compilation

Seems related to this same issue: #1224

To Reproduce
Steps to reproduce the behavior. Please provide:

  • compiling the library with GraalVM 22.0.0.2
  • running the final generated binary
  • Asking for the whatever graphql request

Expected behavior
Should properly return the GraphQL result even within GraalVM

@fmorissette-equisoft fmorissette-equisoft added the type: bug Something isn't working label May 10, 2022
dariuszkuc added a commit to dariuszkuc/graphql-kotlin that referenced this issue Mar 27, 2023
We are using `ClassScanner` (which wraps `ClassGraph`) to automatically resolve polymorphic types (i.e. given an interface we can find all implementing types that are available on classpath) and locate federated entities (i.e. types with `@key` directive). This is generally great as this information can be pulled in automatically but it is a blocker for using the library with GraalVM.

`ClassGraph` is incompatible with GraalVm because when compiling to native image, we will no longer have JARs on classpath so any metadata around resources in those files will be invalid. Since we only use classpath scanning for resolving polyrmophic types and federated entities, the simplest solution is to provide users ability to manually provide this information without relying on the `ClassGraph` (which is still used by default).

This PR introduces a breaking change that removes `SchemaGenerator#addAdditionalTypesWithAnnotation` function. This function was originally to avoid exposing `ClassGraph` outside of `graphql-kotlin-schema-generator` module and allow federation module to easily locate entity types. By making `ClassGraph` dependency optional, function no longer makes sense
.

Related:

* ExpediaGroup#1543
* ExpediaGroup#1441
* ExpediaGroup#1224
dariuszkuc added a commit that referenced this issue Mar 30, 2023
…al (#1733)

### 📝 Description

We are using `ClassScanner` (which wraps `ClassGraph`) to automatically resolve polymorphic types (i.e. given an interface we can find all implementing types that are available on classpath) and locate federated entities (i.e. types with `@key` directive). This is generally great as this information can be pulled in automatically but it is a blocker for using the library with GraalVM.

`ClassGraph` is incompatible with GraalVm because when compiling to native image, we will no longer have JARs on classpath so any metadata around resources in those files will be invalid. Since we only use classpath scanning for resolving polyrmophic types and federated entities, the simplest solution is to provide users ability to manually provide this information without relying on the `ClassGraph` (which is still used by default). By no longer relying on `ClassGraph` we can now generate valid GraalVM reflect metadata and compile GraphQL Kotlin servers to native images.

This PR introduces a breaking change that removes `SchemaGenerator#addAdditionalTypesWithAnnotation` function. This function was originally added to avoid exposing `ClassGraph` outside of `graphql-kotlin-schema-generator` module and allow federation module to easily locate entity types. By making `ClassGraph` dependency optional, function no longer makes sense.

### 🔗 Related Issues

* #1543
* #1441
* #1224
@dariuszkuc
Copy link
Collaborator

GraphQL Kotlin v7 introduces new plugin goals that will generate GraalVM reachability metadata that will allow you to generate native images.

Related:

@fmorissette-equisoft
Copy link
Author

Good! So my understanding is it's working out of the box in v7

@dariuszkuc
Copy link
Collaborator

You need to explicitly provide polymorphic type hierarchy + generate reachability metadata (through plugin). See the docs*.

*changes to support SpringBoot still need to get merged

@fmorissette-equisoft
Copy link
Author

Thanks @dariuszkuc will look at this. I'm not currently using SpringBoot, i'm integrating it with Micronaut.

@fmorissette-equisoft
Copy link
Author

Hi @dariuszkuc , Do you have an idea why all my federated directive does not get added in the subgraph. Trying to use extend and key and they are never added to the type. Tried to look deep in the code but all seems to be fine except that the final output never generates it

@dariuszkuc
Copy link
Collaborator

Hello 👋
Are you using federated generator? Can you provide a link to a repository with your configuration?

@fmorissette-equisoft
Copy link
Author

fmorissette-equisoft commented May 16, 2023

Thanks @dariuszkuc for the feedback

This is an example of the code used

    val hooks = (FederatedSchemaGeneratorHooks(emptyList(), optInFederationV2 = false))

    val config = FederatedSchemaGeneratorConfig(
        supportedPackages = listOf(
            "tasks.graphql.schemas", "kotlin.collections"
        ), hooks = hooks
    )

    val queries = listOf(TopLevelObject(TasksQueries(taskService)))
    var configSchema = toFederatedSchema(config, queries, emptyList(), emptyList())
    return GraphQL.newGraphQL(configSchema).build()

The type to generate contains this
@KeyDirective(fields = FieldSet("taskId"), resolvable = false)
@ExtendsDirective
class TaskDetail2(

@fmorissette-equisoft
Copy link
Author

The type is generated but without the extend and key attributes

@dariuszkuc
Copy link
Collaborator

Hello 👋
Without a link to repository that reproduces the issue it is hard to say what is the underlying problem.

@fmorissette-equisoft
Copy link
Author

No problem, I can't share that portion of code.
Thanks for your feedback :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug Something isn't working
Development

No branches or pull requests

2 participants