Repository navigation
[JAVA, JAVA-SPRING, KOTLIN-CLIENT, KOTLIN-SPRING] - feature - add x-jackson-default-impl / typeInfoDefaultImpls support to allow specifying of fallback schema when deserializing - #23955
Conversation
…foDefaultImpls support
Emit `@JsonTypeInfo(defaultImpl = ...)` for both deduction-based and
discriminator-based oneOf interfaces.
Two configuration sources (config option takes precedence):
- Schema extension: `x-jackson-default-impl: ClassName`
- Config option: `typeInfoDefaultImpls: {SchemaName: ClassName}`
The resolved class name passes through `toModelName()` so schemaMapping,
importMapping, and DTO prefix/suffix are all honoured. A LOGGER.warn is
emitted when the config option shadows a schema-level annotation.
There was a problem hiding this comment.
1 issue found across 9 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| public static final String USE_SEALED_RESPONSE_INTERFACES = "useSealedResponseInterfaces"; | ||
| public static final String COMPANION_OBJECT = "companionObject"; | ||
| public static final String SUSPEND_FUNCTIONS = "suspendFunctions"; | ||
| public static final String TYPE_INFO_DEFAULT_IMPLS = "typeInfoDefaultImpls"; |
There was a problem hiding this comment.
@Picazsoo Could you also add the feature to the java generators?
See src/main/resources/Java/deductionAnnotation.mustache and the different typeInfoAnnotation.mustache under java/libraries
There was a problem hiding this comment.
I will take a look at it. And this is early implementation without any polish. I marked temporarily as "ready for review" just to gather early feedback from Cubic
There was a problem hiding this comment.
But thanks for the review! I will properly tag you once I think it is ready for wasting human review time (-:
There was a problem hiding this comment.
Hi @jpfinne, I added it to the java generators as well.
There was a problem hiding this comment.
This is now ready for review
# Conflicts: # modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java
…Java generators - Add TYPE_INFO_DEFAULT_IMPLS/DESC constants to CodegenConstants (addresses reviewer request to avoid duplication across SpringCodegen and KotlinSpringServerCodegen) - Move typeInfoDefaultImpls field, option registration, processOpts parsing, and x-jackson-resolved-default-impl resolution loop from SpringCodegen into AbstractJavaCodegen so all Java generators inherit the feature - Remove duplicated code from SpringCodegen; update KotlinSpringServerCodegen to reference CodegenConstants.TYPE_INFO_DEFAULT_IMPLS and apply the same safe instanceof cast fix already present in SpringCodegen - Update Java/deductionAnnotation.mustache: emit defaultImpl = X.class on @JsonTypeInfo(use = DEDUCTION) when x-jackson-resolved-default-impl is set - Update Java/typeInfoAnnotation.mustache: emit defaultImpl = X.class on both @JsonTypeInfo(use = NAME) variants (discriminator present/absent) via discriminator.vendorExtensions.x-jackson-resolved-default-impl - Add JavaClientCodegenTest tests covering deduction, discriminator, typeInfoDefaultImpls config option, and absence cases for Java client Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
All reported issues were addressed across 17 files
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
There was a problem hiding this comment.
9 issues found across 27 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="modules/openapi-generator/src/main/resources/kotlin-spring/typeInfoAnnotation.mustache">
<violation number="1" location="modules/openapi-generator/src/main/resources/kotlin-spring/typeInfoAnnotation.mustache:6">
P1: Missing validation that the resolved defaultImpl is a subtype of the polymorphic base; misconfigured `x-jackson-default-impl` or `typeInfoDefaultImpls` values will compile but fail at runtime during deserialization.</violation>
</file>
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
# Conflicts: # modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java
|
Tagging @wing328 - please consider if this contribution makes sense and if it would make sense for 7.24.0 |
# Conflicts: # docs/generators/kotlin-spring.md # docs/generators/kotlin.md # modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java # modules/openapi-generator/src/test/java/org/openapitools/codegen/java/spring/SpringCodegenTest.java
There was a problem hiding this comment.
All reported issues were addressed across 333 files
Note: This PR contains a large number of files. cubic only reviews up to 200 files per PR, so some files may not have been reviewed. cubic prioritizes the most important files to review.
Re-trigger cubic
There was a problem hiding this comment.
All reported issues were addressed across 74 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
|
Hi @wing328 , I wonder if this feature is acceptable or not as is? |
…on-default # Conflicts: # docs/generators/java-camel.md # docs/generators/spring.md # modules/openapi-generator/src/main/java/org/openapitools/codegen/VendorExtension.java # modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/SpringCodegen.java
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
All reported issues were addressed across 30 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
There was a problem hiding this comment.
All reported issues were addressed across 329 files
Requires human review: Auto-approval blocked by 2 unresolved issues from a previous review of this commit.
Re-trigger cubic
- Extract shared JacksonDefaultImplResolver used by AbstractJavaCodegen,
KotlinClientCodegen and KotlinSpringServerCodegen (dedup resolution logic)
- Preserve external/FQN class names for defaultImpl (add import, emit simple
name) instead of mangling them through toModelName
- JavaMicroprofileServerCodegen: strip x-jackson-default-impl before model
post-processing so the vendor extension no longer leaks defaultImpl
- Guard typeInfoAnnotation with discriminator in Java/oneof_interface.mustache
so deduction-based oneOf keeps defaultImpl and drops the bogus property=""
- Correct kotlin-client typeInfoDefaultImpls description (discriminator/jackson
only) and regenerate docs/generators/kotlin.md
- Move ext{} version block before the android branch in Java build.gradle
templates (base + 12 libraries) to fix -Ptarget=android config failure
- Default stricter generateJsonInclude/JsonSetterNulls options on Spring-family
jackson-default-impl configs and render them in java-camel-server pojo
- Add useDeductionForOneOfInterfaces to the restclient sample config
- Regenerate all affected samples
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
All reported issues were addressed across 134 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
…ering - oneof_interface.mustache: render typeInfoAnnotation for non-discriminator oneOf when not using deduction, so sealed oneOf interfaces keep their @JsonTypeInfo/@JsonIgnoreProperties (byte-for-byte stable with master); only suppress it in the deduction path to avoid a duplicate @JsonTypeInfo - deductionAnnotation.mustache: add a leading newline and render at column 0 (mirroring typeInfoAnnotation) so @JsonTypeInfo no longer lands on the same line as @generated - webclient build.gradle.mustache: move the stray jspecify implementation out of the ext{} block into dependencies{} so it runs after the java plugin creates the implementation configuration (fixes useJspecify=true builds while keeping ext{} before the android branch) - Regenerate affected Java client samples Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…on-default # Conflicts: # modules/openapi-generator/src/main/resources/Java/libraries/apache-httpclient/build.gradle.mustache # samples/client/echo_api/java/apache-httpclient/build.gradle # samples/client/petstore/java/apache-httpclient-jackson3/build.gradle # samples/client/petstore/java/apache-httpclient/build.gradle
The forbiddenapis check rejects locale-dependent String.format(String, Object...). Pass Locale.ROOT explicitly, matching the convention used across the codegen language classes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ver" This reverts commit 9cfd134.
…lver" This reverts commit 57f56be.
|
Hello @wing328, I made the PR up-to-date and resolved all the standing issues. |
|
Just merged it. Sorry for the delay as I missed it. |
|
No problem, thanks a bunch! |
Purpose
Complements the current oneOf Jackson polymorphism by making it possible to supply a default fallback value for deserialization. This is useful e.g. when you want to specify a default for deduction-based polymorphism (FasterXML/jackson-databind#3055), or when you want to fall back to some no-op class.
What it adds
Emits
@JsonTypeInfo(defaultImpl = ...)on polymorphiconeOfinterfaces. Two opt-in ways to configure it (both default to disabled):x-jackson-default-impl: <ClassName>on a schema.typeInfoDefaultImpls: {SchemaName: ClassName}, which overrides the vendor extension when both are set for the same schema.Class names are resolved via
toModelName(honoring model mappings and DTO prefix/suffix); warns on overrides and unknown targets.Scope
java(client)springkotlin-springkotlin(client)java-microprofileResolution is centralized in
AbstractJavaCodegen(shared by Java + Spring). Templates only emitdefaultImplwhen a value is resolved, so output is byte-for-byte identical to before for anyone who doesn't opt in.Tests & docs
kotlin-spring, andkotlinclient, covering deduction/discriminator cases, config override, model-name suffix handling, and anoDefaultImplWhenNeitherSourceIsSetcase that confirms no change when unconfigured.3_0/spring/jackson-default-impl.yaml.java,spring,kotlin-spring,kotlin, andjava-camel; newx-jackson-default-implvendor extension registered.PR checklist
Commit all changed files.
This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
These must match the expectations made by your contribution.
You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example
./bin/generate-samples.sh bin/configs/java*.IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
Summary by cubic
Adds an opt‑in Jackson default fallback for deserializing oneOf interfaces. Previously no default existed; now, when configured via
x-jackson-default-implortypeInfoDefaultImpls, generators emit@JsonTypeInfo(defaultImpl=...). Unconfigured outputs are unchanged.JacksonDefaultImplResolver, preserving FQCNs (add import, emit simple name), honoring schema/import mappings and DTO prefix/suffix;typeInfoDefaultImplsoverrides the vendor extension and warns on shadowed or unknown targets; logs useLocale.ROOT.javaandspring:defaultImplfor deduction (Id.DEDUCTION) and discriminator (Id.NAME) oneOf interfaces.kotlin-spring: deduction and discriminator;kotlinclient: discriminator only.java-microprofile: disabled; stripsx-jackson-default-implduring model processing.@JsonTypeInfofor non‑discriminator oneOf when not using deduction; adddefaultImplto deduction annotations; avoid duplicate@JsonTypeInfoand render on its own line.ext {}before the Android branch across Java templates; fixwebclientuseJspecify=true; documenttypeInfoDefaultImplsand the vendor extension; regenerate samples and CI workflows for Java RestClient, Spring Boot,kotlin-spring,kotlinclient, and Java Camel;java-camelPOJOs can render@JsonInclude/@JsonSetter(nulls=...)when configured.CodegenConstants.TYPE_INFO_DEFAULT_IMPLS; tests cover deduction/discriminator cases and config precedence acrossjava,spring,kotlin-spring, andkotlinclient.Migration
x-jackson-default-impl: ClassNameon a schema or configuretypeInfoDefaultImpls: {SchemaName: ClassName}; the config option overrides the extension. No action required if you do not opt in.Written for commit a007a4c. Summary will update on new commits.