Description
Version
Spring Boot 2.7.1
Description
We created a new itest
source set in Gradle and when we run the test using @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
, seems like the autoconfigure GraphQL components are not provisioned.
How to reproduce it
This project contains a pretty simple GraphQL controller, with two tests:
- One inside the
test
source set, using RestAssured to call the GraphQL endpoint, which works fine (HTTP 200) - One inside the
itest
source set, using RestAssured to call the GraphQL endpoint, which doesn't work (HTTP 404)
Clues
I did some debugging and found that ConditionalOnGraphQlSchema
returns true for the test
source set, and false for the itest
source set, it seems like this line on DefaultGraphQlSchemaCondition
cannot find the GraphQL schema, and therefore, Spring Boot doesn't contribute the Graphql autoconfiguration.
My guess is this issue might be for Spring Boot and not Gradle configuration, as other resources work fine, like liquibase changelogs and application.yml files.
Activity
wilkinsona commentedon Jul 19, 2022
It's a classpath ordering problem. Your
itest
task has the project's main resources on its classpath after all of its dependencies whereas thetest
task has the project's main resources on its classpath before all of its dependencies. This ordering matters because thegraphql-java
jar contains agraphql
package. When it's on the classpath before the project's main resources, this package prevents thegraphql/schema.graphqls
file from being found as it ends up looking insidegraphql-java
for it as that's the first occurrence ofgraphql/
on the classpath.You can fix the problem by creating your
itest
source set like this:I'm going to leave this issue open as I think we should consider a different default schema location.
"classpath*:graphql/**/"
would be more robust, although it may be quite slow depending on the size of the classpath.What do you think, @bclozel and @rstoyanchev?
bclozel commentedon Jul 19, 2022
This might be related to spring-projects/spring-graphql#308 (comment)
wilkinsona commentedon Jul 19, 2022
Thanks for the link, Brian. That's the same problem indeed, just with a different source of the unwanted
graphql
package that stops the file from being found.[-]@SpringBootTest with RANDOM_PORT doesn't autoconfigure GraphQL components on a different Gradle sourceSet[/-][+]GraphQL schema files are not found when a root containing a graphql package appears on the classpath before the root that contains the schema files[/+]rstoyanchev commentedon Sep 20, 2022
As of spring-projects/spring-graphql#338, we look in different places for schema vs test request vs client request files, which eliminates a very basic reason to shadowing
graphql/
under main and test sources that most apps would run into otherwise.For the rest, using
classpath*:
by default will find all possible candidates out of the box, including some that may not be intended for inclusion, whileclasspath:
requires an explicit action to decide how to deal with such shadowing. I tend to think the more explicit opt-in option is preferable. I've already made an adjustment to the Spring for GraphQL docs to make that easier to spot.bclozel commentedon Sep 20, 2022
Thanks Rossen, I'll add a similar note in the Spring Boot reference docs, I'll turn this into a documentation issue then.
9 remaining items