Repository navigation
[BUG][JAVA] Complex OpenAPI defaults generate uncompilable Java code #24993
Description
Description
The Java spring and java generators can produce uncompilable Java code, or silently discard a value, when an OpenAPI property declares a complex default value or a scalar value that requires typed conversion.
The problem occurs in the common AbstractJavaCodegen.toDefaultValue() logic and in the handling of default values for arrays and composed schemas. It does not appear to be specific to a single generator.
The issue is reproducible with OpenAPI Generator 7.25.0 and affects, among others, the following cases:
- Arrays of objects.
- Nested arrays.
- Arrays of
integervalues withformat: int64. - Object defaults defined through
allOf,oneOf, oranyOf. byteandbinarydefaults.- Defaults for referenced enums inside composed schemas.
- Explicit
nulldefaults on objects.
Version
- OpenAPI Generator:
7.25.0. - Generators:
springandjava. - OpenAPI:
3.0.3.
Minimal Specification
openapi: 3.0.3
info:
title: Complex defaults
version: 1.0.0
paths: {}
components:
schemas:
DefaultObject:
type: object
required:
- name
- count
properties:
name:
type: string
count:
type: integer
format: int32
status:
$ref: '#/components/schemas/Status'
Status:
type: string
enum:
- ACTIVE
- INACTIVE
Payload:
type: object
properties:
objectArray:
type: array
default:
- name: first
count: 1
status: ACTIVE
- name: second
count: 2
status: INACTIVE
items:
$ref: '#/components/schemas/DefaultObject'
longArray:
type: array
default:
- 10
- 20
items:
type: integer
format: int64
objectAllOf:
allOf:
- $ref: '#/components/schemas/DefaultObject'
default:
name: all-of
count: 3
status: ACTIVE
objectOneOf:
oneOf:
- $ref: '#/components/schemas/DefaultObject'
default:
name: one-of
count: 4
status: ACTIVE
byteValue:
type: string
format: byte
default: ZGVmYXVsdA==
binaryValue:
type: string
format: binary
default: ZGVmYXVsdA==
NullableObject:
type: object
properties:
value:
type: object
default: null
properties:
name:
type: stringFor example, generation can be configured with Maven as follows:
<plugin>
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>7.25.0</version>
<configuration>
<generatorName>spring</generatorName>
<inputSpec>${project.basedir}/src/main/resources/openapi.yaml</inputSpec>
<output>${project.build.directory}/generated-sources/openapi</output>
<generateApiTests>false</generateApiTests>
<generateModelTests>false</generateModelTests>
</configuration>
</plugin>Current Result
The spring generator produces code such as:
private List<@Valid DefaultObject> objectArray =
new ArrayList<>(Arrays.asList(, ));
private List<Long> longArray =
new ArrayList<>(Arrays.asList(10, 20));
private PayloadObjectOneOf objectOneOf =
{"name":"one-of","count":4,"status":"ACTIVE"};
private byte[] byteValue = "[B@...";
private org.springframework.core.io.Resource binaryValue = "[B@...";The observed problems are:
Arrays.asList(, )is not a valid Java expression.10and20areIntegerliterals, notLongliterals, and are incompatible withList<Long>type inference.- The
oneOfdefault is emitted as raw JSON instead of a Java expression. byte[]values are converted to theObject.toString()representation ([B@...) instead of being decoded from Base64.binaryvalues are converted to a string ([B@...) even when the generated type isResourceorFile.- For some objects with
default: null, the generator logs aClassCastExceptionfromNullNodetoObjectNodeand continues generation.
The java generator shows the same array, composition, and byte problems. For binary, it normally uses java.io.File, so a valid and deterministic behavior must be defined for a binary default that cannot be materialized directly as a File.
Expected Result
The generators should produce compilable Java code while preserving the meaning of the contract. For example:
private List<@Valid DefaultObject> objectArray =
new ArrayList<>(Arrays.asList(
new DefaultObject().name("first").count(1).status(Status.ACTIVE),
new DefaultObject().name("second").count(2).status(Status.INACTIVE)));
private List<Long> longArray =
new ArrayList<>(Arrays.asList(10L, 20L));
private byte[] byteValue =
java.util.Base64.getDecoder().decode("ZGVmYXVsdA==");For binary, if the Java type allows the content to be materialized, a valid equivalent expression should be generated. If the mapped type is File and there is no portable way to embed the content, the generator should omit the initializer or emit a clear diagnostic, but it must never generate a non-compiling [B@... string.
null defaults should be processed without internal exceptions or misleading stack traces.
Acceptance Criteria
- Object-array defaults generate valid Java expressions.
- Nested-array defaults are processed recursively.
-
int64values retain theLongtype in arrays and objects. -
allOf,oneOf, andanyOfobject defaults do not emit raw JSON or attempt to instantiate interfaces. -
bytedefaults are generated as valid Base64 conversions. -
binarydefaults generate valid code or an explicit behavior when the mapped type cannot materialize the content. - Enum defaults, including referenced enums inside compositions, generate enum constants rather than strings.
-
nulldefaults do not cause internal generator exceptions. - Generation and compilation tests are added for the cases above in the affected Java generators.
- Existing behavior for simple defaults and composed object defaults is preserved.
Related Issues and PRs
This issue groups several default-generation problems that share the same code path. It is not intended to replace the existing reports; it provides a common place to coordinate a fix and a shared regression matrix.
- [BUG][Java] adding default with a reference using allOf (implicitely) results in uncompileable code #23795 — object defaults with
$ref/allOfgenerate uncompilable Java. - [Java] Render object default for composed ($ref + default) schemas (#23795) #23971 — PR that partially fixed composed object defaults while leaving enum/scalar handling on a separate path.
- [BUG] [Java] Object defaults with enum properties generate invalid fluent builder expressions #24298 — object defaults with enum properties generate invalid fluent builders using strings.
- [BUG][Java] Enum
defaultonallOf+$refproperty is no longer generated (regression in 7.24.0) #24384 — regression where enum defaults are lost forallOf+$ref. - [BUG] [JAVA] Defaults for nested arrays produce invalid code #21589 — nested-array defaults generate invalid Java expressions.
- [BUG][JAVA][MAVEN] Array aliases generate uncompilable Java code with generateAliasAsModel=true #23988 — array aliases generate uncompilable Java code.
- [BUG] [JAVA] Default values are ignored #11459 — Java property defaults are ignored.
- [BUG][JAVA][SPRING] Default values for arrays ignored in spring annotation defaultValue #11957 — array defaults are ignored in Spring
@RequestParamannotations. - [BUG][JAVA] Default value of required array #12678 — default behavior for required arrays.
- [BUG][ALL] Array of object not generated #9150 — object arrays are not generated correctly.
- [BUG] default values for references enums are not generated correctly #14689 — referenced enum defaults are generated incorrectly.
- [BUG][Java] Enum default value generated as string instead of enum value #15144 — enum defaults are generated as
Stringvalues instead of enum constants. - [BUG][Java][Native] invalid generated code when binary/file responses are mapped to InputStream #24057 — invalid Java code related to
binary/filetype mappings.
Implementation Proposal
Centralize default rendering in AbstractJavaCodegen so the Java generators share the same typed conversion logic. The implementation should prefer CodegenProperty metadata and resolved schemas over calling toString() on raw values, and should add a compilation test for the generated code.
Activity
[BUG][JAVA] Fix generation of complex default values (fixes OpenAPITo…
[java][okhttp] Do not seed addItem/putItem with the container default