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
integer values with format: int64.
- Object defaults defined through
allOf, oneOf, or anyOf.
byte and binary defaults.
- Defaults for referenced enums inside composed schemas.
- Explicit
null defaults on objects.
Version
- OpenAPI Generator:
7.25.0.
- Generators:
spring and java.
- 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: string
For 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.
10 and 20 are Integer literals, not Long literals, and are incompatible with List<Long> type inference.
- The
oneOf default is emitted as raw JSON instead of a Java expression.
byte[] values are converted to the Object.toString() representation ([B@...) instead of being decoded from Base64.
binary values are converted to a string ([B@...) even when the generated type is Resource or File.
- For some objects with
default: null, the generator logs a ClassCastException from NullNode to ObjectNode and 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
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.
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.
Description
The Java
springandjavagenerators can produce uncompilable Java code, or silently discard a value, when an OpenAPI property declares a complexdefaultvalue 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.0and affects, among others, the following cases:integervalues withformat: int64.allOf,oneOf, oranyOf.byteandbinarydefaults.nulldefaults on objects.Version
7.25.0.springandjava.3.0.3.Minimal Specification
For example, generation can be configured with Maven as follows:
Current Result
The
springgenerator produces code such as:The observed problems are:
Arrays.asList(, )is not a valid Java expression.10and20areIntegerliterals, notLongliterals, and are incompatible withList<Long>type inference.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.default: null, the generator logs aClassCastExceptionfromNullNodetoObjectNodeand continues generation.The
javagenerator shows the same array, composition, andbyteproblems. Forbinary, it normally usesjava.io.File, so a valid and deterministic behavior must be defined for a binary default that cannot be materialized directly as aFile.Expected Result
The generators should produce compilable Java code while preserving the meaning of the contract. For example:
For
binary, if the Java type allows the content to be materialized, a valid equivalent expression should be generated. If the mapped type isFileand 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.nulldefaults should be processed without internal exceptions or misleading stack traces.Acceptance Criteria
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.nulldefaults do not cause internal generator exceptions.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.
$ref/allOfgenerate uncompilable Java.defaultonallOf+$refproperty is no longer generated (regression in 7.24.0) #24384 — regression where enum defaults are lost forallOf+$ref.@RequestParamannotations.Stringvalues instead of enum constants.binary/filetype mappings.Implementation Proposal
Centralize default rendering in
AbstractJavaCodegenso the Java generators share the same typed conversion logic. The implementation should preferCodegenPropertymetadata and resolved schemas over callingtoString()on raw values, and should add a compilation test for the generated code.