Skip to content

Conversation

tiger9800
Copy link

To implement FasterXML/jackson-databind#5317, we would like to use radix property of the @JsonFromat annotation. We make sure to add it to JsonFormat.Value to parallel the behavior of other properties of the @jsonformat annotation.

@cowtowncoder
Copy link
Member

We have one potential problem here: there's no real "default" marker here, so any use of @JsonFormat would cause override with radix 10 -- since there's no way to tell explicit "10" from default (when radix omitted. That is these are equivalent:

@JsonFormat(shape=Shape.STRING, radix=10)
@JsonFormat(shape=Shape.STRING)

which becomes problem when using global or per-type defaults.

So I think it is necessary to instead use "magic constant" to indicate "use default"; -1 would be traditional choice. This would need to be translated when requested (separate accessor for translating and "raw" value?), and considered when merging Value instances.

@tiger9800
Copy link
Author

Wouldn't we be fine with 10 being a default? Radix only becomes relevant when we are serializing a Number and shape is String, and currently we always serialize numbers as strings in base 10. We will keep doing so if @JsonFormat(shape=Shape.STRING, radix=10) or @JsonFormat(shape=Shape.STRING). My plan was to even check in NumberSerializer against @JsonFromat.DEFAULT_RADIX and decide if we need to employ the special DifferentRadixSerializer.

@cowtowncoder
Copy link
Member

@tiger9800 Problem is not direct @JsonFormat usage but the case where global/type defaults are set to, for example, use radix 16 (for hex). If so, that'd be overwritten by @JsonFormat without radix property (or rather, one for which default of 10 is applied).
Behavior in such cases should vary b/w explicit radix value and default.
Bit like why OptBoolean is used instead of boolean for some annotation to distinguish between "true", "false" and "default".

@tiger9800
Copy link
Author

Oh I see, we can put a global config override of 16 and then apply an annotation @JsonFormat(shape=Shape.STRING) to some property that is a subclass of Number. We would expect the Number to be serialized as a hex string, but it will be serialized as a base-10 string because @JsonFormat(shape=Shape.STRING) with a default radix of 10 had higher precedence.

Great catch, thank you. Will fix!

@cowtowncoder
Copy link
Member

@tiger9800 Exactly! We have had this challenge for some annotations before which is why I recognized it :)

@tiger9800
Copy link
Author

Added the marker default value. For translating from raw value, we have JsonFormat.Value#hasNonDefaultRadix, so I imagine this is enough. Please let me know what you think.

@tiger9800 tiger9800 requested a review from cowtowncoder October 2, 2025 05:16
Comment on lines 956 to 957
public boolean hasNonDefaultRadix() {
return _radix != DEFAULT_RADIX && _radix != 10;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should not check against 10 as ObjectMapper may specify other default radix

Copy link
Member

@cowtowncoder cowtowncoder left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Close; left couple of notes for changes.

@cowtowncoder
Copy link
Member

A unit test failure wrt String representation.

@tiger9800 tiger9800 requested a review from cowtowncoder October 3, 2025 15:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants