[core] Fix UnsupportedOperationException for oneOf members declaring x-implements (#23577)#24076
Merged
wing328 merged 1 commit intoJun 21, 2026
Conversation
) OneOfImplementorAdditionalData.addToImplementor used putIfAbsent + List.add on the model's x-implements vendor extension. When a oneOf member schema already declares x-implements in the spec, the parsed value is a scalar string or an immutable list, so appending the oneOf interface threw java.lang.UnsupportedOperationException during model post-processing. Normalize the existing value into a fresh mutable list (preserving any user-supplied interfaces) before appending. No behavior change for models without a pre-existing x-implements.
Member
|
tested locally to confirm no longer get the UnsupportedOperationException. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #23577
Problem
When a schema is a member of a
oneOfand also declares its ownx-implementsin the spec, generation crashes withjava.lang.UnsupportedOperationExceptionduring model post-processing:addToImplementordidputIfAbsent(X_IMPLEMENTS, new ArrayList<>())and thenList.add(...)on the stored value. When the model already carriesx-implementsfrom the spec, that value is the parser-supplied object (a scalar string or an immutable list), soputIfAbsentis a no-op and the subsequentaddfails.This is the default
oneOf-interface code path. The existingoneOf_issue_23577test only covers theREPLACE_ONE_OF_BY_DISCRIMINATOR_MAPPINGnormalizer path, which convertsoneOfto inheritance and never reaches this code — so the default path remained broken.Fix
Normalize the existing
x-implementsvalue into a fresh mutable list (preserving any user-supplied interfaces, whether stored as a scalar string or a list) before appending theoneOfinterface. Models without a pre-existingx-implementsare unaffected — the result is identical to the previousputIfAbsent(new ArrayList<>())behavior.Test evidence
Added
SpringCodegenTest#oneOf_issue_23577_userDefinedXImplements, which generates the reporter's spec on the defaultoneOf-interface path (no normalizer) and asserts the member implements both its declared interface and theoneOfparent:CreatedEventimplementscom.example.NotificationandEventUpdatedEventimplementsEventConfirmed the new test fails with
UnsupportedOperationExceptionbefore the change and passes after. The pre-existingoneOf_issue_23577andOneOfImplementorAdditionalDataTeststill pass.No generated samples change (the previously-crashing combination produced no committed samples; the no-
x-implementspath is byte-for-byte unchanged), so no sample regeneration is included.Verification done: (1) no in-flight PR (searched open PRs for
x-implements/OneOfImplementor/#23577); (2) no claim comments on the issue; (3) code fix in.javaonly; (4) reproduced the crash onupstream/mastervia a failing test, then confirmed the fix; (5) no parent epic.Summary by cubic
Fixes a crash when a oneOf member also declares its own
x-implements. We now normalize existingx-implementsto a mutable list before adding the oneOf interface.x-implements(string or immutable list) into a new mutable list before appending oneOf interfaces; models withoutx-implementsare unchanged.oneOf_issue_23577_userDefinedXImplementsto verify members implement both the user-defined interface(s) and the oneOf parent.Written for commit bac76e7. Summary will update on new commits.