Skip to content

fix(java): fix OAuth staged builder ordering and long literal default#12031

Open
tjb9dc wants to merge 8 commits intomainfrom
devin/1770089773-fix-java-oauth-staged-builder
Open

fix(java): fix OAuth staged builder ordering and long literal default#12031
tjb9dc wants to merge 8 commits intomainfrom
devin/1770089773-fix-java-oauth-staged-builder

Conversation

@tjb9dc
Copy link
Collaborator

@tjb9dc tjb9dc commented Feb 3, 2026

Description

Refs: Customer reproduction case for Java SDK OAuth compilation failures

This PR fixes two bugs in the Java SDK's OAuthTokenSupplier generator:

  1. Staged builder ordering bug: The generator hardcoded clientId and clientSecret as the first builder method calls, but the staged builder requires properties to be called in their definition order. Fixed by collecting properties from the request body in order and building the request accordingly.

  2. Long literal bug: The default expiresIn value used 3600 (int) instead of 3600L (long), causing a type mismatch when expiresIn is Optional<Long>. Now conditionally uses the correct literal suffix based on the actual type (3600L for Long/Uint64, 3600 for Integer/Uint).

Changes Made

  • Added test-definitions/fern/apis/exhaustive/definition/oauth.yml with a token endpoint where grant_type is required and comes before client_id
  • Updated test-definitions/fern/apis/exhaustive/definition/api.yml to use OAuth authentication
  • Fixed OAuthTokenSupplierGenerator.java:
    • Rewrote buildFetchTokenMethod to collect and iterate through request body properties in definition order
    • Added collectRequestBodyProperties() helper to gather properties from headers and body
    • Added extractLiteral() helper to detect literal properties
    • Added isLongType() helper to check if a type requires the L suffix (handles Long, Uint64)
    • Added RequestBodyProperty inner class to represent properties with their metadata
    • Conditionally uses 3600L or 3600 based on the expires_in type
  • Updated generators/java/sdk/versions.yml with changelog for v3.34.8
  • Updated seed output with fixed OAuthTokenSupplier code
  • Updated Swift snapshot for exhaustive fixture (new OAuth endpoint path)
  • Updated README.md generator (if applicable)

Testing

The fix can be verified by running compilation on the generated output:

cd seed/java-sdk/exhaustive/no-custom-config && ./gradlew compileJava

Before fix - errors:

error: cannot find symbol
    .clientId(clientId)
    ^
  symbol:   method clientId(String)
  location: interface GrantTypeStage

error: incompatible types: int cannot be converted to Long
    this.expiresAt = getExpiresAt(authResponse.getExpiresIn().orElse(3600));

After fix - compiles successfully with correct ordering:

GetTokenRequest getTokenRequest = GetTokenRequest.builder()
        .grantType(grantType)      // Now called first (matches definition order)
        .clientId(clientId)
        .clientSecret(clientSecret)
        .scope(scope)
        .build();
  • Unit tests added/updated
  • Manual testing completed (seed tests pass, generated code compiles)

Human Review Checklist

  • Verify the assumption that headers come before body properties in staged builder order
  • Confirm the fix handles the customer's actual OAuth endpoint structure
  • Note: Referenced request body types are not handled (only inlined bodies) - comment indicates "most OAuth uses inline bodies"
  • Verify propertyToFieldName map correctly handles all naming conventions
  • Properties not in the map are silently skipped - confirm this is intended behavior
  • isLongType() uses PrimitiveTypeV1 visitor - verify this covers all cases (V2 types?)
  • isLongType() handles Optional containers but not Nullable - verify this is sufficient for OAuth use cases

Link to Devin run: https://app.devin.ai/sessions/c08dddf1877142de9c8c40234b8812df
Requested by: @tjb9dc

…ilder ordering bug

Co-Authored-By: thomas@buildwithfern.com <tjb9dcshop@gmail.com>
@devin-ai-integration
Copy link
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

devin-ai-integration bot and others added 7 commits February 3, 2026 03:52
Co-Authored-By: thomas@buildwithfern.com <tjb9dcshop@gmail.com>
Co-Authored-By: thomas@buildwithfern.com <tjb9dcshop@gmail.com>
Co-Authored-By: thomas@buildwithfern.com <tjb9dcshop@gmail.com>
Co-Authored-By: thomas@buildwithfern.com <tjb9dcshop@gmail.com>
Co-Authored-By: thomas@buildwithfern.com <tjb9dcshop@gmail.com>
Co-Authored-By: thomas@buildwithfern.com <tjb9dcshop@gmail.com>
Co-Authored-By: thomas@buildwithfern.com <tjb9dcshop@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant