Description
Starting with version 5.0.0, jsonschema-generator switched to Jackson 3 and introduced a change in how the default ObjectMapper is created in SchemaGeneratorConfigBuilder. This unintentionally introduced a regression: numeric JSON Schema keywords (e.g., minLength, minItems, maxProperties, etc.) are now serialized as strings instead of numbers when the default mapper is used (which is the case in the Maven plugin).
Background
In versions < 5.0.0, the method createDefaultObjectMapper() looked like this:
private static ObjectMapper createDefaultObjectMapper() {
ObjectMapper mapper = new ObjectMapper()
// since version 4.32.0; pretty print by default (can be overridden by supplying explicit mapper)
.enable(SerializationFeature.INDENT_OUTPUT);
mapper.getSerializationConfig()
// since version 4.21.0
.with(JsonWriteFeature.WRITE_NUMBERS_AS_STRINGS);
// since version 4.25.0; as the above doesn't always work
mapper.setNodeFactory(JsonNodeFactory.withExactBigDecimals(true));
return mapper;
}
The call to:
mapper.getSerializationConfig().with(JsonWriteFeature.WRITE_NUMBERS_AS_STRINGS);
had no effect, because with(...) returns a new SerializationConfig instance which is not applied back to the ObjectMapper.
Thus, although the feature was declared, numerical values were still serialized correctly as numbers.
Change in 5.0.0
Since 5.0.0, the method was rewritten using JsonMapper.builder():
private static ObjectMapper createDefaultObjectMapper() {
return JsonMapper.builder()
// since version 4.32.0; pretty print by default (can be overridden by supplying explicit mapper)
.enable(SerializationFeature.INDENT_OUTPUT)
// since version 4.21.0
.enable(JsonWriteFeature.WRITE_NUMBERS_AS_STRINGS)
// since version 4.25.0; as the above doesn't always work
.enable(JsonNodeFeature.STRIP_TRAILING_BIGDECIMAL_ZEROES)
.build();
}
This time, WRITE_NUMBERS_AS_STRINGS is actually applied to the mapper, because the builder enforces it during construction.
As a result, all numbers — including JSON Schema keywords — are serialized as strings, for example:
{
"type": "string",
"minLength": "3"
}
instead of:
{
"type": "string",
"minLength": 3
}
This violates the JSON Schema specification and breaks downstream tooling.
Impact
- The Maven plugin is directly affected because it uses the default mapper.
- JSON Schema validators, editors, and code generators may reject or misinterpret schemas.
- This is a behavior regression compared to version 4.x, where numbers were always written as numbers.
Expected behavior
Numeric JSON Schema keywords should be serialized as numbers, consistent with:
- JSON Schema specification
- Behavior of jsonschema-generator < 5.0.0
- Jackson's default behavior
The default mapper should not turn schema metadata fields into strings.
Possible solutions
-
Remove JsonWriteFeature.WRITE_NUMBERS_AS_STRINGS from the default mapper
→ safest choice, because the feature was not actually effective in previous versions.
-
Apply number-to-string conversion only to actual instance values
→ likely impractical, since schema serialization uses a single mapper.
-
Keep the behavior but document the breaking change
→ does not help Maven plugin users unless they explicitly override the mapper.
-
Retain strict BigDecimal handling (withExactBigDecimals(true)) without enabling global number-to-string conversion
→ closest to the original intention.
Suggested fix
Remove:
.enable(JsonWriteFeature.WRITE_NUMBERS_AS_STRINGS)
from the default mapper in 5.x, because the feature was never effectively active in earlier versions and now causes incorrect JSON Schema output.
Description
Starting with version 5.0.0, jsonschema-generator switched to Jackson 3 and introduced a change in how the default ObjectMapper is created in SchemaGeneratorConfigBuilder. This unintentionally introduced a regression: numeric JSON Schema keywords (e.g.,
minLength,minItems,maxProperties, etc.) are now serialized as strings instead of numbers when the default mapper is used (which is the case in the Maven plugin).Background
In versions < 5.0.0, the method createDefaultObjectMapper() looked like this:
The call to:
had no effect, because with(...) returns a new SerializationConfig instance which is not applied back to the ObjectMapper.
Thus, although the feature was declared, numerical values were still serialized correctly as numbers.
Change in 5.0.0
Since 5.0.0, the method was rewritten using JsonMapper.builder():
This time, WRITE_NUMBERS_AS_STRINGS is actually applied to the mapper, because the builder enforces it during construction.
As a result, all numbers — including JSON Schema keywords — are serialized as strings, for example:
{ "type": "string", "minLength": "3" }instead of:
{ "type": "string", "minLength": 3 }This violates the JSON Schema specification and breaks downstream tooling.
Impact
Expected behavior
Numeric JSON Schema keywords should be serialized as numbers, consistent with:
The default mapper should not turn schema metadata fields into strings.
Possible solutions
Remove JsonWriteFeature.WRITE_NUMBERS_AS_STRINGS from the default mapper
→ safest choice, because the feature was not actually effective in previous versions.
Apply number-to-string conversion only to actual instance values
→ likely impractical, since schema serialization uses a single mapper.
Keep the behavior but document the breaking change
→ does not help Maven plugin users unless they explicitly override the mapper.
Retain strict BigDecimal handling (withExactBigDecimals(true)) without enabling global number-to-string conversion
→ closest to the original intention.
Suggested fix
Remove:
from the default mapper in 5.x, because the feature was never effectively active in earlier versions and now causes incorrect JSON Schema output.