Skip to content

Fix NoClassDefFoundError for kotlin.reflect on pure-Java projects#55

Merged
vpelikh merged 1 commit into
mainfrom
GH-54
Jul 14, 2026
Merged

Fix NoClassDefFoundError for kotlin.reflect on pure-Java projects#55
vpelikh merged 1 commit into
mainfrom
GH-54

Conversation

@vpelikh

@vpelikh vpelikh commented Jul 14, 2026

Copy link
Copy Markdown
Owner

Problem

A pure-Java Spring Boot project using springdoc-openapi-starter-webmvc-api crashes on GET /v3/api-docs with java.lang.NoClassDefFoundError: kotlin/reflect/full/KClasses.

Root cause: KotlinRequiredPropertyCustomizer was instantiated and registered as a Spring ModelConverter whenever kotlin-stdlib is on the classpath. The outer SpringDocKotlinConfiguration class is gated only by @ConditionalOnClass(Continuation::class) (kotlin-stdlib), but the customizer's resolve() method uses kotlin.reflect.full.* (kotlin-reflect).

In a pure-Java project, kotlin-stdlib is present while kotlin-reflect is absent (both are <scope>provided</scope> in the common module's pom.xml). So the customizer was created, registered as a ModelConverter, and threw NoClassDefFoundError the first time model resolution touched a Pageable/Sort/Page type — exactly the reporter's stack trace (KotlinRequiredPropertyCustomizer.resolvePageableOpenAPIConverter.resolvePageOpenAPIConverter.resolveSortOpenAPIConverter.resolve).

Solution

Moved the kotlinRequiredPropertyCustomizer @Bean from the outer SpringDocKotlinConfiguration into the inner KotlinReflectDependingConfiguration, which is gated by @ConditionalOnClass(name = ["kotlin.reflect.full.KClasses"]). This matches the other three Kotlin customizers already nested there.

Now the bean is only created when kotlin-reflect is present. For pure-Java projects the customizer is never registered as a ModelConverter, so resolve() is never invoked and the NoClassDefFoundError cannot occur.

Result

Pure-Java and other non-Kotlin consumers (kotlin-stdlib present, kotlin-reflect absent) no longer crash: GET /v3/api-docs now resolves Pageable/Sort/Page models and returns the OpenAPI document as expected.

The failure path is eliminated — KotlinRequiredPropertyCustomizer is never registered as a ModelConverter unless kotlin-reflect is on the classpath, so resolve() can no longer throw NoClassDefFoundError: kotlin/reflect/full/KClasses.

Kotlin projects are unaffected: kotlin-reflect is always present for them, so the customizer is still created and the required-property schema behavior is preserved.

Closes #54

@vpelikh
vpelikh merged commit 6e3c09e into main Jul 14, 2026
6 checks passed
@vpelikh
vpelikh deleted the GH-54 branch July 14, 2026 09:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NoClassDefFoundError: kotlin/reflect/full/KClasses thrown on pure Java project when accessing /v3/api-docs (Spring Boot 4.1.0 + springdoc 5.0.0)

1 participant