You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
With spring-boot-starter-data-rest on the classpath, every call to /v3/api-docs fails with HTTP 500 and the Swagger UI stays empty. A single JPA entity and a JpaRepository are enough - no custom annotations, no security, no @RestResource configuration.
The failure happens in SpringDocDataRestUtils.updateResponseSchemaEmbedded, where the schema behind the _embedded property is read without a null check:
// SpringDocDataRestUtils.java, line 293 ff.if (openapi31) {
JsonSchemajsonSchema = (JsonSchema) entry.getValue().getProperties().get(entityClassName); // line 297
...
} else {
ArraySchemaarraySchema = (ArraySchema) entry.getValue().getProperties().get(entityClassName); // line 302
...
}
entry.getValue().getProperties() returns null, so both branches throw.
/v3/api-docs returns 200 and describes the Spring Data REST resource.
Additional context
I tested four combinations. The NPE shows up in all of them:
springdoc
springdoc.api-docs.version
Json Processing Exception warnings
Result
3.1.0
default (openapi_3_1)
124
500, NPE at line 297
3.1.0
openapi_3_0
0
500, NPE at line 302
3.0.3
default (openapi_3_1)
0
500, NPE at line 297
Two things follow from this, and I think both are worth pointing out:
This is not a 3.1.0 regression. 3.0.3 fails the same way, so the missing null check has been
there for a while. Only the warnings in the first row are new.
I did not dig into whygetProperties() is null for the _embedded schema - that part I'll leave to you, the reproducer above should make it easy to see.
Stacktrace (springdoc 3.1.0, default spec version, taken from the reproducer)
java.lang.NullPointerException: Cannot invoke "java.util.Map.get(Object)" because the return value of "io.swagger.v3.oas.models.media.Schema.getProperties()" is null
at org.springdoc.core.utils.SpringDocDataRestUtils.updateResponseSchemaEmbedded(SpringDocDataRestUtils.java:297)
at org.springdoc.core.utils.SpringDocDataRestUtils.updateResponseSchema(SpringDocDataRestUtils.java:278)
at org.springdoc.core.utils.SpringDocDataRestUtils.lambda$updateApiResponse$3(SpringDocDataRestUtils.java:173)
at java.base/java.util.HashMap$KeySet.forEach(HashMap.java:1017)
at org.springdoc.core.utils.SpringDocDataRestUtils.lambda$updateApiResponse$4(SpringDocDataRestUtils.java:171)
at java.base/java.util.LinkedHashMap$LinkedValues.forEach(LinkedHashMap.java:834)
at org.springdoc.core.utils.SpringDocDataRestUtils.updateApiResponse(SpringDocDataRestUtils.java:166)
at org.springdoc.core.utils.SpringDocDataRestUtils.lambda$customise$0(SpringDocDataRestUtils.java:150)
at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:987)
at org.springdoc.core.utils.SpringDocDataRestUtils.lambda$customise$1(SpringDocDataRestUtils.java:150)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1604)
at org.springdoc.core.utils.SpringDocDataRestUtils.lambda$customise$2(SpringDocDataRestUtils.java:145)
at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1939)
at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:803)
at org.springdoc.core.utils.SpringDocDataRestUtils.customise(SpringDocDataRestUtils.java:143)
at org.springdoc.core.providers.SpringRepositoryRestResourceProvider.customize(SpringRepositoryRestResourceProvider.java:292)
at org.springdoc.webmvc.api.OpenApiResource.lambda$getPaths$1(OpenApiResource.java:161)
at java.base/java.util.Optional.ifPresent(Optional.java:178)
at org.springdoc.webmvc.api.OpenApiResource.lambda$getPaths$4(OpenApiResource.java:158)
at java.base/java.util.Optional.ifPresent(Optional.java:178)
at org.springdoc.webmvc.api.OpenApiResource.getPaths(OpenApiResource.java:154)
at org.springdoc.api.AbstractOpenApiResource.getOpenApi(AbstractOpenApiResource.java:404)
at org.springdoc.webmvc.api.OpenApiResource.openapiJson(OpenApiResource.java:129)
at org.springdoc.webmvc.api.OpenApiWebMvcResource.openapiJson(OpenApiWebMvcResource.java:117)
Environment
springdoc-openapi 3.1.0 (also reproduced with 3.0.3)
Describe the bug
With
spring-boot-starter-data-reston the classpath, every call to/v3/api-docsfails with HTTP 500 and the Swagger UI stays empty. A single JPA entity and aJpaRepositoryare enough - no custom annotations, no security, no@RestResourceconfiguration.The failure happens in
SpringDocDataRestUtils.updateResponseSchemaEmbedded, where the schema behind the_embeddedproperty is read without a null check:entry.getValue().getProperties()returnsnull, so both branches throw.To Reproduce
Minimal project - four files, nothing else:
pom.xmlItem.javaItemRepository.javaapplication.propertiesThen:
mvn spring-boot:run curl -i http://localhost:8080/v3/api-docs # => HTTP/1.1 500Expected behavior
/v3/api-docsreturns 200 and describes the Spring Data REST resource.Additional context
I tested four combinations. The NPE shows up in all of them:
springdoc.api-docs.versionJson Processing Exceptionwarningsopenapi_3_1)openapi_3_0openapi_3_1)Two things follow from this, and I think both are worth pointing out:
there for a while. Only the warnings in the first row are new.
JsonSchemaclonefrom SpringDocUtils logs Json Processing Exception occurred warning for every @Min-constrained Integer query parameter (regression since 3.1.0) #3314 was leaving the schema empty, but the run with
openapi_3_0produces zeroJson Processing Exceptionwarnings and still throws — and so does 3.0.3, which predates thechange fix: Add a type deserializer to allow for JSON cloning of a JsonSchema object #3315 addresses. So I would not expect fix: Add a type deserializer to allow for JSON cloning of a JsonSchema object #3315 to fix this on its own. Happy to be corrected
if you read it differently.
I did not dig into why
getProperties()is null for the_embeddedschema - that part I'll leave to you, the reproducer above should make it easy to see.Stacktrace (springdoc 3.1.0, default spec version, taken from the reproducer)
Environment
spring-boot-starter-data-rest,spring-boot-starter-data-jpa, H2spring.data.rest.base-path=/apispringdoc.enable-data-rest=false- brings/v3/api-docsback to 200, but drops the Spring Data REST resource from the documentation.