Skip to content

[JAVA] Add generic okhttp client - #24734

Open
rar91279 wants to merge 19 commits into
OpenAPITools:masterfrom
rar91279:java-generic-okhttp
Open

[JAVA] Add generic okhttp client #24734
rar91279 wants to merge 19 commits into
OpenAPITools:masterfrom
rar91279:java-generic-okhttp

Conversation

@rar91279

@rar91279 rar91279 commented Aug 19, 2026

Copy link
Copy Markdown

Adds a new okhttp library to the Java client generator, marked [BETA]. It is derived from
okhttp-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
useJspecify option.

okhttp-gson is untouched and remains the default library — its generated output is byte-identical
to master. This is purely additive for existing users; the new library is opt-in via
--library okhttp.

openapi-generator generate -g java --library okhttp \
  -p serializationLibrary=jackson -p useJackson3=true -p useJspecify=true

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 a serialization
    library.
  • Resolves isGson/isJackson/isJsonb after the serialization switch, where
    getSerializationLibrary() is authoritative. No new early property reads, so no behavioural risk
    to other libraries.
  • Forces openApiNullable off for JSON-B: jackson-databind-nullable is Jackson-only and the pom
    omits it there, so leaving the flag on emitted JsonNullable references that could not resolve.
  • Applies the x-enum-as-string discriminator rewrite for every serialization library, not just
    Jackson. 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 String
    getter. JsonNullable/JsonIgnore imports stay Jackson-only.
  • Extends useSingleRequestParameter and the oneOf/anyOf ModelNull handling to the new
    library; 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, grouped
parameters, parcelable models, streaming, Swagger 1/2 annotations, OpenAPI 3.1, the echo API and
user-defined templates.

One renamebin/configs/java-okhttp-user-defined-templates.yaml
java-okhttp-gson-user-defined-templates.yaml. It generated the okhttp-gson sample despite the
neutral name, and every other okhttp-gson config is already named java-okhttp-gson-*. Content
unchanged, generated sample untouched.

PR checklist

  • Read the contribution guidelines.
  • Run the following to build the project and update samples:
    ./mvnw clean package || exit
    ./bin/generate-samples.sh ./bin/configs/*.yaml || exit
    ./bin/utils/export_docs_generators.sh || exit
    
    (For Windows users, please run the script in WSL)
    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.
  • If your PR is targeting a particular programming language, @mention the technical committee members, so they are more likely to review the pull request.

@bbdouglas @sreeshas @jfiala @lukoyanov @cbornet @jeff9finger @karismann @Zomzog @lwlee2608 @martin-mfg @KannaKim


Summary by cubic

Adds a new okhttp Java client library that generates OkHttp 5.4.0 clients for Gson (default), Jackson 2/3, and JSON-B. okhttp-gson remains 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

  • Registers okhttp in JavaClientCodegen, resolves serializer flags after serializationLibrary, and extends useSingleRequestParameter and oneOf/anyOf null handling.
  • Forces openApiNullable=false across the library and applies the x-enum-as-string discriminator rewrite across all serializers.
  • New Java/libraries/okhttp/* templates provide per-client JSON config, payload bytes passed to auth, AWS4 signed last, and RetryingOAuth on OkHttp (no Apache Oltu).
  • JSON-B gains custom serializers for discriminator hierarchies and additional properties; oneOf wrappers get composed fromJson/toJson helpers.

Correctness, samples, and CI

  • Fixes gzip content length restoration, progress body/source memoization, x-amz-* header signing, RFC3339 date module for Jackson 2/3, @JsonbTransient for additionalProperties, bearer-token NPE, executeStream connection leak, and null params in dynamic operations.
  • Adds 27 okhttp sample configs across Gson/Jackson 2/3/JSON-B, JSpecify, oneOf/anyOf, streaming, AWS4, OpenAPI 3.1, grouped params, dynamic operations, and parcelable.
  • Wires samples into GitHub Actions and new Maven profiles, updates generator docs, renames the okhttp-gson user-defined-templates config to match its library, and ports the invoker unit tests.

Generate with openapi-generator generate -g java --library okhttp -p serializationLibrary=gson|jackson|jsonb [-p useJackson3=true] [-p useJspecify=true]. No migration for existing okhttp-gson users. openApiNullable is disabled for the whole library, so jackson-databind-nullable types are not generated.

Written for commit b6c18a6. Summary will update on new commits.

Review in cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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>

Comment thread samples/client/echo_api/java/okhttp-jackson-user-defined-templates/git_push.sh Outdated
@rar91279
rar91279 marked this pull request as draft August 19, 2026 12:04
@rar91279
rar91279 marked this pull request as ready for review August 19, 2026 21:32

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All reported issues were addressed across 1 file (changes from recent commits).

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread samples/client/others/java/okhttp-jackson-oneOf/git_push.sh Outdated
…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.
@KannaKim

Copy link
Copy Markdown
Contributor

This PR is too broad in scope, it's difficult to review 400k lines of changes.

@rar91279

rar91279 commented Sep 2, 2026

Copy link
Copy Markdown
Author

Hi, @KannaKim.
Thank you and sorry about that.

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.
I suppose many people use this as default and changing anything on it could have much more impact on running codebases as adding generic okthttp generator, as beta, aside of it.

Do you have some Idea for me how to organize this PR better for review?
Beside the fixing all concerns of cubic review, i have to do.

@wing328

wing328 commented Sep 3, 2026

Copy link
Copy Markdown
Member

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.
@rar91279
rar91279 force-pushed the java-generic-okhttp branch from d7145f5 to d289677 Compare September 4, 2026 11:32
@rar91279

rar91279 commented Sep 4, 2026

Copy link
Copy Markdown
Author

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.
i'll migrate an api client to the new one with jackson2 in a production system going in testing next week.

JSON-B will be difficult, i don't have any projects runnig this in production :(

I have merged master yesterday and resolved cubic concerns.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants