Description
We are experiencing a StackOverflowError during OpenAPI schema generation after upgrading springdoc-openapi-starter-common
and springdoc-openapi-starter-webmvc-ui
from version 2.3.0
to 2.8.5
. This upgrade was part of a larger update, including Spring Boot from 3.3.7
to 3.4.1
. We are using Kotlin and Gradle.
The issue appears to be related to the processing of a sealed class hierarchy with @JsonSubTypes
annotation. The structure is similar to the following:
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, property = "@type")
@JsonSubTypes(
JsonSubTypes.Type(value = ConcreteClassA::class, nams = "TYPE_A"),
JsonSubTypes.Type(value = ConcreteClassB::class, name = "TYPE_B"),
// ... more subtypes ...
JsonSubTypes.Type(value = ConcreteClassWithGrandchild::class, name = "TYPE_WITH_GRANDCHILD"),
// ... more subtypes ...
)
sealed class AbstractBaseClass {
abstract fun someAbstractFunction(): String?
open fun anotherFunction() = someAbstractFunction() ?: ""
}
// Example of a simple subclass
data class ConcreteClassA(
val someProperty: String?
) : AbstractBaseClass() {
override fun someAbstractFunction(): String? { /* implementation */ }
}
// Intermediate abstract class
sealed class IntermediateAbstractClass : AbstractBaseClass() {
abstract val commonProperty1: String?
abstract val commonProperty2: String?
}
// Example of class extends to another sealed class
data class ConcreteClassWithGrandchild(
@JsonAlias("alias_prop1")
@JsonInclude(JsonInclude.Include.NON_NULL)
override val commonProperty1: String? = null,
@JsonAlias("alias_prop2")
@JsonInclude(JsonInclude.Include.NON_NULL)
val specificProperty: String?,
override val commonProperty2: String?,
) : IntermediateAbstractClass() {
override fun someAbstractFunction() = "someValue"
}
The key points are:
- A sealed class (AbstractBaseClass) is used as the base.
- @JsonTypeInfo and @JsonSubTypes are used for polymorphic deserialization.
- There are multiple concrete subclasses, and, importantly, at least one subclass (ConcreteClassWithGrandchild) extends to another sealed class (IntermediateAbstractClass).
- Some properties use @JsonAlias and @JsonInclude.
The exception occurs during the openApiGenerate Gradle task. The stack trace indicates a stack overflow within org.openapitools.codegen.DefaultCodegen.getAllOfDescendants
, suggesting a problem with recursive processing of the class hierarchy.
org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':openApiGenerate'.
...
Caused by: org.gradle.api.GradleException: Code generation failed.
...
Caused by: java.lang.RuntimeException: Could not process model 'AbstractBaseClass'.Please make sure that your schema is correct!
...
Caused by: java.lang.RuntimeException: Stack overflow hit when looking for AbstractBaseClass an infinite loop starting and ending at ConcreteClassWithGrandchild was seen
at org.openapitools.codegen.DefaultCodegen.getAllOfDescendants(DefaultCodegen.java:3491)
at org.openapitools.codegen.DefaultCodegen.createDiscriminator(DefaultCodegen.java:3573)
at org.openapitools.codegen.DefaultCodegen.fromModel(DefaultCodegen.java:3035)
at org.openapitools.codegen.DefaultGenerator.processModels(DefaultGenerator.java:1765)
at org.openapitools.codegen.DefaultGenerator.generateModels(DefaultGenerator.java:523)
...
This issue seems related to the previously reported and fixed issue: #2603. However, that fix doesn't seem to resolve the problem in our case, potentially because of the grandchild sealed class relationship, or some interaction with the other annotations.
Expected Behavior:
The OpenAPI schema should be generated successfully without a StackOverflowError.
Actual Behavior:
A StackOverflowError occurs during schema generation, preventing the build from completing.
Steps to Reproduce:
While I can't share the exact code, the provided class structure above outlines a simplified version. Creating a similar setup with:
- Kotlin sealed class.
- Multiple subtypes.
- Grandchild in sealed class hierarchy.
- @JsonTypeInfo, @JsonSubTypes, @JsonAlias, and @JsonInclude annotations.
- Spring Boot 3.4.1 and springdoc-openapi 2.8.5
should reproduce it.
Environment:
- Spring Boot: 3.4.1
- springdoc-openapi-starter-common: 2.8.5
- springdoc-openapi-starter-webmvc-ui: 2.8.5
- Kotlin
- Gradle
Could you please investigate this issue? It's breaking our doc generation completely. Thank you!