[JAVA] Add generic okhttp client - #24734
Conversation
There was a problem hiding this comment.
6 issues found across 3000 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="samples/client/others/java/okhttp-jackson-oneOf/settings.gradle">
<violation number="1" location="samples/client/others/java/okhttp-jackson-oneOf/settings.gradle:1">
P3: The new settings.gradle is missing a trailing newline at end of file, unlike every other sample settings.gradle in this directory. Add a final newline to match conventions and avoid a spurious diff marker.</violation>
</file>
<file name="samples/client/others/java/okhttp-jackson-oneOf/src/main/java/org/openapitools/client/RFC3339InstantDeserializer.java">
<violation number="1" location="samples/client/others/java/okhttp-jackson-oneOf/src/main/java/org/openapitools/client/RFC3339InstantDeserializer.java:32">
P2: This deserializer is never installed in the generated mapper, so the `_fromString` override that normalizes space-separated RFC3339 values never runs. Register `RFC3339JavaTimeModule` in `JSON` alongside `JavaTimeModule`, or omit this supporting class.</violation>
</file>
<file name="samples/client/echo_api/java/okhttp-user-defined-templates/src/main/java/org/openapitools/client/Configuration.java">
<violation number="1" location="samples/client/echo_api/java/okhttp-user-defined-templates/src/main/java/org/openapitools/client/Configuration.java:39">
P2: During concurrent first access, `AtomicReference.updateAndGet` may retry this updater after a CAS failure, so `apiClientFactory.get()` can construct and discard extra clients. Initialize the singleton under a non-retryable critical section, or keep factory invocation outside a retryable updater.</violation>
</file>
<file name="modules/openapi-generator/src/main/resources/Java/libraries/okhttp/additional_properties.mustache">
<violation number="1" location="modules/openapi-generator/src/main/resources/Java/libraries/okhttp/additional_properties.mustache:39">
P1: When `serializationLibrary=jsonb` is used with `additionalProperties: true`, JSON-B cannot round-trip undeclared fields. Unknown response keys are ignored, while values added through `putAdditionalProperty` are not emitted under their original names; add a JSON-B serializer/deserializer that captures and flattens undeclared fields and excludes the backing bean property.</violation>
</file>
<file name="samples/client/others/java/okhttp-jackson-oneOf/git_push.sh">
<violation number="1" location="samples/client/others/java/okhttp-jackson-oneOf/git_push.sh:47">
P2: When the directory already has a non-`origin` remote, this check skips adding `origin`, but the script later pulls and pushes from `origin`. Check specifically for `origin` before deciding whether to add it.</violation>
<violation number="2" location="samples/client/others/java/okhttp-jackson-oneOf/git_push.sh:54">
P1: When `GIT_TOKEN` is set, this command stores the credential in plaintext in `.git/config` and exposes it through Git remote inspection. Use Git's credential helper or `GIT_ASKPASS` instead of embedding the token in the remote URL.</violation>
</file>
Note: This PR contains a large number of files. cubic only reviews up to 400 files per PR, so some files may not have been reviewed. cubic prioritizes the most important files to review.
Re-trigger cubic
| {{#isJackson}} | ||
| @JsonAnyGetter | ||
| {{/isJackson}} | ||
| public Map<String, Object> getAdditionalProperties() { |
There was a problem hiding this comment.
P1: When serializationLibrary=jsonb is used with additionalProperties: true, JSON-B cannot round-trip undeclared fields. Unknown response keys are ignored, while values added through putAdditionalProperty are not emitted under their original names; add a JSON-B serializer/deserializer that captures and flattens undeclared fields and excludes the backing bean property.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At modules/openapi-generator/src/main/resources/Java/libraries/okhttp/additional_properties.mustache, line 39:
<comment>When `serializationLibrary=jsonb` is used with `additionalProperties: true`, JSON-B cannot round-trip undeclared fields. Unknown response keys are ignored, while values added through `putAdditionalProperty` are not emitted under their original names; add a JSON-B serializer/deserializer that captures and flattens undeclared fields and excludes the backing bean property.</comment>
<file context>
@@ -0,0 +1,55 @@
+ {{#isJackson}}
+ @JsonAnyGetter
+ {{/isJackson}}
+ public Map<String, Object> getAdditionalProperties() {
+ return additionalProperties;
+ }
</file context>
| echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment." | ||
| git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git | ||
| else | ||
| git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git |
There was a problem hiding this comment.
P1: When GIT_TOKEN is set, this command stores the credential in plaintext in .git/config and exposes it through Git remote inspection. Use Git's credential helper or GIT_ASKPASS instead of embedding the token in the remote URL.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/others/java/okhttp-jackson-oneOf/git_push.sh, line 54:
<comment>When `GIT_TOKEN` is set, this command stores the credential in plaintext in `.git/config` and exposes it through Git remote inspection. Use Git's credential helper or `GIT_ASKPASS` instead of embedding the token in the remote URL.</comment>
<file context>
@@ -0,0 +1,63 @@
+ echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment."
+ git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git
+ else
+ git remote add origin https://${git_user_id}:"${GIT_TOKEN}"@${git_host}/${git_user_id}/${git_repo_id}.git
+ fi
+
</file context>
There was a problem hiding this comment.
All reported issues were addressed across 1 file (changes from recent commits).
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
…ON-B Adds a new "okhttp" library to the Java client generator, forked from "okhttp-gson" but decoupled from Gson: one template set emits clients for Gson (default), Jackson 2, Jackson 3 and JSON-B, on OkHttp 5.4.0, and honours the existing useJspecify option. Templates (Java/libraries/okhttp/): - JSON.mustache carries three parallel implementations - Gson (gson-fire + TypeAdapterFactory), Jackson (ObjectMapper, jacksonPackage-parameterised for 2.x/3.x) and JSON-B (Yasson + JsonbAdapters, with a GenericType<T> helper standing in for TypeToken). - ApiClient holds JSON as an instance so serializer config is per-client, passes request payloads to auth as byte[] rather than String, and signs AWS4 last so it sees the final query string. - auth/RetryingOAuth embeds its own TokenRequestBuilder and talks to OkHttp directly, dropping the Apache Oltu dependency that okhttp-gson needs. - api/pojo/oneof/anyof switch between TypeToken, TypeReference and JSON.GenericType, and use the shared nullableArgument partials plus the jSpecifyDatatype lambda already provided by AbstractJavaCodegen. Templates that only differed cosmetically from their root-level counterparts (Pair, StringUtil, ServerVariable, ServerConfiguration, maven.yml, travis, git_push.sh) are deliberately not forked - mustache resolution falls back to Java/ and the generated output is verified to include them. JavaClientCodegen: - registers the library, adds it to JSPECIFY_SUPPORTED_LIBRARIES and to the useJackson3 allowlist, and reuses the okhttp-gson supporting-file branch without forcing the serialization library. - resolves isGson/isJackson/isJsonb after the serialization switch, where getSerializationLibrary() is authoritative, instead of guessing earlier. - forces openApiNullable off for JSON-B, since jackson-databind-nullable is Jackson-only and the pom omits it there. - applies the x-enum-as-string discriminator rewrite for every serialization library (a narrowed discriminator otherwise generates a getter that cannot override the parent's String getter), while keeping the JsonNullable and JsonIgnore imports Jackson-only. - extends the useSingleRequestParameter and oneOf/anyOf ModelNull handling to the new library, both of which its templates support.
…library bin/configs/java-okhttp-user-defined-templates.yaml generated the okhttp-gson sample despite the neutral name; every other okhttp-gson config on master is already named java-okhttp-gson-*. Renaming it keeps the naming consistent and frees the java-okhttp-* prefix for the new okhttp library, without touching the generated sample.
27 configs covering the new library: the four serialization variants (Gson, Jackson 2, Jackson 3, JSON-B), JSpecify for each of Jackson 2/3 and JSON-B, oneOf/anyOf, nullable-required, AWS4 signing, dynamic operations, grouped parameters, parcelable models, streaming, swagger 1/2 annotations, OpenAPI 3.1, the echo API and user-defined templates. Fixes carried over from the prototype branch: - java-okhttp-echo-api.yaml had "library" commented out, so it silently generated with the default okhttp-gson library instead of okhttp. - java-okhttp-jackson-nullable-required.yaml never set serializationLibrary: jackson, making it a duplicate of the gson config. - java-okhttp.yaml had "useReflectionEqualsHashCode::" with a double colon, so the property never applied. - java-okhttp-jackson3-oneOf.yaml wrote to others/java/oneOf-okhttp-jackson3, breaking the okhttp-<serializer>-<feature> convention of its siblings, and java-okhttp-jackson3-jspecify.yaml reused the artifactId of the non-jspecify jackson3 config. - java-okhttp-jsonb-jspecify.yaml set useJackson3 alongside JSON-B. Every config names its serialization library explicitly, including the Gson ones: JavaClientCodegen infers its internal "jackson" flag from the absence of the property, so relying on the default would opt Gson output into Jackson-specific nullable handling. All 27 configs generate, and every generated sample compiles and passes its tests under Maven.
- pom.xml: java-client-okhttp profile builds the four serialization variants, java-client-okhttp-parcelable mirrors the okhttp-gson parcelable profile. - Workflows: each okhttp-gson entry gains its okhttp counterpart, in both the path triggers and the sample matrices. The petstore-server workflow gets the three samples that mirror okhttp-gson there; the plain client workflow gets the serialization, jspecify, oneOf, nullable-required, swagger, streaming, AWS4, grouped-parameter and parcelable samples; echo-api, gradle and sbt get their okhttp equivalents. - docs/generators/java.md: regenerated - the library table gains okhttp and useJspecify now lists it as supported.
Generated output for the 27 new bin/configs. Every sample compiles and passes its tests under Maven, across all four serialization variants.
The previously committed samples were generated with a jar that still contained seven okhttp templates from an earlier prototype build: Pair, StringUtil, ServerVariable, ServerConfiguration, maven.yml, travis and git_push.sh. Those templates are intentionally not part of this library - mustache resolution is supposed to fall back to the shared Java/ and _common/ templates - but stale target/classes output survived an incremental build and was shaded into the CLI jar, where library-local templates take precedence. Rebuilt with `mvn clean install` and regenerated. Only git_push.sh actually differed in the output; it now matches _common/git_push.sh.mustache and is byte-identical to the okhttp-gson sample, as are Pair, StringUtil, ServerVariable, ServerConfiguration, maven.yml and travis.
Correctness fixes to the forked templates: - GzipRequestInterceptor: restore the forceContentLength() wrapper dropped from okhttp-gson. Without it the gzip body reports contentLength() == -1, OkHttp falls back to Transfer-Encoding: chunked, and every compressed request fails against servers that reject chunked request bodies. The unused okio.Buffer import was the tell that the removal was accidental. - ProgressResponseBody: restore the memoized bufferedSource field. OkHttp calls source() again on close(), so without caching each call built a fresh ForwardingSource over a partially consumed stream, resetting the progress counter and risking double reads. - ProgressRequestBody: CountingSink no longer reports done, so a known-length body gets exactly one terminal callback instead of two (writeTo still emits the terminal event, which is what unknown-length bodies rely on). Dropped the unreachable private countingSink(Sink) helper. - AWS4Auth: sign x-amz-* headers. They were never added to the signable request, so SigV4 omitted them from SignedHeaders and AWS rejected the signature. Content-Type is deliberately left unsigned because OkHttp's BridgeInterceptor appends the multipart boundary after signing. This also wires up the two-pass auth ordering in ApiClient, which until now had no effect. - JSON: register RFC3339JavaTimeModule for Jackson 2. The codegen already emitted RFC3339InstantDeserializer and RFC3339JavaTimeModule, but nothing installed them, so the space-separated RFC3339 normalization never ran. Every other Jackson library registers it. Jackson 3 does not emit the classes and is left untouched. - additional_properties: replace Java `transient` with @JsonbTransient. The transient keyword was added by this fork and made Java serialization drop all undeclared properties when serializableModel=true; @JsonbTransient keeps JSON-B from emitting the backing map without that side effect. - ApiResponse: lowercase header keys in the caseInsensitiveResponseHeaders branch, matching okhttp-gson, native, jersey2 and jersey3. - pojo: stop emitting five Jackson imports that JavaClientCodegen already contributes via model.imports, which produced duplicate import lines. JsonTypeName is only contributed for Jackson 2, so it is still emitted from the template under useJackson3. Build files: - build.gradle: add the com.google.android:android compileOnly dependency under parcelableModel, mirroring the pom. Generated Parcelable models now compile with a plain Gradle build. - build.sbt: add the swagger-parser-v3 dependency under dynamicOperations and the jakarta.validation-api dependency under useBeanValidation, both of which the pom and Gradle builds already declared; gate jackson-annotations on Jackson 2 so Jackson 3 clients take the version aligned by jackson-databind. All 27 samples regenerated; each compiles and passes mvn test, and JavaClientCodegenTest still passes 288 tests. okhttp-gson output is unchanged.
…imports The previous fix emitted the JsonTypeName import from pojo.mustache whenever useJackson3 was set. AbstractJavaCodegen already adds that import for any model whose classname was sanitized, regardless of Jackson version, so models such as Apple, Banana and EnumTest ended up importing it twice. Contribute it from JavaClientCodegen.postProcessModelProperty instead. Because model.imports is a Set, the import is emitted exactly once whichever path asks for it, and the template no longer hardcodes it. Jackson-annotation duplicate imports across the okhttp samples drop from 19 to 1. The remaining one is JsonIgnore on a model that hits both the additionalProperties template path and the shared nullable addImports path, which appends to a List without de-duplicating - the same pre-existing mechanism that leaves five duplicate imports in okhttp-gson-nullable-required on master.
|
This PR is too broad in scope, it's difficult to review 400k lines of changes. |
|
Hi, @KannaKim. Yes, i know, that a bunch of changes, but its a completelly new okhttp generator supporting all three currently available JSON serialization libs as well as JSpecify. I don't want and i try hard, to don't change anything on the current okhttp-gson generator. Do you have some Idea for me how to organize this PR better for review? |
|
thanks for the contribution. please resolve the merge conflicts when you've time is it correct to say that you've been using this generator's output in production for a while and it's working as expected? i'll try to take a look this weekend. |
# Conflicts: # modules/openapi-generator/src/test/java/org/openapitools/codegen/java/JavaClientCodegenTest.java
…t separator helper Port two changes from master into the okhttp library: - generateInsecureTlsHook (OpenAPITools#24786): when set to false, the okhttp ApiClient omits the verifyingSsl field, setVerifyingSsl/isVerifyingSsl and the trust-all X509TrustManager/HostnameVerifier, for consumers whose static analysis flags that code. The verifying TLS setup moves into trustedTrustManagers()/trustedHostnameVerifier() so both template variants share it. - CollectionFormat helper (OpenAPITools#24781): deduplicate the collection-format delimiter lookup in parameterToPairs and collectionPathParameterToString into a collectionFormatSeparator method.
… changes Includes the churn from master (7.26.0-SNAPSHOT version bump, path backslash removal, inline-enum resolver fix), the new ApiClient helpers, and the RequiredAndNullable/FileContent files the jspecify samples were missing since the spec gained them in OpenAPITools#24711.
…earer-token NPE, modelCopy JsonTypeName - JSON-B has no @JsonAnyGetter/@JsonAnySetter, so models with 'additionalProperties: true' silently dropped undeclared fields in both directions. Generate a CustomJsonbSerializer/CustomJsonbDeserializer into each such pojo and register them in the Jsonb config built by JSON, mirroring what the Gson CustomTypeAdapterFactory does. Verified with a runtime round trip against the generated okhttp-jsonb client. - HttpBearerAuth.getBearerToken() threw NullPointerException before a token was configured, although applyToParams treats an unset supplier as valid unauthenticated state. Return null instead. - @JsonTypeName was emitted as "java" when pojo.mustache is rendered as a user-defined Model template (files config), because the bundle root's "name" key holds the generator name. Resolve the model name through the models/model scope, which works in both contexts. - ApiResponse: use conventional 'private final' modifier order and fix the "response bod" javadoc typo.
Correctness fixes across the okhttp templates and JavaClientCodegen, each verified by unit tests and runtime round trips against the regenerated clients: Gson: - oneOf/anyOf branches typed List<X>/Map<String,X> had no validation (bare matches++), and plain non-primitive branches (UUID, BigDecimal) none at all, while String/Boolean accepted any primitive - valid payloads failed with "N classes match result, expected 1". Branch validation now checks the concrete JSON type, ported from the okhttp-gson baseline. - Serializing a null additional property crashed on JsonNull.getAsJsonObject(); the baseline's isJsonNull branch is restored. - JSON.isInstanceOf(type, null) returned true, letting non-nullable oneOf/anyOf wrappers accept null; nullable wrappers handle null in setActualInstance, so null now matches nothing. - new JSON() unconditionally rebuilt the shared static Gson, discarding a setGson() customization on every ApiClient/RetryingOAuth construction; the constructor now keeps an existing instance. - CustomTypeAdapterFactory is no longer generated for parents with children (it was never registered, matching the baseline guard). Jackson: - oneOf deserializers double-counted duplicated data types (the one loop missing the x-duplicated-data-type guard), so such models could never deserialize; jsonb loops had the same gap. - errorObjectType's catch block gained the missing Jackson branch. - Jackson 3 now gets RFC3339JavaTimeModule/RFC3339InstantDeserializer like Jackson 2 (JavaClientCodegen whitelist + JSON.mustache). - openApiNullable is forced off for the whole library: the templates never emit JsonNullable, so the flag only produced dead equalsNullable/hashCodeNullable helpers and duplicate imports. JSON-B: - Discriminator hierarchies were silently unsupported (a Cat response typed Animal lost its fields). Yasson's native @JsonbTypeInfo cannot be used because the discriminator is also a bean property (key collision on both paths, "CHANGE naming conflict"), so hierarchy roots now generate TypeSelector-style custom (de)serializers that dispatch on the discriminator and bind subtypes through a second, polymorphism-free Jsonb instance (JSON.getPlainJsonb()). - The additionalProperties deserializer coerced explicit JSON null into the field default, skipped readOnly properties, and read the volatile Jsonb once per field; it now binds null, sets readOnly fields reflectively, validates openapiRequiredFields (previously dead for JSON-B), and captures the instance once per object. - anyOf toUrlQueryString iterated composedSchemas.oneOf and always returned null under supportUrlQuery. ApiClient: - executeStream() leaked the connection and discarded the error body on non-2xx responses; it now mirrors handleResponse(). - dynamicOperations sent null optional header/cookie params as empty strings; fillParametersFromOperation now skips null values. - The dead public updateParamsForAuth() (stale-URI semantics diverging from buildRequest's inline loop) is removed. - build.gradle no longer declares the mockito dependency pom dropped.
…oJson, free-form validation - oneOf wrapper models were missing the static fromJson(String)/toJson() helpers that okhttp-gson (and this library's anyOf wrappers and plain pojos) expose, an API-surface regression for migrating consumers. The Gson block from anyof_model.mustache is mirrored into oneof_model.mustache. - The per-type branch validation rejected free-form values: Object is a Java language-specific primitive, so an anyType branch or anyType container item fell into the primitive check and its "must be Number" fallback - a Map<String, Object> oneOf branch no longer accepted string/boolean/object values. anyType branches and items now skip validation entirely (any JSON value matches), like the okhttp-gson baseline.
Regenerated for the composed fromJson/toJson helpers and the anyType validation fix. Ports the 8 hand-maintained invoker tests from the okhttp-gson petstore sample (ApiClient, Client, Configuration, JSON, StringUtil, ApiKeyAuth, HttpBasicAuth, RetryingOAuth), adapted to this library: byte[] auth payloads, the Oltu-free RetryingOAuth is exercised against a local HttpServer instead of Mockito, JSONTest uses the composed-model fromJson/toJson helpers and the library's fail-fast discriminator messages, and equals() assertions avoid reflectionEquals (needs --add-opens on JDK 9+). Suite: 501 tests, 0 failures.
d7145f5 to
d289677
Compare
|
Hello @wing328, thank you for your time. Unfortunally it isn't in production now. I have only 4 local test projects against local httpbin running before push. JSON-B will be difficult, i don't have any projects runnig this in production :( I have merged master yesterday and resolved cubic concerns. |
…re spec, fix jsonb gaps
The three okhttp samples generated with a non-gson serializer took their spec from
3_0/java/native/petstore-...-with-http-signature.yaml, which declares an
`http_signature_test` scheme (type: http, scheme: signature). ApiClient.mustache only
registers basic/bearer/apiKey/oauth schemes, while api.mustache emits every scheme name
into localVarAuthNames, so PetApi.addPet, updatePet, findPetsByStatus and findPetsByTags
threw `RuntimeException: Authentication undefined: http_signature_test` on every generated
call surface (plain, WithHttpInfo and Async alike), with no way out: getAuthentications()
is an unmodifiable map, and the throw happens in buildRequest before any interceptor runs.
Point them at the spec java-okhttp.yaml already uses. That drops the unsatisfiable scheme
and, because all four serializers now generate from one spec, makes okhttp / okhttp-jackson
/ okhttp-jackson3 / okhttp-jsonb a like-for-like serializer matrix.
The richer spec exposed three jsonb defects, all fixed here:
* JSON.mustache registered no adapter for java.io.File, the mapping of `format: binary`.
JSON-B then treated File as a bean: serializing recursed through getAbsoluteFile()
("Recursive reference has been found in class java.io.File") and deserializing demanded
START_OBJECT where the schema carries a string. Adds a FileAdapter matching Jackson's
representation - getAbsolutePath() out, new File(String) in.
* oneof_model/anyof_model did not import JsonbTransient, which
additional_properties.mustache needs for its holder field. A pojo gets the import from
pojo.mustache; a composed model got none, so any composed schema with
additionalProperties failed to compile (40 errors).
* the composed deserializers called parser.getObject() unconditionally, which throws on
START_ARRAY, and routed every branch through ctx.deserialize, which Yasson cannot bind to
a root-level scalar. They now read a generic JsonValue and send structured values through
the context and scalars through the binding API.
Verified against a Prism mock per sample, driving every generated operation of all 42
okhttp-family samples (864 operations): all four serializers are now identical
operation-for-operation on the shared spec, all 14 okhttp/okhttp-gson pairs remain
identical, and no okhttp-gson template, sample or config is touched.
There was a problem hiding this comment.
10 issues found across 3000 files
Not reviewed (too large): samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/api/FakeApi.java (~3,457 lines), samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/api/FakeApi.java (~3,457 lines), samples/client/petstore/java/okhttp-jsonb/src/main/java/org/openapitools/client/api/FakeApi.java (~3,456 lines), samples/client/petstore/java/okhttp-dynamicOperations/src/main/java/org/openapitools/client/api/FakeApi.java (~2,248 lines), samples/client/petstore/java/okhttp-parcelableModel/src/main/java/org/openapitools/client/api/FakeApi.java (~2,191 lines) - if these are generated or fixture files, add them to ignored paths to exclude them from future reviews.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="modules/openapi-generator/src/main/resources/Java/libraries/okhttp/additional_properties.mustache">
<violation number="1" location="modules/openapi-generator/src/main/resources/Java/libraries/okhttp/additional_properties.mustache:11">
P2: For JSON-B models with children, `putAdditionalProperty` values are dropped during serialization. `@JsonbTransient` removes the holder from normal mapping, but the `hasChildren` serializer uses plain JSON-B without the additional-properties serializer; add equivalent flattening to that path or avoid applying this annotation for models handled there.</violation>
</file>
<file name="modules/openapi-generator/src/main/resources/Java/libraries/okhttp/auth/AWS4Auth.mustache">
<violation number="1" location="modules/openapi-generator/src/main/resources/Java/libraries/okhttp/auth/AWS4Auth.mustache:79">
P1: When `useGzipFeature=true`, `AWS4Auth` signs the original payload, but `GzipRequestInterceptor` compresses the body before it reaches AWS. The resulting SigV4 payload hash does not match the transmitted bytes, so signed requests are rejected; disable gzip for AWS4 requests or sign the final compressed body.</violation>
</file>
<file name="modules/openapi-generator/src/main/resources/Java/libraries/okhttp/ProgressResponseBody.mustache">
<violation number="1" location="modules/openapi-generator/src/main/resources/Java/libraries/okhttp/ProgressResponseBody.mustache:42">
P1: When a callback-tagged request receives a response without a body, `responseBody` is null and this wrapper dereferences it while the generated client consumes the response. Skip creating `ProgressResponseBody` for null response bodies in `getProgressInterceptor()` so no-content responses complete normally.</violation>
</file>
<file name="samples/client/echo_api/java/okhttp-user-defined-templates/src/main/java/org/openapitools/client/GzipRequestInterceptor.java">
<violation number="1" location="samples/client/echo_api/java/okhttp-user-defined-templates/src/main/java/org/openapitools/client/GzipRequestInterceptor.java:40">
P1: When AWS4 signing and `useGzipFeature` are enabled together, this interceptor changes the signed request body after `AWS4Auth` computes its signature, so AWS rejects the request. Skip compression for signed requests or apply signing after compression using the compressed payload hash.</violation>
</file>
<file name="samples/client/echo_api/java/okhttp-jackson-user-defined-templates/src/main/java/org/openapitools/client/model/Category.java">
<violation number="1" location="samples/client/echo_api/java/okhttp-jackson-user-defined-templates/src/main/java/org/openapitools/client/model/Category.java:19">
P3: The generated Category.java imports eight symbols that are never referenced in the file: com.fasterxml.jackson.annotation.JsonCreator, JsonValue, java.io.IOException, java.util.HashMap, List, Map, Set, and org.openapitools.client.JSON. These unused imports are emitted by the new okhttp pojo.mustache common import block (model.imports) for every model regardless of whether the model uses them, adding compiler warnings to every generated model. Restrict the template's import emission to symbols the model actually uses (e.g., only emit JSON when the model references the JSON helper, JsonValue/JsonCreator only when relevant), so the generated models compile warning-free.</violation>
</file>
<file name="samples/client/others/java/okhttp-jackson-oneOf/src/main/java/org/openapitools/client/ServerConfiguration.java">
<violation number="1" location="samples/client/others/java/okhttp-jackson-oneOf/src/main/java/org/openapitools/client/ServerConfiguration.java:55">
P2: When a server variable has no `enum` and a caller overrides it, `URL(Map<String, String>)` throws `NullPointerException` because `ServerVariable.enumValues` is nullable. Check for `null` before inspecting the allowed values so non-enumerated server variables can be substituted.</violation>
</file>
<file name="samples/client/echo_api/java/okhttp-jackson-user-defined-templates/src/main/java/org/openapitools/client/ServerConfiguration.java">
<violation number="1" location="samples/client/echo_api/java/okhttp-jackson-user-defined-templates/src/main/java/org/openapitools/client/ServerConfiguration.java:55">
P2: When a custom server variable has no enum values, `URL(Map)` throws `NullPointerException` while validating the supplied value. Guard the optional `enumValues` collection before calling `size()` or `contains()`.</violation>
</file>
<file name="samples/client/others/java/okhttp-jackson-oneOf/src/main/java/org/openapitools/client/GzipRequestInterceptor.java">
<violation number="1" location="samples/client/others/java/okhttp-jackson-oneOf/src/main/java/org/openapitools/client/GzipRequestInterceptor.java:52">
P2: When gzip is enabled for an asynchronous upload, this eager write makes `ProgressRequestBody` report completion before the network sends the request. It also retains every compressed file or streaming body in memory, which can cause large uploads to run out of memory; avoid precompressing in the interceptor or use a streaming/file-backed strategy that preserves progress reporting.</violation>
</file>
<file name="samples/client/echo_api/java/okhttp-jackson-user-defined-templates/src/main/java/org/openapitools/client/Configuration.java">
<violation number="1" location="samples/client/echo_api/java/okhttp-jackson-user-defined-templates/src/main/java/org/openapitools/client/Configuration.java:39">
P2: When multiple threads first call `getDefaultApiClient()`, `updateAndGet` can invoke `apiClientFactory` more than once and discard the extra clients. Protect lazy initialization with synchronization or another mechanism that guarantees the factory runs only once.</violation>
</file>
<file name="samples/client/others/java/okhttp-jackson-oneOf/src/main/java/org/openapitools/client/RFC3339JavaTimeModule.java">
<violation number="1" location="samples/client/others/java/okhttp-jackson-oneOf/src/main/java/org/openapitools/client/RFC3339JavaTimeModule.java:32">
P2: When Jackson registers this module, `super.setupModule(context)` publishes the deserializer map before these `addDeserializer` calls execute. Move the registrations before `super.setupModule(context)` or into the constructor, otherwise the RFC3339 deserializer is never used.</violation>
</file>
Note: This PR contains a large number of files. cubic selects up to 200 of the highest-priority eligible files for this review, so some files may not have been reviewed.
Re-trigger cubic
| ContentStreamProvider provider = new ContentStreamProvider() { | ||
| @Override | ||
| public InputStream newStream() { | ||
| return new ByteArrayInputStream(payload); |
There was a problem hiding this comment.
P1: When useGzipFeature=true, AWS4Auth signs the original payload, but GzipRequestInterceptor compresses the body before it reaches AWS. The resulting SigV4 payload hash does not match the transmitted bytes, so signed requests are rejected; disable gzip for AWS4 requests or sign the final compressed body.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At modules/openapi-generator/src/main/resources/Java/libraries/okhttp/auth/AWS4Auth.mustache, line 79:
<comment>When `useGzipFeature=true`, `AWS4Auth` signs the original payload, but `GzipRequestInterceptor` compresses the body before it reaches AWS. The resulting SigV4 payload hash does not match the transmitted bytes, so signed requests are rejected; disable gzip for AWS4 requests or sign the final compressed body.</comment>
<file context>
@@ -0,0 +1,114 @@
+ ContentStreamProvider provider = new ContentStreamProvider() {
+ @Override
+ public InputStream newStream() {
+ return new ByteArrayInputStream(payload);
+ }
+ };
</file context>
| // Memoized: OkHttp calls source() again on close(), and a second ForwardingSource would | ||
| // reset the progress counter and re-wrap an already partially consumed stream. | ||
| if (bufferedSource == null) { | ||
| bufferedSource = Okio.buffer(source(responseBody.source())); |
There was a problem hiding this comment.
P1: When a callback-tagged request receives a response without a body, responseBody is null and this wrapper dereferences it while the generated client consumes the response. Skip creating ProgressResponseBody for null response bodies in getProgressInterceptor() so no-content responses complete normally.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At modules/openapi-generator/src/main/resources/Java/libraries/okhttp/ProgressResponseBody.mustache, line 42:
<comment>When a callback-tagged request receives a response without a body, `responseBody` is null and this wrapper dereferences it while the generated client consumes the response. Skip creating `ProgressResponseBody` for null response bodies in `getProgressInterceptor()` so no-content responses complete normally.</comment>
<file context>
@@ -0,0 +1,61 @@
+ // Memoized: OkHttp calls source() again on close(), and a second ForwardingSource would
+ // reset the progress counter and re-wrap an already partially consumed stream.
+ if (bufferedSource == null) {
+ bufferedSource = Okio.buffer(source(responseBody.source()));
+ }
+ return bufferedSource;
</file context>
|
|
||
| Request compressedRequest = originalRequest.newBuilder() | ||
| .header("Content-Encoding", "gzip") | ||
| .method(originalRequest.method(), forceContentLength(gzip(body))) |
There was a problem hiding this comment.
P1: When AWS4 signing and useGzipFeature are enabled together, this interceptor changes the signed request body after AWS4Auth computes its signature, so AWS rejects the request. Skip compression for signed requests or apply signing after compression using the compressed payload hash.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/echo_api/java/okhttp-user-defined-templates/src/main/java/org/openapitools/client/GzipRequestInterceptor.java, line 40:
<comment>When AWS4 signing and `useGzipFeature` are enabled together, this interceptor changes the signed request body after `AWS4Auth` computes its signature, so AWS rejects the request. Skip compression for signed requests or apply signing after compression using the compressed payload hash.</comment>
<file context>
@@ -0,0 +1,91 @@
+
+ Request compressedRequest = originalRequest.newBuilder()
+ .header("Content-Encoding", "gzip")
+ .method(originalRequest.method(), forceContentLength(gzip(body)))
+ .build();
+ return chain.proceed(compressedRequest);
</file context>
| super.setupModule(context); | ||
|
|
||
| addDeserializer(Instant.class, RFC3339InstantDeserializer.INSTANT); | ||
| addDeserializer(OffsetDateTime.class, RFC3339InstantDeserializer.OFFSET_DATE_TIME); | ||
| addDeserializer(ZonedDateTime.class, RFC3339InstantDeserializer.ZONED_DATE_TIME); |
There was a problem hiding this comment.
P2: When Jackson registers this module, super.setupModule(context) publishes the deserializer map before these addDeserializer calls execute. Move the registrations before super.setupModule(context) or into the constructor, otherwise the RFC3339 deserializer is never used.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/others/java/okhttp-jackson-oneOf/src/main/java/org/openapitools/client/RFC3339JavaTimeModule.java, line 32:
<comment>When Jackson registers this module, `super.setupModule(context)` publishes the deserializer map before these `addDeserializer` calls execute. Move the registrations before `super.setupModule(context)` or into the constructor, otherwise the RFC3339 deserializer is never used.</comment>
<file context>
@@ -0,0 +1,39 @@
+
+ @Override
+ public void setupModule(SetupContext context) {
+ super.setupModule(context);
+
+ addDeserializer(Instant.class, RFC3339InstantDeserializer.INSTANT);
</file context>
| super.setupModule(context); | |
| addDeserializer(Instant.class, RFC3339InstantDeserializer.INSTANT); | |
| addDeserializer(OffsetDateTime.class, RFC3339InstantDeserializer.OFFSET_DATE_TIME); | |
| addDeserializer(ZonedDateTime.class, RFC3339InstantDeserializer.ZONED_DATE_TIME); | |
| addDeserializer(Instant.class, RFC3339InstantDeserializer.INSTANT); | |
| addDeserializer(OffsetDateTime.class, RFC3339InstantDeserializer.OFFSET_DATE_TIME); | |
| addDeserializer(ZonedDateTime.class, RFC3339InstantDeserializer.ZONED_DATE_TIME); | |
| super.setupModule(context); |
| @@ -0,0 +1,156 @@ | |||
| /* | |||
There was a problem hiding this comment.
P3: The generated Category.java imports eight symbols that are never referenced in the file: com.fasterxml.jackson.annotation.JsonCreator, JsonValue, java.io.IOException, java.util.HashMap, List, Map, Set, and org.openapitools.client.JSON. These unused imports are emitted by the new okhttp pojo.mustache common import block (model.imports) for every model regardless of whether the model uses them, adding compiler warnings to every generated model. Restrict the template's import emission to symbols the model actually uses (e.g., only emit JSON when the model references the JSON helper, JsonValue/JsonCreator only when relevant), so the generated models compile warning-free.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/echo_api/java/okhttp-jackson-user-defined-templates/src/main/java/org/openapitools/client/model/Category.java, line 19:
<comment>The generated Category.java imports eight symbols that are never referenced in the file: com.fasterxml.jackson.annotation.JsonCreator, JsonValue, java.io.IOException, java.util.HashMap, List, Map, Set, and org.openapitools.client.JSON. These unused imports are emitted by the new okhttp pojo.mustache common import block (model.imports) for every model regardless of whether the model uses them, adding compiler warnings to every generated model. Restrict the template's import emission to symbols the model actually uses (e.g., only emit JSON when the model references the JSON helper, JsonValue/JsonCreator only when relevant), so the generated models compile warning-free.</comment>
<file context>
@@ -0,0 +1,156 @@
+import java.util.Objects;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonTypeName;
+import com.fasterxml.jackson.annotation.JsonValue;
</file context>
…ibrary Address the actionable findings from the 2026-09-07 review run, all confined to the okhttp library templates: - GzipRequestInterceptor: skip compression for AWS SigV4-signed requests. AWS4Auth hashes the uncompressed payload and stamps the Authorization header before the Request exists, so gzipping afterwards made the transmitted bytes disagree with the signature and AWS rejected the call. Guarded by withAWSV4Signature, so non-AWS clients are unchanged. - GzipRequestInterceptor: keep upload progress truthful. Buffering to publish a Content-Length drained the enclosing ProgressRequestBody, firing every callback (terminal one included, with uncompressed totals) before a byte reached the socket. Compress the wrapped delegate instead and re-wrap the compressed buffer with the same callback, and replay it in segments so the upload is reported as it happens. The in-memory buffering itself is inherent to publishing a compressed length and is now documented. - pojo.mustache: flatten additionalProperties for JSON-B models with children. @JsonbTransient hides the holder and the flattening serializer was registered only for non-hasChildren models, so an instance whose runtime type is the discriminated root silently lost its extra properties. - build.gradle.mustache: select Java 17 when useJackson3 is set, as the POM already does; nothing derives the internal java17 property from it, so Gradle clients targeted Java 8 with a Jackson 3 dependency. - build.sbt.mustache: add the Parcelable and Bean Validation provider dependencies that the POM and Gradle builds already declare. - ProgressRequestBody: delegate isOneShot()/isDuplex() so a wrapped one-shot or duplex body keeps its contract. - ApiResponse.mustache: lower-case response header names with Locale.ROOT so a Turkish/Azeri default locale cannot corrupt them. - api_doc.mustache: import modelPackage rather than a non-existent "<invokerPackage>.models" package, so the doc examples compile. Samples regenerated for all 27 okhttp configs. okhttp-gson stays byte identical to master.
There was a problem hiding this comment.
1 existing issue remains and no new issues found across 171 files (changes from recent commits).
Requires human review: Auto-approval blocked because this review re-detected 1 unresolved issue already reported by Cubic.
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
Jackson 3 requires Java 17, so the generated POM for a useJackson3 client compiles with source/target 17. The three okhttp jackson3 samples were wired into the JDK 11 sample workflow when okhttp CI coverage was added, and their "Build with Maven" step has failed there ever since: a JDK 11 javac cannot honour target 17. Move them to the JDK 17 workflow, where every other library already keeps its jackson3 sample (native-jackson3, apache-httpclient-jackson3, jersey3-jackson3): - samples/client/petstore/java/okhttp-jackson3 - samples/client/petstore/java/okhttp-jackson3-jspecify - samples/client/others/java/okhttp-jackson3-oneOf The generated POMs are unchanged; only the CI wiring was wrong.
There was a problem hiding this comment.
All reported issues were addressed across 173 files (changes from recent commits).
Requires human review: Auto-approval blocked because this review re-detected 1 unresolved issue already reported by Cubic.
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
(ApiClient.java:1022-1032) — the real one. sink.writeAll(response.body().source()) never closes the body's source; on success the connection is only released because the stream happens to be read to exhaustion, but if an IOException hits mid-copy, both the BufferedSink (file descriptor) and the response body (pooled connection) leak. Needs try-with-resources on both
Close responses explicitly on failures
There was a problem hiding this comment.
All reported issues were addressed across 1 file (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
…ependencies - Updated template dependencies to select Jakarta EL or Glassfish EL dynamically based on useJakartaEe (5.x for Jakarta EE and 3.x for javax). - Adjusted hibernate-validator versions for Jakarta vs. javax compatibility. - Flattened additionalProperties handling for JSON-B models with inheritance. - Added branch validation in composed models to prevent mismatched deserialization. - Ensured correct library dependencies in all build scripts (Maven, Gradle, SBT) while maintaining compatibility configurations.
There was a problem hiding this comment.
All reported issues were addressed across 3000 files
Not reviewed (too large): samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/api/FakeApi.java (~3,457 lines), samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/api/FakeApi.java (~3,457 lines), samples/client/petstore/java/okhttp-jsonb/src/main/java/org/openapitools/client/api/FakeApi.java (~3,456 lines), samples/client/petstore/java/okhttp-dynamicOperations/src/main/java/org/openapitools/client/api/FakeApi.java (~2,248 lines), samples/client/petstore/java/okhttp-parcelableModel/src/main/java/org/openapitools/client/api/FakeApi.java (~2,191 lines) - if these are generated or fixture files, add them to ignored paths to exclude them from future reviews.
Note: This PR contains a large number of files. cubic selects up to 200 of the highest-priority eligible files for this review, so some files may not have been reviewed.
Re-trigger cubic
…ve required-field validation - Delegate model symbol imports to JavaClientCodegen to eliminate duplicate import lines in templates. - Introduce `uncheckedJsonb` instance to bypass additional properties enforcement during deserialization. - Register custom JSON-B deserializers for models with required properties for stricter validation. - Synchronize Java version source/target settings across build tools for `useJackson3`.
There was a problem hiding this comment.
1 issue found across 21 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="modules/openapi-generator/src/main/resources/Java/libraries/okhttp/JSON.mustache">
<violation number="1" location="modules/openapi-generator/src/main/resources/Java/libraries/okhttp/JSON.mustache:733">
P1: When a discriminator root declares required properties, JSON-B does not enforce them because this block excludes every `hasChildren` model. Validate required fields in the discriminator deserializer before subtype dispatch, rather than omitting these roots from required validation.</violation>
</file>
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
| {{^vendorExtensions.x-is-one-of-interface}} | ||
| {{^oneOf}} | ||
| {{^anyOf}} | ||
| {{^hasChildren}} |
There was a problem hiding this comment.
P1: When a discriminator root declares required properties, JSON-B does not enforce them because this block excludes every hasChildren model. Validate required fields in the discriminator deserializer before subtype dispatch, rather than omitting these roots from required validation.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At modules/openapi-generator/src/main/resources/Java/libraries/okhttp/JSON.mustache, line 733:
<comment>When a discriminator root declares required properties, JSON-B does not enforce them because this block excludes every `hasChildren` model. Validate required fields in the discriminator deserializer before subtype dispatch, rather than omitting these roots from required validation.</comment>
<file context>
@@ -703,6 +716,33 @@ public class JSON {
+ {{^vendorExtensions.x-is-one-of-interface}}
+ {{^oneOf}}
+ {{^anyOf}}
+ {{^hasChildren}}
+ {{^isAdditionalPropertiesTrue}}
+ {{#hasRequired}}
</file context>
82f8bfe edited build.sbt.mustache, api_doc.mustache, JavaClientCodegen.java and the two java-okhttp-*-user-defined-templates.yaml configs, but regenerated only the four JSON-B samples. Run the remaining 27 java-okhttp* configs so the samples match the templates again. Generated output only, no template change: - model imports deduplicated (JavaClientCodegen now contributes them) - build.sbt pins -source/-target to the Maven and Gradle bytecode level - the two user-defined-templates samples gain their README and api docs
1. A model that forbids additional properties never rejected an UNDECLARED
field. Yasson binds such a model by plain bean mapping, which drops an
unknown key silently, so a oneOf branch accepted a payload belonging to a
sibling branch: {"lengthCm":10,"mealy":true} bound BananaReq and discarded
`mealy`. Mirror the Gson type adapter's validateJsonElement and reject any
key outside openapiFields. The guard moves from hasRequired to "declares a
property", because a branch with no required field needs the check just as
much; a model with no declared property stays excluded so that an empty
openapiFields cannot reject every key.
2. Required-field checks did not survive nesting. `uncheckedJsonb` was built
before EVERY required-field deserializer, so a checked model binding through
it disabled the checks of all of its nested models too. A recursion guard
cannot fix that: a re-entrant whole-object bind has to land on some instance
that carries no checker, which is the defect itself. Drop uncheckedJsonb and
bind property by property through the fully configured instance instead -
the shape the additional-properties deserializer already used. That cannot
re-enter itself, since the target type is the property's and not the class'.
3. The root of a discriminated hierarchy enforced no required property, because
the registration block excludes every hasChildren model. Validate in the
discriminator deserializer, both for the unmapped-root fallback and for a
mapped subtype that has children of its own. A leaf subtype is covered by
registering the required-field deserializers BEFORE plainJsonb is built:
that instance now carries everything except the polymorphism roots, so a
subtype bound through it validates itself.
4. setJsonb()/setSerializer() called before the first JSON was constructed left
plainJsonb null, and every generated deserializer then failed with an NPE.
Build the companion instance first, and check it in the constructor too.
There was a problem hiding this comment.
8 issues found across 3000 files
Not reviewed (too large): samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/api/FakeApi.java (~3,457 lines), samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/api/FakeApi.java (~3,457 lines), samples/client/petstore/java/okhttp-jsonb/src/main/java/org/openapitools/client/api/FakeApi.java (~3,456 lines), samples/client/petstore/java/okhttp-dynamicOperations/src/main/java/org/openapitools/client/api/FakeApi.java (~2,248 lines), samples/client/petstore/java/okhttp-parcelableModel/src/main/java/org/openapitools/client/api/FakeApi.java (~2,191 lines) - if these are generated or fixture files, add them to ignored paths to exclude them from future reviews.
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="modules/openapi-generator/src/main/resources/Java/libraries/okhttp/build.sbt.mustache">
<violation number="1" location="modules/openapi-generator/src/main/resources/Java/libraries/okhttp/build.sbt.mustache:58">
P2: When `withXml=true` on the supported Java 11 or 17 targets, generated models cannot compile because JAXB was removed from the JDK and this build declares no JAXB API. Add a `jakarta.xml.bind-api` dependency for Jakarta mode and `javax.xml.bind:jaxb-api` for the non-Jakarta mode.</violation>
<violation number="2" location="modules/openapi-generator/src/main/resources/Java/libraries/okhttp/build.sbt.mustache:58">
P2: On Java 11+, SBT-generated clients fail to compile because the generated sources reference `javax.annotation.Generated`, but this build declares only `jakarta.annotation-api`. Add the matching `javax.annotation` API dependency or generate the corresponding Jakarta annotation imports.</violation>
<violation number="3" location="modules/openapi-generator/src/main/resources/Java/libraries/okhttp/build.sbt.mustache:69">
P1: When `useBeanValidation=true` and `useJakartaEe=false`, generated models import `javax.validation`, but this build declares the Jakarta validation artifact. Use `javax.validation:validation-api:2.0.1` for the non-Jakarta branch and retain the current Jakarta coordinate only for `useJakartaEe=true`.</violation>
</file>
<file name="samples/client/echo_api/java/okhttp-jackson-user-defined-templates/src/main/java/org/openapitools/client/model/TestQueryStyleFormExplodeTrueArrayStringQueryObjectParameter.java">
<violation number="1" location="samples/client/echo_api/java/okhttp-jackson-user-defined-templates/src/main/java/org/openapitools/client/model/TestQueryStyleFormExplodeTrueArrayStringQueryObjectParameter.java:115">
P3: In the Jackson-generated models, `openapiFields`/`openapiRequiredFields` are declared and populated but never read: the okhttp-gson template consumes them in `validateJsonElement`, which the Jackson port omits. The same template should not emit these fields (nor the unused `Map`, `JsonCreator`, `JsonValue` imports) for the Jackson/JSON-B serializers, otherwise every generated model carries dead code.</violation>
</file>
<file name="samples/client/echo_api/java/okhttp-jackson-user-defined-templates/modelCopy/Query.java">
<violation number="1" location="samples/client/echo_api/java/okhttp-jackson-user-defined-templates/modelCopy/Query.java:1">
P2: The generated model won't compile: it calls Objects.hash() and uses @JsonTypeName("Query") but never imports java.util.Objects or com.fasterxml.jackson.annotation.JsonTypeName. Because this user-defined-template config maps only pojo.mustache as the Model template, the imports normally added by model.mustache (the unconditional java.util.Objects and the {{#jackson}} JsonPropertyOrder/JsonTypeName pair) are not emitted. Add both missing imports so the generated sample compiles, or include the model.mustache import header in the user-defined template generation.</violation>
</file>
<file name="samples/client/echo_api/java/okhttp-jackson-user-defined-templates/modelCopy/StringEnumRef.java">
<violation number="1" location="samples/client/echo_api/java/okhttp-jackson-user-defined-templates/modelCopy/StringEnumRef.java:11">
P2: The modelCopy output for this model is an empty class: it loses the enum constants (SUCCESS/FAILURE/UNCLASSIFIED), the value field, and all serialization helpers that the src/main model version and the gson modelCopy version retain. Every modelCopy file renders as an empty property-less stub, so the user-defined-template modelCopy output is broken, not just this one. Regenerate/fix the pojo template so modelCopy output matches the compiled model content.</violation>
</file>
<file name="samples/client/echo_api/java/okhttp-jackson-user-defined-templates/modelCopy/Tag.java">
<violation number="1" location="samples/client/echo_api/java/okhttp-jackson-user-defined-templates/modelCopy/Tag.java:44">
P3: toIndentedString(Object) is private and never called: toString() only appends "}" without invoking it. Remove the dead method, or have toString() use it, to match the standard pojo template where the field lines are emitted.</violation>
</file>
<file name="samples/client/echo_api/java/okhttp-user-defined-templates/.openapi-generator/FILES">
<violation number="1" location="samples/client/echo_api/java/okhttp-user-defined-templates/.openapi-generator/FILES:8">
P2: The sample commits `info.md` and the six `docs/*ApiDocumentation.md` files, but none are listed in this FILES manifest and the new config no longer generates them (it produces README.md and `docs/*Api.md` instead; `info.md`/`*ApiDocumentation.md` come from the old config's `files:` entries). Files absent from FILES are never removed or rewritten by the generator, so the sample will keep these stale leftovers and stay out of sync with `bin/generate-samples.sh` output. Delete these seven orphaned files.</violation>
</file>
Note: This PR contains a large number of files. cubic selects up to 200 of the highest-priority eligible files for this review, so some files may not have been reviewed.
Re-trigger cubic
| "com.google.android" % "android" % "4.1.1.4" % "provided", | ||
| {{/parcelableModel}} | ||
| {{#useBeanValidation}} | ||
| "jakarta.validation" % "jakarta.validation-api" % "{{#useJakartaEe}}3.0.2{{/useJakartaEe}}{{^useJakartaEe}}2.0.2{{/useJakartaEe}}", |
There was a problem hiding this comment.
P1: When useBeanValidation=true and useJakartaEe=false, generated models import javax.validation, but this build declares the Jakarta validation artifact. Use javax.validation:validation-api:2.0.1 for the non-Jakarta branch and retain the current Jakarta coordinate only for useJakartaEe=true.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At modules/openapi-generator/src/main/resources/Java/libraries/okhttp/build.sbt.mustache, line 69:
<comment>When `useBeanValidation=true` and `useJakartaEe=false`, generated models import `javax.validation`, but this build declares the Jakarta validation artifact. Use `javax.validation:validation-api:2.0.1` for the non-Jakarta branch and retain the current Jakarta coordinate only for `useJakartaEe=true`.</comment>
<file context>
@@ -0,0 +1,85 @@
+ "com.google.android" % "android" % "4.1.1.4" % "provided",
+ {{/parcelableModel}}
+ {{#useBeanValidation}}
+ "jakarta.validation" % "jakarta.validation-api" % "{{#useJakartaEe}}3.0.2{{/useJakartaEe}}{{^useJakartaEe}}2.0.2{{/useJakartaEe}}",
+ {{/useBeanValidation}}
+ {{#performBeanValidation}}
</file context>
| "jakarta.validation" % "jakarta.validation-api" % "{{#useJakartaEe}}3.0.2{{/useJakartaEe}}{{^useJakartaEe}}2.0.2{{/useJakartaEe}}", | |
| {{#useJakartaEe}} | |
| "jakarta.validation" % "jakarta.validation-api" % "3.0.2", | |
| {{/useJakartaEe}} | |
| {{^useJakartaEe}} | |
| "javax.validation" % "validation-api" % "2.0.1", | |
| {{/useJakartaEe}} |
| {{#joda}} | ||
| "joda-time" % "joda-time" % "2.12.0", | ||
| {{/joda}} | ||
| "jakarta.annotation" % "jakarta.annotation-api" % "{{#useJakartaEe}}2.1.1{{/useJakartaEe}}{{^useJakartaEe}}1.3.5{{/useJakartaEe}}", |
There was a problem hiding this comment.
P2: When withXml=true on the supported Java 11 or 17 targets, generated models cannot compile because JAXB was removed from the JDK and this build declares no JAXB API. Add a jakarta.xml.bind-api dependency for Jakarta mode and javax.xml.bind:jaxb-api for the non-Jakarta mode.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At modules/openapi-generator/src/main/resources/Java/libraries/okhttp/build.sbt.mustache, line 58:
<comment>When `withXml=true` on the supported Java 11 or 17 targets, generated models cannot compile because JAXB was removed from the JDK and this build declares no JAXB API. Add a `jakarta.xml.bind-api` dependency for Jakarta mode and `javax.xml.bind:jaxb-api` for the non-Jakarta mode.</comment>
<file context>
@@ -0,0 +1,85 @@
+ {{#joda}}
+ "joda-time" % "joda-time" % "2.12.0",
+ {{/joda}}
+ "jakarta.annotation" % "jakarta.annotation-api" % "{{#useJakartaEe}}2.1.1{{/useJakartaEe}}{{^useJakartaEe}}1.3.5{{/useJakartaEe}}",
+ {{#withAWSV4Signature}}
+ "software.amazon.awssdk" % "auth" % "2.20.157",
</file context>
| "jakarta.annotation" % "jakarta.annotation-api" % "{{#useJakartaEe}}2.1.1{{/useJakartaEe}}{{^useJakartaEe}}1.3.5{{/useJakartaEe}}", | |
| "jakarta.annotation" % "jakarta.annotation-api" % "{{#useJakartaEe}}2.1.1{{/useJakartaEe}}{{^useJakartaEe}}1.3.5{{/useJakartaEe}}", | |
| {{#withXml}} | |
| {{#useJakartaEe}} | |
| "jakarta.xml.bind" % "jakarta.xml.bind-api" % "4.0.2", | |
| {{/useJakartaEe}} | |
| {{^useJakartaEe}} | |
| "javax.xml.bind" % "jaxb-api" % "2.3.1", | |
| {{/useJakartaEe}} | |
| {{/withXml}} |
| @@ -0,0 +1,61 @@ | |||
| import com.fasterxml.jackson.annotation.JsonPropertyOrder; | |||
There was a problem hiding this comment.
P2: The generated model won't compile: it calls Objects.hash() and uses @JsonTypeName("Query") but never imports java.util.Objects or com.fasterxml.jackson.annotation.JsonTypeName. Because this user-defined-template config maps only pojo.mustache as the Model template, the imports normally added by model.mustache (the unconditional java.util.Objects and the {{#jackson}} JsonPropertyOrder/JsonTypeName pair) are not emitted. Add both missing imports so the generated sample compiles, or include the model.mustache import header in the user-defined template generation.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/echo_api/java/okhttp-jackson-user-defined-templates/modelCopy/Query.java, line 1:
<comment>The generated model won't compile: it calls Objects.hash() and uses @JsonTypeName("Query") but never imports java.util.Objects or com.fasterxml.jackson.annotation.JsonTypeName. Because this user-defined-template config maps only pojo.mustache as the Model template, the imports normally added by model.mustache (the unconditional java.util.Objects and the {{#jackson}} JsonPropertyOrder/JsonTypeName pair) are not emitted. Add both missing imports so the generated sample compiles, or include the model.mustache import header in the user-defined template generation.</comment>
<file context>
@@ -0,0 +1,61 @@
+import com.fasterxml.jackson.annotation.JsonPropertyOrder;
+import java.util.HashSet;
+
</file context>
| @@ -0,0 +1,61 @@ | |||
| import com.fasterxml.jackson.annotation.JsonPropertyOrder; | |||
There was a problem hiding this comment.
P2: The modelCopy output for this model is an empty class: it loses the enum constants (SUCCESS/FAILURE/UNCLASSIFIED), the value field, and all serialization helpers that the src/main model version and the gson modelCopy version retain. Every modelCopy file renders as an empty property-less stub, so the user-defined-template modelCopy output is broken, not just this one. Regenerate/fix the pojo template so modelCopy output matches the compiled model content.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/echo_api/java/okhttp-jackson-user-defined-templates/modelCopy/StringEnumRef.java, line 11:
<comment>The modelCopy output for this model is an empty class: it loses the enum constants (SUCCESS/FAILURE/UNCLASSIFIED), the value field, and all serialization helpers that the src/main model version and the gson modelCopy version retain. Every modelCopy file renders as an empty property-less stub, so the user-defined-template modelCopy output is broken, not just this one. Regenerate/fix the pojo template so modelCopy output matches the compiled model content.</comment>
<file context>
@@ -0,0 +1,61 @@
+@JsonPropertyOrder({
+})
+@JsonTypeName("StringEnumRef")
+public class StringEnumRef {
+ public StringEnumRef() {
+ }
</file context>
| @@ -0,0 +1,82 @@ | |||
| .github/workflows/maven.yml | |||
There was a problem hiding this comment.
P2: The sample commits info.md and the six docs/*ApiDocumentation.md files, but none are listed in this FILES manifest and the new config no longer generates them (it produces README.md and docs/*Api.md instead; info.md/*ApiDocumentation.md come from the old config's files: entries). Files absent from FILES are never removed or rewritten by the generator, so the sample will keep these stale leftovers and stay out of sync with bin/generate-samples.sh output. Delete these seven orphaned files.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/echo_api/java/okhttp-user-defined-templates/.openapi-generator/FILES, line 8:
<comment>The sample commits `info.md` and the six `docs/*ApiDocumentation.md` files, but none are listed in this FILES manifest and the new config no longer generates them (it produces README.md and `docs/*Api.md` instead; `info.md`/`*ApiDocumentation.md` come from the old config's `files:` entries). Files absent from FILES are never removed or rewritten by the generator, so the sample will keep these stale leftovers and stay out of sync with `bin/generate-samples.sh` output. Delete these seven orphaned files.</comment>
<file context>
@@ -0,0 +1,82 @@
+api/openapi.yaml
+build.gradle
+build.sbt
+docs/AuthApi.md
+docs/Bird.md
+docs/BodyApi.md
</file context>
| {{#joda}} | ||
| "joda-time" % "joda-time" % "2.12.0", | ||
| {{/joda}} | ||
| "jakarta.annotation" % "jakarta.annotation-api" % "{{#useJakartaEe}}2.1.1{{/useJakartaEe}}{{^useJakartaEe}}1.3.5{{/useJakartaEe}}", |
There was a problem hiding this comment.
P2: On Java 11+, SBT-generated clients fail to compile because the generated sources reference javax.annotation.Generated, but this build declares only jakarta.annotation-api. Add the matching javax.annotation API dependency or generate the corresponding Jakarta annotation imports.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At modules/openapi-generator/src/main/resources/Java/libraries/okhttp/build.sbt.mustache, line 58:
<comment>On Java 11+, SBT-generated clients fail to compile because the generated sources reference `javax.annotation.Generated`, but this build declares only `jakarta.annotation-api`. Add the matching `javax.annotation` API dependency or generate the corresponding Jakarta annotation imports.</comment>
<file context>
@@ -0,0 +1,85 @@
+ {{#joda}}
+ "joda-time" % "joda-time" % "2.12.0",
+ {{/joda}}
+ "jakarta.annotation" % "jakarta.annotation-api" % "{{#useJakartaEe}}2.1.1{{/useJakartaEe}}{{^useJakartaEe}}1.3.5{{/useJakartaEe}}",
+ {{#withAWSV4Signature}}
+ "software.amazon.awssdk" % "auth" % "2.20.157",
</file context>
| } | ||
|
|
||
|
|
||
| public static HashSet<String> openapiFields; |
There was a problem hiding this comment.
P3: In the Jackson-generated models, openapiFields/openapiRequiredFields are declared and populated but never read: the okhttp-gson template consumes them in validateJsonElement, which the Jackson port omits. The same template should not emit these fields (nor the unused Map, JsonCreator, JsonValue imports) for the Jackson/JSON-B serializers, otherwise every generated model carries dead code.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/echo_api/java/okhttp-jackson-user-defined-templates/src/main/java/org/openapitools/client/model/TestQueryStyleFormExplodeTrueArrayStringQueryObjectParameter.java, line 115:
<comment>In the Jackson-generated models, `openapiFields`/`openapiRequiredFields` are declared and populated but never read: the okhttp-gson template consumes them in `validateJsonElement`, which the Jackson port omits. The same template should not emit these fields (nor the unused `Map`, `JsonCreator`, `JsonValue` imports) for the Jackson/JSON-B serializers, otherwise every generated model carries dead code.</comment>
<file context>
@@ -0,0 +1,128 @@
+ }
+
+
+ public static HashSet<String> openapiFields;
+ public static HashSet<String> openapiRequiredFields;
+
</file context>
| * Convert the given object to string with each line indented by 4 spaces | ||
| * (except the first line). | ||
| */ | ||
| private String toIndentedString(Object o) { |
There was a problem hiding this comment.
P3: toIndentedString(Object) is private and never called: toString() only appends "}" without invoking it. Remove the dead method, or have toString() use it, to match the standard pojo template where the field lines are emitted.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/echo_api/java/okhttp-jackson-user-defined-templates/modelCopy/Tag.java, line 44:
<comment>toIndentedString(Object) is private and never called: toString() only appends "}" without invoking it. Remove the dead method, or have toString() use it, to match the standard pojo template where the field lines are emitted.</comment>
<file context>
@@ -0,0 +1,61 @@
+ * Convert the given object to string with each line indented by 4 spaces
+ * (except the first line).
+ */
+ private String toIndentedString(Object o) {
+ return o == null ? "null" : o.toString().replace("\n", "\n ");
+ }
</file context>
…builds JSON.mustache imports com.fasterxml.jackson.datatype.joda.JodaModule (or tools.jackson.datatype.joda.JodaModule under Jackson 3) and registers it on the mapper whenever dateLibrary=joda is combined with a Jackson serializationLibrary, but none of the three generated build files declared that artifact -- they carried only joda-time. A client generated that way failed to compile with "package com.fasterxml.jackson.datatype.joda does not exist". The omission was inherited from okhttp-gson, whose JSON.mustache is Gson-only and handles Joda with hand-written DateTimeTypeAdapters, so joda-time alone was correct there. It stops being correct once the same build files serve the Jackson serializers. jackson-datatype-joda is published for both generations at the versions this library already pins -- com.fasterxml.jackson.datatype:2.22.1 and tools.jackson.datatype:3.2.1 -- so the dependency follows the jackson-core and jackson-databind pattern and needs no useJackson3 gate, unlike jackson-datatype-jsr310. No sample sets dateLibrary: joda, so this path has no CI coverage; verified by generating a client for each Jackson generation and compiling both.
82f8bfe dropped the README.mustache -> info.md and api_doc.mustache -> Documentation.md filename mappings from the two user-defined-templates configs, and 49d04be regenerated the samples. That run added the new README.md and docs/*Api.md outputs but left the old ones in place, so both spellings have been sitting side by side since. The generator only rewrites or removes files listed in .openapi-generator/FILES, and these seven per sample are not listed, so they would have survived every future regeneration. The manifests themselves are already correct and need no change. Removes info.md and docs/{Auth,Body,Form,Header,Path,Query}ApiDocumentation.md from both okhttp-user-defined-templates and okhttp-jackson-user-defined-templates. Nothing references them: they are not in either FILES manifest, not linked from README.md, and not part of the pom or gradle build.
Both live in the discriminator-root serializer that pojo.mustache generates
for a hasChildren model with additionalProperties: true.
A nested value lost its additional properties when its runtime type was a
hierarchy root. JSON registers a CustomJsonbSerializer for every
non-hasChildren model before building plainJsonb and adds the roots only
afterwards, so a nested Cat or Dog kept its flattening but a nested Animal or
GrandparentAnimal fell through to plain bean mapping, where the @JsonbTransient
holder is dropped. Additional-property values now render through a separate
toNestedJsonValue() on the configured Jsonb; the outer value stays on
plainJsonb, which is what keeps the serializer from re-entering itself. This
follows the delegation deserializeBranch already uses.
An additional property could also take a subtype's declared name. The guard
tested the root's openapiFields and then whether the key was already in the
serialized output, but a subtype serializer omits a declared property whose
value is null -- so declawed=null together with
putAdditionalProperty("declawed", x) wrote x under the declared name and, on
the way back, migrated it into the declared field. A generated
declaredFields() helper now resolves the runtime type's own openapiFields by
exact class match over the discriminator mappings, so the declared name wins
whether or not the subtype emitted it. Exact matching rather than instanceof
keeps a mid-level subtype from shadowing its own children.
The second defect only surfaces when the subtype has no serializer of its own,
which is why the petstore hierarchy does not show it: Cat and Dog are
additionalProperties: true and Yasson dispatches to their own serializers.
Regenerating the okhttp samples touches only Animal and GrandparentAnimal, the
two models that are both a discriminator root and additionalProperties: true.
There was a problem hiding this comment.
1 issue found across 20 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="modules/openapi-generator/src/main/resources/Java/libraries/okhttp/build.gradle.mustache">
<violation number="1" location="modules/openapi-generator/src/main/resources/Java/libraries/okhttp/build.gradle.mustache:114">
P1: When `useJackson3` and `joda` are enabled, this dependency combines the Jackson 3 group with the Jackson 2 `$jackson_version`, so the generated Gradle build requests an unavailable or incompatible `tools.jackson.datatype:jackson-datatype-joda:2.x` artifact. Select `$jackson3_version` for Jackson 3 and `$jackson_version` otherwise, and apply the same conditional to the new POM dependency.</violation>
</file>
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
| {{#joda}} | ||
| implementation 'joda-time:joda-time:2.12.0' | ||
| {{#isJackson}} | ||
| implementation "{{jacksonPackage}}.datatype:jackson-datatype-joda:$jackson_version" |
There was a problem hiding this comment.
P1: When useJackson3 and joda are enabled, this dependency combines the Jackson 3 group with the Jackson 2 $jackson_version, so the generated Gradle build requests an unavailable or incompatible tools.jackson.datatype:jackson-datatype-joda:2.x artifact. Select $jackson3_version for Jackson 3 and $jackson_version otherwise, and apply the same conditional to the new POM dependency.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At modules/openapi-generator/src/main/resources/Java/libraries/okhttp/build.gradle.mustache, line 114:
<comment>When `useJackson3` and `joda` are enabled, this dependency combines the Jackson 3 group with the Jackson 2 `$jackson_version`, so the generated Gradle build requests an unavailable or incompatible `tools.jackson.datatype:jackson-datatype-joda:2.x` artifact. Select `$jackson3_version` for Jackson 3 and `$jackson_version` otherwise, and apply the same conditional to the new POM dependency.</comment>
<file context>
@@ -110,6 +110,9 @@ dependencies {
{{#joda}}
implementation 'joda-time:joda-time:2.12.0'
+ {{#isJackson}}
+ implementation "{{jacksonPackage}}.datatype:jackson-datatype-joda:$jackson_version"
+ {{/isJackson}}
{{/joda}}
</file context>
…matrix Found by generating the okhttp client for a live spring-petclinic-rest server across all four serialization libraries x 17 parameter combinations (68 runs), then compiling and exercising each against the running server. All changes are confined to Java/libraries/okhttp/ plus one okhttp-gated block in JavaClientCodegen; okhttp-gson and the shared root Java/*.mustache are untouched. pojo.mustache / JSON.mustache * readOnly properties never deserialized on Jackson 2 and Jackson 3. The field carried @JsonProperty(access = Access.READ_ONLY), which is the SERVER reading of OpenAPI readOnly - it means "serialize out, ignore on input", so Jackson discarded exactly the values a client needs. Setters are suppressed for readOnly vars and the readonly-args constructor had no @JsonCreator, so all three paths into the field were closed. Drop the access attribute (matching the shared root pojo.mustache, the only other emitter) and annotate the constructor. Every id, plus Owner.pets/Pet.visits/ProblemDetail, was null. * serializationLibrary=jsonb + dateLibrary=joda did not compile: the joda format imports were {{#isGson}}-gated while the JSON-B adapters, their fields and their setters all reference DateTimeFormatter - eight unresolved symbols. The joda adapters were also registered only when a format had been set explicitly, so Yasson (which has no joda support) fell back to bean mapping; register them unconditionally with ISO defaults, as the FileAdapter already does. * dateLibrary=legacy corrupted every format: date value. legacy maps both date and date-time onto java.util.Date, so the mapper-wide RFC3339 format applied to date-only properties: at Europe/Berlin, 2020-01-15 went out as "2020-01-14T23:00:00.000+00:00" - simultaneously a full timestamp the server rejects and a one-day backward shift. Select the representation per property instead, through one shared dateOnlyFormat() so all four serializers agree on the wire. Note a bare @jsonformat pattern is insufficient: with no explicit timezone it resolves against the mapper default, which Jackson sets to UTC rather than the JVM zone, and the day still shifts. * The generated JSON-B CustomJsonbDeserializer binds each property by declared type, so a field-level @JsonbTypeAdapter is never consulted; date-only properties now bind through an explicit helper. * RFC3339JavaTimeModule registers its deserializers after calling super.setupModule(), and SimpleModule forwards _deserializers only if that lazily-created map is already non-null - so on Jackson 2 the lenient RFC3339 parsing never took effect at all. Build the equivalent module locally rather than patching a template shared by six libraries. The upstream fix belongs in RFC3339JavaTimeModule itself. * generateBuilders and generateConstructorWithAllArgs were silently inert: neither flag appeared anywhere in the okhttp pojo template, unlike restclient, resttemplate, webclient and native. Wire up the shared javaBuilder partial and the all-args constructor. api.mustache * performBeanValidation removed the required-parameter null checks instead of adding to them - they lived inside the inverted section - and the substituted validator never fires for a plain null argument, so a clear ApiException became a NullPointerException or the null reached the server. The checks are now unconditional and validation is additive. JavaClientCodegen * defaultToEmptyContainer is a rule string, but DefaultCodegen only logs unrecognised tokens and then sets the flag unconditionally, so the boolean spelling every other option uses - defaultToEmptyContainer=true - matched no rule and silently produced the OPPOSITE of the documented behaviour. Reject it with a message naming the real syntax. Validating this for every generator belongs upstream; this is gated to okhttp. Verified: 42 okhttp configs regenerated, all samples compile, 501 okhttp invoker tests and 434 okhttp-jsonb tests green, JavaClientCodegenTest green, and each fix reproduced before/after against the live server. Zero okhttp-gson diff and zero shared-template diff.
There was a problem hiding this comment.
7 existing issues remain and 40 new issues found across 280 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/PetComposition.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/PetComposition.java:446">
P2: When a `PetComposition` contains an undeclared JSON property, `toBuilder().build()` silently drops it because the builder has no `additionalProperties` copy path. Preserve the additional-properties map in `toBuilder()` (and expose a builder setter if needed) so the documented shallow copy retains the complete model state.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/Order.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/Order.java:428">
P2: When an `Order` has undeclared JSON properties, `toBuilder()` drops them from the rebuilt object. Copy `additionalProperties` as part of the builder conversion, including the corresponding builder support.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/GrandparentAnimal.java">
<violation number="1">
P2: When a `GrandparentAnimal` has undeclared properties, `toBuilder()` silently drops them because the builder copies only `petType`. Add builder support for `additionalProperties` and copy the map so the documented shallow-copy operation preserves serialized state.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/PetRef.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/PetRef.java:447">
P2: When a `PetRef` contains an undeclared JSON property, `toBuilder().build()` drops it because `toBuilder()` copies only the six schema fields. Copy `additionalProperties` as part of the documented shallow clone.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/model/OuterComposite.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/model/OuterComposite.java:288">
P2: `toBuilder()` drops all undeclared JSON fields. Since `OuterComposite` stores those fields in `additionalProperties`, `toBuilder().build()` silently loses them; copy the map through the builder as part of this shallow copy.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/AllOfModelArrayAnyOf.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/AllOfModelArrayAnyOf.java:325">
P2: `toBuilder()` drops every entry in `additionalProperties`, so rebuilding a model with undeclared JSON fields silently loses those fields. Copy the additional-properties map as part of the builder state (and expose the corresponding builder assignment) before returning the rebuilt instance.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/ArrayDefault.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/ArrayDefault.java:267">
P2: When an `ArrayDefault` contains undeclared JSON fields, `toBuilder()` drops them despite documenting a shallow copy of the instance. Copy `additionalProperties` into the builder as well.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/NullableClass.java">
<violation number="1">
P2: When a model contains undeclared JSON fields, `toBuilder()` drops `additionalProperties`, so `build()` silently loses data. Copy `additionalProperties` into the builder instance as part of the shallow copy.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/model/PropertyNameCollision.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/model/PropertyNameCollision.java:284">
P2: When a `PropertyNameCollision` contains an undeclared JSON property, `toBuilder()` drops that property because it copies only the declared fields. Preserve `additionalProperties` when constructing the builder copy so `toBuilder()` matches its documented shallow-copy contract.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/model/AllOfModelArrayAnyOfAllOfLinkListColumn1.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/model/AllOfModelArrayAnyOfAllOfLinkListColumn1.java:226">
P2: When this model contains undeclared JSON fields, `toBuilder()` drops them because it copies only `value`, so the rebuilt model serializes without those fields. Preserve `additionalProperties` through the builder and `toBuilder()` copy.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/model/Category.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/model/Category.java:249">
P2: When a `Category` contains undeclared properties, `toBuilder().build()` silently drops them because this copy only transfers `id` and `name`. Copy `additionalProperties` as part of the shallow copy so builder round-trips preserve deserialized or explicitly added data.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/SpecialModelName.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/SpecialModelName.java:249">
P2: When this model contains undeclared JSON properties, `toBuilder().build()` silently drops them because `toBuilder()` copies only the declared fields. Copy `additionalProperties` shallowly as part of the builder conversion, and update the builder template so generated models retain these fields.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/FreeFormObjectTestClass.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/FreeFormObjectTestClass.java:252">
P2: When this model contains undeclared JSON properties, `toBuilder()` drops them because it copies only the declared fields. Preserve `additionalProperties` in the builder copy, including a builder path for that map, so the documented shallow copy retains the full model state.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jsonb/src/main/java/org/openapitools/client/model/Animal.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jsonb/src/main/java/org/openapitools/client/model/Animal.java:358">
P2: When an `Animal` contains an undeclared property, `toBuilder().build()` drops it because `toBuilder()` copies only `className` and `color`. Copy `additionalProperties` as well, shallowly, so rebuilding the model preserves its serialized data.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/model/Apple.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/model/Apple.java:248">
P2: `toBuilder()` drops undeclared properties. When `putAdditionalProperty` has captured a response field, this chain copies only declared fields, so the rebuilt model loses data during later serialization. Copy `additionalProperties` through the builder as well.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/model/ComplexQuadrilateral.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/model/ComplexQuadrilateral.java:248">
P2: When a model contains undeclared JSON fields, `toBuilder()` drops them even though it promises a shallow copy of the instance. Copy `additionalProperties` through the builder so builder-based copy/edit/send workflows preserve unknown fields.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/model/EnumArrays.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/model/EnumArrays.java:331">
P2: When `EnumArrays` contains an undeclared JSON property, `toBuilder().build()` silently drops it because this chain copies only declared fields. Copy `additionalProperties` in the builder template and regenerate these models.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/MixedPropertiesAndAdditionalPropertiesClass.java">
<violation number="1">
P2: When this model contains undeclared properties, `toBuilder()` silently loses them because the builder has no additional-properties copy path. Preserve `additionalProperties` in the builder and include it in `toBuilder()` so its documented shallow-copy behavior does not discard JSON data.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jsonb/src/main/java/org/openapitools/client/model/AllOfRefToLong.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jsonb/src/main/java/org/openapitools/client/model/AllOfRefToLong.java:303">
P2: When a JSON-B object contains undeclared fields, `toBuilder()` drops them because it copies only `id`; the returned model then loses those fields on access or serialization. Copy `additionalProperties` as part of the builder state.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/OuterComposite.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/OuterComposite.java:285">
P2: When an `OuterComposite` contains undeclared JSON properties, `toBuilder()` silently loses them because the builder has no `additionalProperties` copy. Add builder support for that map and copy it in `toBuilder()` so the documented shallow-copy operation preserves the full model state.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/model/NullableFieldsValue.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/model/NullableFieldsValue.java:249">
P2: When a model contains undeclared JSON properties, `toBuilder()` drops them because it copies only `before` and `after`. Copy `additionalProperties` as well so the documented shallow-copy contract preserves the model state.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/model/ModelWithOneOfAnyOfProperties.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/model/ModelWithOneOfAnyOfProperties.java:250">
P2: When this model contains undeclared properties, `toBuilder()` drops them because it copies only the two declared fields. Preserve `additionalProperties` when creating the builder so the documented shallow copy does not lose data.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/Dog.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/Dog.java:237">
P2: When a `Dog` contains undeclared properties, `toBuilder()` drops them from the rebuilt instance. Copy `getAdditionalProperties()` into the builder so editing a known field does not silently lose data.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/Pet.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/Pet.java:447">
P2: When a `Pet` contains undeclared properties, `toBuilder()` drops them because it copies only the six schema fields. Copy `additionalProperties` as part of the documented shallow copy so rebuilding does not lose serialized data.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/ObjectWithDeprecatedFields.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/ObjectWithDeprecatedFields.java:345">
P2: When this model contains an undeclared JSON property, `toBuilder().build()` drops it because the new copy path transfers only declared fields. Preserve `additionalProperties` through the builder as well.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/Name.java">
<violation number="1">
P2: Because `snake_case` and `123Number` are OpenAPI read-only properties, removing `READ_ONLY` makes generated `Name` objects include server-managed values in request JSON. Preserve read-only property access while handling response deserialization through the creator path.</violation>
<violation number="2">
P2: When a `Name` contains undeclared properties, `toBuilder().build()` silently drops them because `toBuilder()` never copies `additionalProperties`. Include the additional-property map in the builder copy, or change the method contract if that loss is intentional.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/model/Foo.java">
<violation number="1">
P2: Calling `Foo.toBuilder().build()` loses every undeclared JSON field. `Foo` stores those fields in `additionalProperties` via `putAdditionalProperty`, but this method copies only `bar`. Add an `additionalProperties` builder member/setter and copy it in `toBuilder()`.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jsonb/src/main/java/org/openapitools/client/model/AllOfModelArrayAnyOf.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jsonb/src/main/java/org/openapitools/client/model/AllOfModelArrayAnyOf.java:419">
P2: When a JSON-B model contains an undeclared property, the new `toBuilder()` drops it. Preserve `getAdditionalProperties()` in the builder copy so the documented shallow copy does not lose data that the custom deserializer captured and serializer emits.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/NewPet.java">
<violation number="1">
P2: With default access here, Jackson serializes `categoryAllOfRefDescriptionReadonly` as well as deserializes it. A populated `NewPet` can therefore send `category_allOf_ref_description_readonly` in request JSON despite the schema's `readOnly: true`; use `WRITE_ONLY` or an equivalent request serializer.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/ScaleneTriangle.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/ScaleneTriangle.java:251">
P2: When a model contains undeclared properties, `toBuilder()` drops them because it copies only `shapeType` and `triangleType`. Copy `additionalProperties` into the builder before returning it.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/model/PetWithRequiredTags.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/model/PetWithRequiredTags.java:453">
P2: When this model contains an undeclared property, `toBuilder().build()` drops it because the new builder copies only declared fields. Add builder support for `additionalProperties` and copy it in `toBuilder()` so the documented shallow-copy contract preserves JSON data.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/User.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/User.java:598">
P2: When a `User` contains an undeclared property, `toBuilder().build()` silently drops it because `toBuilder()` copies only declared fields. Preserve `additionalProperties` through the builder so the documented shallow copy remains complete.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/model/NewPet.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/model/NewPet.java:553">
P2: When a `NewPet` contains undeclared properties, `toBuilder()` silently drops them despite documenting a shallow copy of the instance. Preserve `additionalProperties` in the builder and in `toBuilder()` (and update the builder template so generated models retain this state).</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/model/AllOfRefToLong.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/model/AllOfRefToLong.java:215">
P2: When this model contains undeclared JSON fields, `toBuilder().build()` drops them because this chain copies only `id`. Copy `getAdditionalProperties()` through the builder, or otherwise preserve it in the builder's copy path.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/ClassModel.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/ClassModel.java:215">
P2: When a `ClassModel` contains undeclared JSON fields, `toBuilder()` drops them because the builder copies only `propertyClass`. Add builder support for `additionalProperties` and include it in this copy chain.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/Drawing.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/Drawing.java:333">
P2: toBuilder() does not copy the `additionalProperties` map, so for this model (which declares additionalProperties with @JsonAnySetter/@JsonAnyGetter) calling toBuilder().build() silently loses all undeclared properties. The javaBuilder.mustache template only chains the declared vars; extend it to also copy the additional-properties map when the model has `additionalProperties: true`.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/FormatTest.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/FormatTest.java:788">
P2: `toBuilder()` silently drops all undeclared additional properties. FormatTest supports `additionalProperties` via `@JsonAnySetter`/`@JsonAnyGetter` (`putAdditionalProperty`/`getAdditionalProperties`), but the generated Builder exposes no setter for it and `toBuilder()` never copies it, so `instance.toBuilder().build()` loses any undeclared properties. Add a copy of `additionalProperties` in `toBuilder()` (and ideally a builder method) so the builder round-trips the model faithfully.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/ReadOnlyFirst.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/ReadOnlyFirst.java:45">
P2: When `ReadOnlyFirst` is used in a request, Jackson now serializes the response-only `bar` property because this annotation removed `READ_ONLY`. Preserve creator-based response deserialization while excluding `readOnly` properties from outbound JSON.</violation>
</file>
<file name="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/TriangleInterface.java">
<violation number="1" location="samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/TriangleInterface.java:213">
P2: When `TriangleInterface` contains an undeclared property, `toBuilder()` drops it because the builder copies only `triangleType`. Preserve `additionalProperties` in the builder copy so `toBuilder()` fulfills its shallow-copy contract.</violation>
</file>
Note: This PR contains a large number of files. cubic selects up to 200 of the highest-priority eligible files for this review, so some files may not have been reviewed.
Requires human review: Auto-approval blocked because this review re-detected 7 unresolved issues already reported by Cubic.
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
| /** | ||
| * Create a builder with a shallow copy of this instance. | ||
| */ | ||
| public PetComposition.Builder toBuilder() { |
There was a problem hiding this comment.
P2: When a PetComposition contains an undeclared JSON property, toBuilder().build() silently drops it because the builder has no additionalProperties copy path. Preserve the additional-properties map in toBuilder() (and expose a builder setter if needed) so the documented shallow copy retains the complete model state.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/PetComposition.java, line 446:
<comment>When a `PetComposition` contains an undeclared JSON property, `toBuilder().build()` silently drops it because the builder has no `additionalProperties` copy path. Preserve the additional-properties map in `toBuilder()` (and expose a builder setter if needed) so the documented shallow copy retains the complete model state.</comment>
<file context>
@@ -374,5 +374,84 @@ private String toIndentedString(Object o) {
+ /**
+ * Create a builder with a shallow copy of this instance.
+ */
+ public PetComposition.Builder toBuilder() {
+ return new PetComposition.Builder()
+ .id(getId())
</file context>
| * Create a builder with a shallow copy of this instance. | ||
| */ | ||
| public Order.Builder toBuilder() { | ||
| return new Order.Builder() |
There was a problem hiding this comment.
P2: When an Order has undeclared JSON properties, toBuilder() drops them from the rebuilt object. Copy additionalProperties as part of the builder conversion, including the corresponding builder support.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/Order.java, line 428:
<comment>When an `Order` has undeclared JSON properties, `toBuilder()` drops them from the rebuilt object. Copy `additionalProperties` as part of the builder conversion, including the corresponding builder support.</comment>
<file context>
@@ -355,5 +355,84 @@ private String toIndentedString(Object o) {
+ * Create a builder with a shallow copy of this instance.
+ */
+ public Order.Builder toBuilder() {
+ return new Order.Builder()
+ .id(getId())
+ .petId(getPetId())
</file context>
| @@ -0,0 +1,232 @@ | |||
| /* | |||
There was a problem hiding this comment.
P2: When a GrandparentAnimal has undeclared properties, toBuilder() silently drops them because the builder copies only petType. Add builder support for additionalProperties and copy the map so the documented shallow-copy operation preserves serialized state.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/GrandparentAnimal.java, line 228:
<comment>When a `GrandparentAnimal` has undeclared properties, `toBuilder()` silently drops them because the builder copies only `petType`. Add builder support for `additionalProperties` and copy the map so the documented shallow-copy operation preserves serialized state.</comment>
<file context>
@@ -174,5 +174,59 @@ private String toIndentedString(Object o) {
+ */
+ public GrandparentAnimal.Builder toBuilder() {
+ return new GrandparentAnimal.Builder()
+ .petType(getPetType());
+ }
+
</file context>
| return new PetRef.Builder() | ||
| .id(getId()) | ||
| .category(getCategory()) | ||
| .name(getName()) | ||
| .photoUrls(getPhotoUrls()) | ||
| .tags(getTags()) | ||
| .status(getStatus()); |
There was a problem hiding this comment.
P2: When a PetRef contains an undeclared JSON property, toBuilder().build() drops it because toBuilder() copies only the six schema fields. Copy additionalProperties as part of the documented shallow clone.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/PetRef.java, line 447:
<comment>When a `PetRef` contains an undeclared JSON property, `toBuilder().build()` drops it because `toBuilder()` copies only the six schema fields. Copy `additionalProperties` as part of the documented shallow clone.</comment>
<file context>
@@ -374,5 +374,84 @@ private String toIndentedString(Object o) {
+ * Create a builder with a shallow copy of this instance.
+ */
+ public PetRef.Builder toBuilder() {
+ return new PetRef.Builder()
+ .id(getId())
+ .category(getCategory())
</file context>
| return new PetRef.Builder() | |
| .id(getId()) | |
| .category(getCategory()) | |
| .name(getName()) | |
| .photoUrls(getPhotoUrls()) | |
| .tags(getTags()) | |
| .status(getStatus()); | |
| PetRef.Builder builder = new PetRef.Builder() | |
| .id(getId()) | |
| .category(getCategory()) | |
| .name(getName()) | |
| .photoUrls(getPhotoUrls()) | |
| .tags(getTags()) | |
| .status(getStatus()); | |
| builder.instance.additionalProperties = getAdditionalProperties(); | |
| return builder; |
| return new OuterComposite.Builder() | ||
| .myNumber(getMyNumber()) | ||
| .myString(getMyString()) | ||
| .myBoolean(getMyBoolean()); |
There was a problem hiding this comment.
P2: toBuilder() drops all undeclared JSON fields. Since OuterComposite stores those fields in additionalProperties, toBuilder().build() silently loses them; copy the map through the builder as part of this shallow copy.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/java/okhttp-jackson/src/main/java/org/openapitools/client/model/OuterComposite.java, line 288:
<comment>`toBuilder()` drops all undeclared JSON fields. Since `OuterComposite` stores those fields in `additionalProperties`, `toBuilder().build()` silently loses them; copy the map through the builder as part of this shallow copy.</comment>
<file context>
@@ -224,5 +224,69 @@ private String toIndentedString(Object o) {
+ return new OuterComposite.Builder()
+ .myNumber(getMyNumber())
+ .myString(getMyString())
+ .myBoolean(getMyBoolean());
+ }
+
</file context>
| */ | ||
| public ClassModel.Builder toBuilder() { | ||
| return new ClassModel.Builder() | ||
| .propertyClass(getPropertyClass()); |
There was a problem hiding this comment.
P2: When a ClassModel contains undeclared JSON fields, toBuilder() drops them because the builder copies only propertyClass. Add builder support for additionalProperties and include it in this copy chain.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/ClassModel.java, line 215:
<comment>When a `ClassModel` contains undeclared JSON fields, `toBuilder()` drops them because the builder copies only `propertyClass`. Add builder support for `additionalProperties` and include it in this copy chain.</comment>
<file context>
@@ -161,5 +161,59 @@ private String toIndentedString(Object o) {
+ */
+ public ClassModel.Builder toBuilder() {
+ return new ClassModel.Builder()
+ .propertyClass(getPropertyClass());
+ }
+
</file context>
| * Create a builder with a shallow copy of this instance. | ||
| */ | ||
| public Drawing.Builder toBuilder() { | ||
| return new Drawing.Builder() |
There was a problem hiding this comment.
P2: toBuilder() does not copy the additionalProperties map, so for this model (which declares additionalProperties with @JsonAnySetter/@JsonAnyGetter) calling toBuilder().build() silently loses all undeclared properties. The javaBuilder.mustache template only chains the declared vars; extend it to also copy the additional-properties map when the model has additionalProperties: true.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/Drawing.java, line 333:
<comment>toBuilder() does not copy the `additionalProperties` map, so for this model (which declares additionalProperties with @JsonAnySetter/@JsonAnyGetter) calling toBuilder().build() silently loses all undeclared properties. The javaBuilder.mustache template only chains the declared vars; extend it to also copy the additional-properties map when the model has `additionalProperties: true`.</comment>
<file context>
@@ -268,5 +268,74 @@ private String toIndentedString(Object o) {
+ * Create a builder with a shallow copy of this instance.
+ */
+ public Drawing.Builder toBuilder() {
+ return new Drawing.Builder()
+ .mainShape(getMainShape())
+ .shapeOrNull(getShapeOrNull())
</file context>
| /** | ||
| * Create a builder with a shallow copy of this instance. | ||
| */ | ||
| public FormatTest.Builder toBuilder() { |
There was a problem hiding this comment.
P2: toBuilder() silently drops all undeclared additional properties. FormatTest supports additionalProperties via @JsonAnySetter/@JsonAnyGetter (putAdditionalProperty/getAdditionalProperties), but the generated Builder exposes no setter for it and toBuilder() never copies it, so instance.toBuilder().build() loses any undeclared properties. Add a copy of additionalProperties in toBuilder() (and ideally a builder method) so the builder round-trips the model faithfully.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/FormatTest.java, line 788:
<comment>`toBuilder()` silently drops all undeclared additional properties. FormatTest supports `additionalProperties` via `@JsonAnySetter`/`@JsonAnyGetter` (`putAdditionalProperty`/`getAdditionalProperties`), but the generated Builder exposes no setter for it and `toBuilder()` never copies it, so `instance.toBuilder().build()` loses any undeclared properties. Add a copy of `additionalProperties` in `toBuilder()` (and ideally a builder method) so the builder round-trips the model faithfully.</comment>
<file context>
@@ -672,5 +672,139 @@ private String toIndentedString(Object o) {
+ /**
+ * Create a builder with a shallow copy of this instance.
+ */
+ public FormatTest.Builder toBuilder() {
+ return new FormatTest.Builder()
+ .integer(getInteger())
</file context>
| @JsonTypeName("ReadOnlyFirst") | ||
| public class ReadOnlyFirst { | ||
| public static final String JSON_PROPERTY_BAR = "bar"; | ||
| @JsonProperty(value = JSON_PROPERTY_BAR) |
There was a problem hiding this comment.
P2: When ReadOnlyFirst is used in a request, Jackson now serializes the response-only bar property because this annotation removed READ_ONLY. Preserve creator-based response deserialization while excluding readOnly properties from outbound JSON.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/ReadOnlyFirst.java, line 45:
<comment>When `ReadOnlyFirst` is used in a request, Jackson now serializes the response-only `bar` property because this annotation removed `READ_ONLY`. Preserve creator-based response deserialization while excluding `readOnly` properties from outbound JSON.</comment>
<file context>
@@ -42,7 +42,7 @@
public class ReadOnlyFirst {
public static final String JSON_PROPERTY_BAR = "bar";
- @JsonProperty(value = JSON_PROPERTY_BAR, access = JsonProperty.Access.READ_ONLY)
+ @JsonProperty(value = JSON_PROPERTY_BAR)
@javax.annotation.Nullable
private String bar;
</file context>
| /** | ||
| * Create a builder with a shallow copy of this instance. | ||
| */ | ||
| public TriangleInterface.Builder toBuilder() { |
There was a problem hiding this comment.
P2: When TriangleInterface contains an undeclared property, toBuilder() drops it because the builder copies only triangleType. Preserve additionalProperties in the builder copy so toBuilder() fulfills its shallow-copy contract.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At samples/client/petstore/java/okhttp-jackson3/src/main/java/org/openapitools/client/model/TriangleInterface.java, line 213:
<comment>When `TriangleInterface` contains an undeclared property, `toBuilder()` drops it because the builder copies only `triangleType`. Preserve `additionalProperties` in the builder copy so `toBuilder()` fulfills its shallow-copy contract.</comment>
<file context>
@@ -161,5 +161,59 @@ private String toIndentedString(Object o) {
+ /**
+ * Create a builder with a shallow copy of this instance.
+ */
+ public TriangleInterface.Builder toBuilder() {
+ return new TriangleInterface.Builder()
+ .triangleType(getTriangleType());
</file context>
Adds a new
okhttplibrary to the Java client generator, marked[BETA]. It is derived fromokhttp-gson, but decoupled from Gson: a single template set emits working clients for Gson(default), Jackson 2, Jackson 3 and JSON-B, on OkHttp 5.4.0, and it honours the existing
useJspecifyoption.okhttp-gsonis untouched and remains the default library — its generated output is byte-identicalto master. This is purely additive for existing users; the new library is opt-in via
--library okhttp.JavaClientCodegenJSPECIFY_SUPPORTED_LIBRARIESand to theuseJackson3allowlist, and reuses the
okhttp-gsonsupporting-file branch without forcing a serializationlibrary.
isGson/isJackson/isJsonbafter the serialization switch, wheregetSerializationLibrary()is authoritative. No new early property reads, so no behavioural riskto other libraries.
openApiNullableoff for JSON-B:jackson-databind-nullableis Jackson-only and the pomomits it there, so leaving the flag on emitted
JsonNullablereferences that could not resolve.x-enum-as-stringdiscriminator rewrite for every serialization library, not justJackson. This is not a Jackson nicety — a child schema that narrows an inherited discriminator to
a single-value enum otherwise generates a getter that cannot override the parent's
Stringgetter.
JsonNullable/JsonIgnoreimports stay Jackson-only.useSingleRequestParameterand theoneOf/anyOfModelNullhandling to the newlibrary; both were gated on allowlists that excluded it, even though its templates support them.
Samples — 27 configs covering the four serialization variants, JSpecify for each of Jackson 2/3
and JSON-B,
oneOf/anyOf, nullable-required, AWS4 signing, dynamic operations, groupedparameters, parcelable models, streaming, Swagger 1/2 annotations, OpenAPI 3.1, the echo API and
user-defined templates.
One rename —
bin/configs/java-okhttp-user-defined-templates.yaml→java-okhttp-gson-user-defined-templates.yaml. It generated theokhttp-gsonsample despite theneutral name, and every other
okhttp-gsonconfig is already namedjava-okhttp-gson-*. Contentunchanged, generated sample untouched.
PR checklist
Commit all changed files.
This is important, as CI jobs will verify all generator outputs of your HEAD commit as it would merge with master.
These must match the expectations made by your contribution.
You may regenerate an individual generator by passing the relevant config(s) as an argument to the script, for example
./bin/generate-samples.sh bin/configs/java*.IMPORTANT: Do NOT purge/delete any folders/files (e.g. tests) when regenerating the samples as manually written tests may be removed.
@bbdouglas @sreeshas @jfiala @lukoyanov @cbornet @jeff9finger @karismann @Zomzog @lwlee2608 @martin-mfg @KannaKim
Summary by cubic
Adds a new
okhttpJava client library that generates OkHttp 5.4.0 clients for Gson (default), Jackson 2/3, and JSON-B.okhttp-gsonremains the default and byte-identical; the new library is opt-in via--library okhttp. Standardizes discriminator handling and fixes correctness issues in the new templates.Codegen and templates
okhttpinJavaClientCodegen, resolves serializer flags afterserializationLibrary, extendsuseSingleRequestParameterandoneOf/anyOfnull handling, delegates model symbol imports to avoid duplicate import lines, and rejects the booleandefaultToEmptyContainer=truespelling (it silently inverted the option).openApiNullable=falseacross the library and applies thex-enum-as-stringdiscriminator rewrite across all serializers.Java/libraries/okhttp/*templates provide per-client JSON config, payload bytes passed to auth, AWS4 signed last, andRetryingOAuthon OkHttp (no Apache Oltu).fromJson/toJsonhelpers.Correctness, samples, and CI
x-amz-*header signing, RFC3339 date module for Jackson 2/3 (built locally so Jackson 2 lenient parsing takes effect),@JsonbTransientadditionalProperties, response-header lowercasing withLocale.ROOT, bearer-token NPE, null params in dynamic operations, and resource leaks in the download path (bodies and sinks close on mid-copy failures and responses close on failures). Jackson readOnly properties now deserialize (READ_ONLYaccess dropped, constructor annotated),generateBuilders/generateConstructorWithAllArgsnow generate,performBeanValidationkeeps required-parameter null checks, date-onlylegacyvalues no longer shift a day, and JSON-B compiles withdateLibrary=joda(joda adapters registered unconditionally).dateLibrary=jodaJackson clients compile.okhttpsample configs across Gson/Jackson 2/3/JSON-B, JSpecify,oneOf/anyOf, streaming, AWS4, OpenAPI 3.1, grouped params, dynamic operations, and parcelable. The Jackson 2/3 and JSON-B samples now generate from the same spec as the Gson sample (previously the http-signature spec), which exposed and fixed JSON-B gaps: a File adapter,@JsonbTransientin composed models, and composed deserializers handling arrays and scalar roots.useJakartaEe), updates generator docs (api doc examples now importmodelPackage), renames theokhttp-gsonuser-defined-templates config, ports the invoker unit tests, and removes staleinfo.md/*ApiDocumentation.mdoutput from the user-defined-templates samples.Generate with
openapi-generator generate -g java --library okhttp -p serializationLibrary=gson|jackson|jsonb [-p useJackson3=true] [-p useJspecify=true]. No migration for existingokhttp-gsonusers.openApiNullableis disabled for the whole library, sojackson-databind-nullabletypes are not generated.Written for commit e373777. Summary will update on new commits.