Repository navigation
Commit 1f57b0e
[java] fix: okhttp-gson additionalProperties field makes every allOf child undeserializable (#24895)
* [java] fix: the okhttp-gson additionalProperties bag breaks every allOf child
With disallowAdditionalPropertiesIfNotPresent=false every model declares
private Map<String, Object> additionalProperties - so an allOf child
declares the field twice, once itself and once inherited, and gson refuses
the class before the model's own TypeAdapterFactory can run:
IllegalArgumentException: Class Child declares multiple JSON fields
named 'additionalProperties'
Every allOf child model is undeserializable (and unserializable). Mark the
field transient: the custom TypeAdapterFactory already reads and writes the
bag explicitly around the reflective delegate - on write it even removes
the additionalProperties key the delegate emitted - so hiding it from
gson's reflection changes nothing for flat models and unbreaks the children.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GcwZ1arjLZNpetHz2a3TJz
* [java] fix: keep the bag visible on parents that have no adapter of their own
Review caught that models with children get no CustomTypeAdapterFactory
({{^hasChildren}} in pojo.mustache), so a transient field on such a parent
silently dropped its bag - reflection was its only carrier. The transient
modifier is now gated the same way the factory is: parents with children
keep the field visible (their reflective round-trip is unchanged), and an
allOf child's transient declaration shadows it, so the duplicate-field
conflict still cannot arise.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GcwZ1arjLZNpetHz2a3TJz
* [java] docs: describe gson's field binding accurately
Gson does not use Java field-hiding semantics: it collects the declared
fields of each class in the hierarchy and refuses two bound to one JSON
name, so the child's transient declaration excludes its own copy rather
than hiding the parent's. Same behaviour, correct description - the
comment ships into every generated model.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GcwZ1arjLZNpetHz2a3TJz
* [java] fix: declare the okhttp-gson bag once per allOf hierarchy
Review caught that a three-level allOf chain (Root <- Middle <- Leaf) still
broke: only models without children marked their copy transient, so Root
and Middle - both parents - each kept a reflectively bound
additionalProperties field, and gson refused Middle and Leaf alike
("declares multiple JSON fields named 'additionalProperties'").
Marking Middle's copy transient as well would not do: a parent has no
TypeAdapterFactory, so reflection would fill Root's field while Middle's
accessors read its own, dropping the bag. Instead the field is now declared
exactly once, on the topmost ancestor that has one; JavaClientCodegen tags
every descendant with x-inherits-additional-properties, and those models
inherit the field and its getters, override putAdditionalProperty only to
keep the covariant return type, and leave the bag to super.equals,
super.hashCode and super.toString.
Adds a multi-level regression test (fails without this change) and
regenerates the okhttp-gson samples.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* [java] fix: round-trip a literal additionalProperties key on allOf children
Review caught that a descendant inherits the bag from a class that has children, so
the field is not transient and gson's reflective delegate binds it. An undeclared
property literally named `additionalProperties` therefore landed in the bag twice:
the delegate stored it under its own name, and the descendant's adapter then read the
same key from the raw JSON and flattened its entries into the bag. Writing back
emitted those entries as top-level properties, so
{"className":"Dog","breed":"b","additionalProperties":{"x":1},"extra":"e"} came out
with a phantom top-level "x":1.0.
The adapter now clears the delegate-bound bag right after fromJsonTree, before the
loop that collects the undeclared keys. That loop re-reads every one of them from the
raw JSON, the literal key included, so nothing is lost and it round-trips as a single
entry. The clear is emitted only for models tagged
x-inherits-additional-properties: a model that declares the bag itself keeps it
transient, so the delegate binds nothing into it and there is nothing to clear.
Extends the codegen tests with the emitted clear and adds a runtime round-trip to the
okhttp-gson sample's hand-written JSONTest.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* test: [java] record the new checksum of the okhttp-gson JSONTest
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
* [java] fix: hide a literal additionalProperties key from the okhttp-gson delegate
On an allOf child the inherited bag is visible to gson's reflection, so the
delegate adapter tried to bind a literal `additionalProperties` key into the
Map-typed field and threw on a primitive or array value. The adapter now hands
the delegate a copy without that key (only when present) and the extras loop
collects it from the raw JSON like any other undeclared property. The delegate
no longer binds anything into the bag, so the clear() is dropped.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* [java] refactor: drop transient and the literal-key handling from the okhttp-gson bag
Declaring the additionalProperties field once per hierarchy already removes
the duplicate that gson rejects, so `transient` fixed nothing: it only
changed flat models, which were never broken (and dropped the bag from Java
serialization under serializableModel). Flat models are byte-identical to
master again.
The delegate copy that hid a literal `additionalProperties` JSON key from
the reflective adapter is removed too. Every okhttp-gson model on master
binds that key through the delegate, so it is a pre-existing gap for a
separate fix, not part of this one. allOf descendants now behave exactly
like flat models for it.
The codegen tests assert only the invariant: one class per hierarchy
declares the bag, descendants override putAdditionalProperty.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* test: [java] round-trip an allOf child's additional properties in the okhttp-gson JSONTest
Replaces the two literal-`additionalProperties`-key cases with a plain Dog
round-trip, the case that threw on master, and records the new checksum.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>1 parent e0f8a28 commit 1f57b0e
12 files changed
Lines changed: 165 additions & 187 deletions
File tree
- bin/utils
- modules/openapi-generator/src
- main
- java/org/openapitools/codegen/languages
- resources/Java/libraries/okhttp-gson
- test
- java/org/openapitools/codegen/java
- resources/3_0/java
- samples/client/petstore/java
- okhttp-gson-3.1/src/main/java/org/openapitools/client/model
- okhttp-gson/src
- main/java/org/openapitools/client/model
- test/java/org/openapitools/client
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
13 | | - | |
| 13 | + | |
14 | 14 | | |
15 | 15 | | |
16 | 16 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1233 | 1233 | | |
1234 | 1234 | | |
1235 | 1235 | | |
| 1236 | + | |
| 1237 | + | |
| 1238 | + | |
| 1239 | + | |
| 1240 | + | |
| 1241 | + | |
| 1242 | + | |
| 1243 | + | |
| 1244 | + | |
| 1245 | + | |
| 1246 | + | |
| 1247 | + | |
| 1248 | + | |
| 1249 | + | |
| 1250 | + | |
| 1251 | + | |
| 1252 | + | |
| 1253 | + | |
| 1254 | + | |
1236 | 1255 | | |
1237 | 1256 | | |
1238 | 1257 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
| 2 | + | |
2 | 3 | | |
3 | 4 | | |
4 | 5 | | |
| |||
43 | 44 | | |
44 | 45 | | |
45 | 46 | | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
46 | 64 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
206 | 206 | | |
207 | 207 | | |
208 | 208 | | |
209 | | - | |
210 | | - | |
| 209 | + | |
| 210 | + | |
211 | 211 | | |
212 | 212 | | |
213 | 213 | | |
| |||
223 | 223 | | |
224 | 224 | | |
225 | 225 | | |
226 | | - | |
| 226 | + | |
227 | 227 | | |
228 | 228 | | |
229 | 229 | | |
| |||
245 | 245 | | |
246 | 246 | | |
247 | 247 | | |
| 248 | + | |
248 | 249 | | |
| 250 | + | |
249 | 251 | | |
250 | 252 | | |
251 | 253 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2227 | 2227 | | |
2228 | 2228 | | |
2229 | 2229 | | |
| 2230 | + | |
| 2231 | + | |
| 2232 | + | |
| 2233 | + | |
| 2234 | + | |
| 2235 | + | |
| 2236 | + | |
| 2237 | + | |
| 2238 | + | |
| 2239 | + | |
| 2240 | + | |
| 2241 | + | |
| 2242 | + | |
| 2243 | + | |
| 2244 | + | |
| 2245 | + | |
| 2246 | + | |
| 2247 | + | |
| 2248 | + | |
| 2249 | + | |
| 2250 | + | |
| 2251 | + | |
| 2252 | + | |
| 2253 | + | |
| 2254 | + | |
| 2255 | + | |
| 2256 | + | |
| 2257 | + | |
| 2258 | + | |
| 2259 | + | |
| 2260 | + | |
| 2261 | + | |
| 2262 | + | |
| 2263 | + | |
| 2264 | + | |
| 2265 | + | |
| 2266 | + | |
| 2267 | + | |
| 2268 | + | |
| 2269 | + | |
| 2270 | + | |
| 2271 | + | |
| 2272 | + | |
| 2273 | + | |
| 2274 | + | |
| 2275 | + | |
| 2276 | + | |
| 2277 | + | |
| 2278 | + | |
| 2279 | + | |
| 2280 | + | |
| 2281 | + | |
| 2282 | + | |
| 2283 | + | |
| 2284 | + | |
2230 | 2285 | | |
2231 | 2286 | | |
2232 | 2287 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
79 | 79 | | |
80 | 80 | | |
81 | 81 | | |
82 | | - | |
83 | | - | |
84 | | - | |
85 | | - | |
86 | | - | |
87 | | - | |
88 | | - | |
89 | 82 | | |
90 | 83 | | |
91 | 84 | | |
| 85 | + | |
92 | 86 | | |
93 | 87 | | |
94 | 88 | | |
95 | 89 | | |
96 | 90 | | |
| 91 | + | |
97 | 92 | | |
98 | | - | |
99 | | - | |
100 | | - | |
101 | | - | |
| 93 | + | |
102 | 94 | | |
103 | 95 | | |
104 | 96 | | |
105 | | - | |
106 | | - | |
107 | | - | |
108 | | - | |
109 | | - | |
110 | | - | |
111 | | - | |
112 | | - | |
113 | | - | |
114 | | - | |
115 | | - | |
116 | | - | |
117 | | - | |
118 | | - | |
119 | | - | |
120 | | - | |
121 | | - | |
122 | | - | |
123 | | - | |
124 | | - | |
125 | | - | |
126 | | - | |
127 | 97 | | |
128 | 98 | | |
129 | 99 | | |
| |||
134 | 104 | | |
135 | 105 | | |
136 | 106 | | |
137 | | - | |
138 | | - | |
| 107 | + | |
139 | 108 | | |
140 | 109 | | |
141 | 110 | | |
142 | 111 | | |
143 | 112 | | |
144 | | - | |
| 113 | + | |
145 | 114 | | |
146 | 115 | | |
147 | 116 | | |
| |||
150 | 119 | | |
151 | 120 | | |
152 | 121 | | |
153 | | - | |
154 | 122 | | |
155 | 123 | | |
156 | 124 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
79 | 79 | | |
80 | 80 | | |
81 | 81 | | |
82 | | - | |
83 | | - | |
84 | | - | |
85 | | - | |
86 | | - | |
87 | | - | |
88 | | - | |
89 | 82 | | |
90 | 83 | | |
91 | 84 | | |
| 85 | + | |
92 | 86 | | |
93 | 87 | | |
94 | 88 | | |
95 | 89 | | |
96 | 90 | | |
| 91 | + | |
97 | 92 | | |
98 | | - | |
99 | | - | |
100 | | - | |
101 | | - | |
| 93 | + | |
102 | 94 | | |
103 | 95 | | |
104 | 96 | | |
105 | | - | |
106 | | - | |
107 | | - | |
108 | | - | |
109 | | - | |
110 | | - | |
111 | | - | |
112 | | - | |
113 | | - | |
114 | | - | |
115 | | - | |
116 | | - | |
117 | | - | |
118 | | - | |
119 | | - | |
120 | | - | |
121 | | - | |
122 | | - | |
123 | | - | |
124 | | - | |
125 | | - | |
126 | | - | |
127 | 97 | | |
128 | 98 | | |
129 | 99 | | |
| |||
134 | 104 | | |
135 | 105 | | |
136 | 106 | | |
137 | | - | |
138 | | - | |
| 107 | + | |
139 | 108 | | |
140 | 109 | | |
141 | 110 | | |
142 | 111 | | |
143 | 112 | | |
144 | | - | |
| 113 | + | |
145 | 114 | | |
146 | 115 | | |
147 | 116 | | |
| |||
150 | 119 | | |
151 | 120 | | |
152 | 121 | | |
153 | | - | |
154 | 122 | | |
155 | 123 | | |
156 | 124 | | |
| |||
0 commit comments