Netflix / dgs-framework

GraphQL for Java with Spring Boot made easy.
https://netflix.github.io/dgs
Apache License 2.0
3.06k stars 295 forks source link

bug: Schema hot-reload not works at all, spring 3.2.1 #1774

Closed frct1 closed 8 months ago

frct1 commented 8 months ago

Please read our contributor guide before creating an issue.

Expected behavior

Schema is being loaded on each request

Actual behavior

Schema is not being re-loaded in hot mode. But currently if i edit query name eq "hello" -> "hey" dgs gets broken.

type Query {
    hello(name: String! = "Spring"): String!
}

become

type Query {
    hey(name: String! = "Spring"): String!
}

After starting schema fetch in Postman i can see error message related to DGS

com.netflix.graphql.dgs.exceptions.DataFetcherSchemaMismatchException: @DgsData in com.example.demo.DemoResolver on field hey references object type `Query` it has no field named `hey`. All data fetchers registered with @DgsData|@DgsQuery|@DgsMutation|@DgsSubscription must match a field in the schema.

Steps to reproduce

JRebel Agent 2023.4.2 Spring boot: 3.2.1 application.yml: dgs.reload: true presents. Enabling laptop profile is also tried with no success

Note: A test case would be highly appreciated, but we understand that's not always possible

frct1 commented 8 months ago

UPD: As far as i can see, new schema is getting copied to out folder with correct content but for some reason DGS doesn't reload it

type Query {
    hey(name: String! = "Spring"): String!
}

Digged into sources, tried to debug more:

boolean hotReloadSetting = env.getProperty("dgs.reload", Boolean.class);

shows true. What else needs to be checked ?

frct1 commented 8 months ago

UPD2: As i can see in case of Spring Gradle plugin is being used i have to add ext['kotlin.version'] = '1.4.31' it leads to things get broken at all

2024-01-13T18:09:02.024+03:00  INFO 26848 --- [           main] .s.b.a.l.ConditionEvaluationReportLogger : 

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2024-01-13T18:09:02.049+03:00 ERROR 26848 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

An attempt was made to call a method that does not exist. The attempt was made from the following location:

    org.springframework.beans.BeanUtils$KotlinDelegate.findPrimaryConstructor(BeanUtils.java:861)

The following method did not exist:

    'boolean kotlin.reflect.KClass.isValue()'

The calling method's class, org.springframework.beans.BeanUtils$KotlinDelegate, was loaded from the following location:

    jar:file:/C:/Users/admin/.gradle/caches/modules-2/files-2.1/org.springframework/spring-beans/6.1.2/abf52f2254975a3b1e95b2b63fb8b01d891cdc51/spring-beans-6.1.2.jar!/org/springframework/beans/BeanUtils$KotlinDelegate.class

The called method's class, kotlin.reflect.KClass, is available from the following locations:

    jar:file:/C:/Users/admin/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.4.31/a58e0fb9812a6a93ca24b5da75e4b5a0cb89c957/kotlin-stdlib-1.4.31.jar!/kotlin/reflect/KClass.class

The called method's class hierarchy was loaded from the following locations:

    kotlin.reflect.KClass: file:/C:/Users/admin/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.4.31/a58e0fb9812a6a93ca24b5da75e4b5a0cb89c957/kotlin-stdlib-1.4.31.jar

Action:

Correct the classpath of your application so that it contains compatible versions of the classes org.springframework.beans.BeanUtils$KotlinDelegate and kotlin.reflect.KClass

Here is build.gradle deps

plugins {
    id 'java'
    id 'org.springframework.boot' version '3.2.1'
    id 'io.spring.dependency-management' version '1.1.4'
    id 'org.hibernate.orm' version '6.4.1.Final'
    id 'org.graalvm.buildtools.native' version '0.9.27'
    id 'org.asciidoctor.jvm.convert' version '3.3.2'
}
...
dependencyManagement {
    imports {
        mavenBom("com.netflix.graphql.dgs:graphql-dgs-platform-dependencies:latest.release")
    }
}
ext['kotlin.version'] = '1.4.31'
dependencies {
...
implementation 'com.netflix.graphql.dgs:graphql-dgs-spring-boot-starter'
}
frct1 commented 8 months ago

Upd3: I can see in release that kotlin has update, so tried next thing

ext['kotlin.version'] = '1.9.22'

and it's make it start but hot-reload still doesn't work, have no clue what could be wrong 🤔

paulbakker commented 8 months ago

@baikov-ilia I just validated the reload behavior and it works, so I'm not sure why it's not working for you.

In Intellij you need to explicitly "build" (cmnd-f9 on Macos) for file to be copied, so make sure you do that. The next thing you could try is set a breakpoint in DgsSchemaProvider to see if it goes through the re-loading logic.

I'm going to close this issue for now, assuming it's something related to your setup, since the functionality seems to be working fine.

frct1 commented 7 months ago

Yep, found out that in order to sync schema from resources folder to build it's needed to run processResources manually in idea and schema is being reloaded on a next request. No clue on how to run this task after a build, but seems like reload is working.

paulbakker commented 7 months ago

What build system are you using? I was testing with Gradle, and that "just works" in Intellij if I hit the "build" command. I'm actually really not sure about other builds systems.

On Tue, Feb 13, 2024 at 5:36 PM Ilia Baikov @.***> wrote:

Yep, found out that in order to sync schema from resources folder to build it's needed to run processResources manually in idea and schema is being reloaded on a next request. No clue on how to run this task after a build, but seems like reload is working.

— Reply to this email directly, view it on GitHub https://github.com/Netflix/dgs-framework/issues/1774#issuecomment-1942955152, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAA2XLA7S7AUMHX2VUXRNITYTQIK5AVCNFSM6AAAAABBZLYG3KVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNBSHE2TKMJVGI . You are receiving this because you modified the open/close state.Message ID: @.***>

frct1 commented 7 months ago

What build system are you using? I was testing with Gradle, and that "just works" in Intellij if I hit the "build" command. I'm actually really not sure about other builds systems.

I'm using Gradle along with JRebel since devtools throw some exception related to classpath when mapstruct is used. Firing processResources even when JRebel is running helps to update schema and then it is get reloaded fine.