OpenAPITools / OpenAPITools/openapi-generator

[BUG] Java OpenApi generation fails for type number, format double when Double min/max are both used together

Open
#12,111 0 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

Issue: Bug
Dominant language
Java
Stars
26.8k
Forks
7.7k
PR merge metrics
PR metrics pending

Description

Bug Report Checklist
  • Have you provided a full/minimal spec to reproduce the issue?
  • Have you validated the input using an OpenAPI validator (example)?
  • Have you tested with the latest master to confirm the issue still exists?
  • Have you searched for related issues/PRs?
  • What's the actual output vs expected output?
  • [Optional] Sponsorship to speed up the bug fix or feature request (example)
Description

When generating Java models, if Double max and min are passed BOTH for maximum/minimum for type: number; format: double in api spec, code generation fails. Looking at the stack trace as well as experimenting, it appears that if you leave off one or the other, it will work.

Bottom of the stack trace is:

Caused by: java.lang.NumberFormatException: Character I is neither a decimal digit number, decimal point, nor "e" notation exponential mark.
        at org.openapitools.codegen.examples.ExampleGenerator.resolvePropertyToExample(ExampleGenerator.java:254)
        at org.openapitools.codegen.examples.ExampleGenerator.resolveModelToExample(ExampleGenerator.java:348)
        at org.openapitools.codegen.examples.ExampleGenerator.generate(ExampleGenerator.java:159)
        at org.openapitools.codegen.examples.ExampleGenerator.generateFromResponseSchema(ExampleGenerator.java:97)
        at org.openapitools.codegen.examples.ExampleGenerator.generateFromResponseSchema(ExampleGenerator.java:59)
        at org.openapitools.codegen.DefaultCodegen.handleMethodResponse(DefaultCodegen.java:3874)
        at org.openapitools.codegen.DefaultCodegen.fromOperation(DefaultCodegen.java:4039)
        at org.openapitools.codegen.languages.AbstractJavaCodegen.fromOperation(AbstractJavaCodegen.java:1529)
        at org.openapitools.codegen.DefaultGenerator.processOperation(DefaultGenerator.java:1131)

There

openapi-generator version

5.4.0 (Gradle via plugin)

OpenAPI declaration file content or url
openapi: 3.0.3
info:
  title: Sample Title
  version: '20220411'
paths:
  /api/v1/endpoint:
    post:
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SomeRequest'
        description: The user to create.
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SomeResponse'
          description: Success
components:
  schemas:
    SomeRequest:
      type: object
      description: Request Object
      properties:
        idCode:
          description: ID code
          maxLength: 32767
          pattern: '^[\w\W]*$'
          type: string
    SomeResponse:
      type: object
      description: Response Object
      properties:
        doubleValue:
          description: A Double floating point value.  -1.7e308 - 1.7e308
          type: number
          format: double
#          minimum: 0
          minimum: -1.7976931348623158e308
          maximum: 1.7976931348623157e308
#            minimum: -1.7976931348623158e308
#          maximum: -1.0e308

Generation Details

Gradle build, client+model generation, library=native, System=Java17

Steps to reproduce
  • Generate java models from given api spec.
  • Code generation fails
Related issues/PRs

N/A

Suggest a fix

This is likely due to the following line

https://github.com/OpenAPITools/openapi-generator/blob/d17316e8d98be750fd87af528174b6584578d394/modules/openapi-generator/src/main/java/org/openapitools/codegen/examples/ExampleGenerator.java#L322

private double randomNumber(Double min, Double max) {
        if (min != null && max != null) {
            double range = max - min;
            return random.nextDouble() * range + min;
        } else if (min != null) {
            return random.nextDouble() + min;
        } else if (max != null) {
            return random.nextDouble() * max;
        } else {
            return random.nextDouble() * 10;
        }
    }

When value of -1.7976931348623158e308 is specified for minimum, and a value of 1.7976931348623157e308 is specified for maximum, at the same time, the line double range = max - min will appear out of range for type double. Run in IntelliJ, the result is "Infinity", which is likely where the capital letter "I" is coming from in the exception message

Caused by: java.lang.NumberFormatException: Character I is neither a decimal digit number, decimal point, nor "e" notation

The double range = max - min should likely be of type BigDecimal to hold the range, which can be larger than the scope of Double itself, wheras the result is always within the range of Double, so it can then be converted back after the random.nextDouble() * range/

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with modules/openapi-generator/src/main/java/org/openapitools/codegen/examples/ExampleGenerator.java, especially resolvePropertyToExample and randomNumber. Reproduce the failure with the supplied OpenAPI schema and both Double bounds. Done means Java generation succeeds and produces a valid example for the double property without the NumberFormatException.

Written by the indexing model from the issue text.

Assessment

Tech stack
java, openapi
Domain
backend-api-design, devtools
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.