#3314 fix has no effect if swagger-core resolved a schema before `ObjectMapperProvider` was created
Maintainer antworten meist innerhalb von 1 Tag
Bewertung
- Schwierigkeit
- 4/5
- Geschätzter Aufwand
- 3-5 Tage
- Anfängerfreundlichkeit
- 45/100
- Issue-Typ
- Bug
- Klarheit
- Klar beschrieben
- Aktivitätsstatus
- Aktiv
- Tech-Stack
- java, spring-boot
- Bereich
- backend
Rechercherichtung
Start in ObjectMapperProvider, where the constructor registers SchemaTypeMixin on the shared Json31.mapper(), then follow SpringDocUtils.cloneViaJson and the fallback in AbstractRequestService.applyBeanValidatorAnnotations. Reproduce by creating a bean that calls AnnotationsUtils.resolveSchemaFromType before springdoc auto-configuration, then requesting /v3/api-docs for a constrained parameter. Done when cloning a JsonSchema with types no longer depends on mapper initialization order; run the relevant springdoc tests for OpenAPI 3.1 schema cloning.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Beschreibung
Describe the bug
With OpenAPI 3.1, Json Processing Exception occurred: Cannot construct instance of java.util.HashSet … from String value ('string') (through reference chain: io.swagger.v3.oas.models.media.JsonSchema["type"]) is still logged for every parameter with a validation constraint (@Min, @Pattern, @Size, …), although #3314 should have fixed this in 3.1.1. As a consequence, AbstractRequestService.applyBeanValidatorAnnotations falls back to modifying the original, possibly shared schema, which is the case #3270 meant to avoid.
Cause
ObjectMapperProvider registers SchemaTypeMixin on the JVM-wide Json31.mapper() in its constructor. Jackson only applies mixins to deserializers built afterwards, and caches those deserializers.
swagger-core uses the same mapper: ModelResolver copies property schemas via AnnotationsUtils.clone, which reads them back through ModelDeserializer, which in turn calls Json31.mapper().convertValue(node, JsonSchema.class) after removing type from the node. If that happens before ObjectMapperProvider is created, the cached JsonSchema deserializer lacks the TypeSetDeserializer. Every later SpringDocUtils.cloneViaJson fails, because it does not remove type first.
This happens in any application whose own configuration resolves a schema while it is being created. User configuration beans are instantiated before springdoc's auto-configuration. In our case it was an OperationCustomizer bean:
@Bean
public OperationCustomizer errorResponseSchemas(SpringDocConfigProperties properties) {
Schema schema = AnnotationsUtils.resolveSchemaFromType(ApiResponseBody.class, null, null, properties.isOpenapi31());
// …
}
To Reproduce
- Spring Boot: 4.1.1
- springdoc-openapi: 3.1.1 and 3.2.0
- swagger-core: 2.2.55
springdoc.api-docs.version=OPENAPI_3_1(the default)
- A bean in the application's own configuration that calls
AnnotationsUtils.resolveSchemaFromType(SomeDto.class, null, null, true)for a class with properties. - A controller method with a constrained parameter, e.g.
@RequestParam @Min(1) Integer pageSize. - Request
/v3/api-docs: the warning is logged for that parameter.
At that point, objectMapperProvider.jsonMapper() is Json31.mapper() and findMixInClassFor(Schema.class) returns SchemaTypeMixin, yet SpringDocUtils.cloneViaJson of a JsonSchema with types = [integer] falls back to returning the original object. The same clone succeeds in a fresh JVM without the early bean.
Expected behavior
The schema is copied regardless of what used Json31.mapper() before springdoc was initialized.
Workaround
Inject ObjectMapperProvider into the bean that resolves schemas early, so that springdoc configures the mapper first. This makes the warnings disappear in our application.
Possible fix
Don't change the shared Json31.mapper(). Let ObjectMapperProvider configure its own instance instead, e.g. ObjectMapperFactory.createJson31() with SchemaTypeMixin, as createJson already does for the standalone mappers. Alternatively, swagger-core could make the 3.1 type property readable back in the form it writes it (swagger-api/swagger-core#5264), which would make the mixin unnecessary.
- Vorherrschende Sprache
- Java
- Sterne
- 3.7k
- Forks
- 605
- Ø Merge
- 4 T. 18 Std.
- Gemergte PRs (30 T.)
- 21
Entwicklungsumgebung
Dieses Projekt bietet weder Dev-Container noch Dockerfile noch Beitragsleitfaden – die Einrichtung liegt bei Ihnen. Beginnen Sie mit der README; die allgemeinen Schritte stehen in unserem Leitfaden für den ersten Beitrag.
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus springdoc/springdoc-openapi
-
enhancement upstream
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 48/100
springdoc/springdoc-openapi#3324 · 2 Kommentare ·
Maintainer antworten meist innerhalb von 1 Tag
-
enhancement upstream
Schwierigkeit 3/5 1-2 Tage Anfängerfreundlichkeit 55/100
springdoc/springdoc-openapi#3309 · 4 Kommentare · 1 Reaktion ·
Maintainer antworten meist innerhalb von 1 Tag
Alle Issues in springdoc/springdoc-openapi
Ähnliche Issues
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 73/100
Julow/Unexpected-Keyboard#1490 ·
Maintainer antworten meist innerhalb von 4 Tagen
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 67/100
Vakore/ZappierGames#275 ·
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 82/100
unitycatalog/unitycatalog#2148 ·
Maintainer antworten meist innerhalb von 2 Tagen
-
enhancement priority: low
Schwierigkeit 1/5 Unter einer Stunde Anfängerfreundlichkeit 92/100
Riptide-Labs/riptide#1060 ·
Maintainer antworten meist innerhalb von 1 Tag
-
bug key bindings source editor
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 75/100
Maintainer antworten meist innerhalb von 1 Tag