openapi-generator icon indicating copy to clipboard operation
openapi-generator copied to clipboard

[BUG] [Java] Invalid code generation for oneof types.

Open Bethibande opened this issue 1 year ago • 1 comments

Bug Report Checklist

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

The generator generated an invalid java class when generating a client for the github api definition.

openapi-generator version

v7.5.0 (docker image: openapitools/openapi-generator-cli:v7.5.0) Note the docker image "latest" was also tested and has the same issue.

OpenAPI declaration file content or url

https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json line 35245 seems to be the issue:

"payload": {
    "oneOf": [
        {
            "type": "object",
            "additionalProperties": true
        },
        {
            "type": "string",
            "description": "JSON payload with extra information about the deployment.",
            "default": ""
        }
    ]
}

This generated a class that doesn't compile (ReposCreateDeploymentRequestPayload.java). Compiling the generated project using "gradle build" causes 6 compiler errors, all within this one class. For example the following method is generated:

/**
 * Get the actual instance of `Map<String, Object>`. If the actual instance is not `Map<String, Object>`,
 * the ClassCastException will be thrown.
 *
 * @return The actual instance of `Map<String, Object>`
 * @throws ClassCastException if the instance is not `Map<String, Object>`
 */
public Map<String, Object> getMap<String, Object>() throws ClassCastException {
    return (Map<String, Object>)super.getActualInstance();
}

Other errors include invalid field names (containing Map<String, Object>) or calls like Map<String, Object>.class

final TypeAdapter<Map<String, Object>> adapterMap<String, Object> = gson.getDelegateAdapter(this, TypeToken.get(Map<String, Object>.class));

See gradle error logs: https://gist.github.com/Bethibande/4d0c2e925daff40572bcb3cee44d6ed7

Generation Details / Steps to reproduce

This can be reproduced on Windows with Docker (WSL) using the following two commands:

docker run --rm -v "%CD%:/local" openapitools/openapi-generator-cli:v7.5.0 generate -i https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json -g java -o /local/out/java
docker run --rm -v "%CD%:/local" -w /local/out/java gradle:8.7.0-jdk17 gradle build
Suggest a fix
  1. Remove <, ,, and > from field and method names resulting in names like getMapStringObject or adapterMapStringObject
  2. Change TypeToken creation for Map types from TypeToken.get(Map<String, Object>.class) to TypeToken.getParameterized(Map.class, String.class, Object.class) or new TypeToken<Map<String, Object>>() {}, see Gson documentation for TypeToken

Bethibande avatar Apr 27 '24 15:04 Bethibande

thanks for reporting the issue and suggesting a fix.

can you please PM me via Slack in the coming week when you've time to further discuss the fix? thanks

https://join.slack.com/t/openapi-generator/shared_invite/zt-12jxxd7p2-XUeQM~4pzsU9x~eGLQqX2g

wing328 avatar Apr 28 '24 13:04 wing328