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

[BUG][JAVA] JsonNullable<?> is not generated for property define as nullable:true

Open robertop87 opened this issue 1 year ago • 17 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

I've create this repository as example https://github.com/robertop87/opengen

The problem is that the generator (gradle plugin 7.3.0) is not generating JsonNullable<?> for properties defined as nullable: true

Update 2: According docs, enabling x-is-jackson-optional-nullable extension should generate the expected code, but it has no any effect in generation.

Update 1: Based on community suggestion, I changed the generatorName from java to spring, then the JsonNullable was generated correctly BUT the generated code is a spring server application, which is not the goal for this case. The goal is to generate a JAVA client.

openapi-generator version

id "org.openapi.generator" version "7.3.0"

OpenAPI declaration file content or url

https://github.com/robertop87/opengen/blob/main/swagger.yml

Generation Details

Just using the mentioned gradle plugin, steps to generate are in the repository https://github.com/robertop87/opengen

./gradlew clean assemble

Steps to reproduce

Generate the Pet.java class

Related issues/PRs

https://github.com/OpenAPITools/openapi-generator/issues/14765

robertop87 avatar Feb 15 '24 13:02 robertop87

Did you enable openApiNullable https://openapi-generator.tech/docs/generators/spring/

MelleD avatar Feb 15 '24 13:02 MelleD

I also just stumbled upon this issue when testing v7.3.0 – but I tested with the maven plugin.

@MelleD openApiNullable is documented to be enabled by default 🤷

tofi86 avatar Feb 15 '24 21:02 tofi86

Hey @tofi86 I tried it with:

    <groupId>org.openapitools</groupId>
    <artifactId>openapi-generator-maven-plugin</artifactId>
    <version>7.3.0</version>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
            <configuration>
                <inputSpec>
                    ${project.basedir}/swagger.yml
                </inputSpec>
                <generatorName>spring</generatorName>
                <apiPackage>test</apiPackage>
                <modelPackage>test</modelPackage>
            </configuration>
        </execution>
    </executions>

and works


public class Pet {

  private Long id;

  private String name;

  private JsonNullable<String> tag = JsonNullable.<String>undefined();

  public Pet() {
    super();
  }

So not sure what maven settings you are using

MelleD avatar Feb 15 '24 21:02 MelleD

@robertop87 not familiar with gradle but you have to use the spring generator and not the java generator. generatorName.set("java") looks wrong

I linked the documentation to the spring generator above

MelleD avatar Feb 15 '24 22:02 MelleD

@MelleD damn, that was the result of the cli generator I tested – and for some reason I had set it to the java generator as well but meant to test spring 🙈 Sorry...

tofi86 avatar Feb 15 '24 22:02 tofi86

Awesome. I got the expected behavior with the next changes (build.gradle).

https://github.com/robertop87/opengen/commit/540a8dd4f6e51f4b95eff452f63e32a10dc50a48

I'll double check if it's working as expected in a real project and I'll back to close this issue. Thank you.

robertop87 avatar Feb 16 '24 14:02 robertop87

Hello @MelleD ,

I just notice that using generatorName = spring, it's generating a full serve application, not just a java client.

In that context I think this is still a bug, I mean JsonNullable is not being generated for java client.

I updated my repo in this commit: https://github.com/robertop87/opengen/commit/b4077778561bdd0cc1adc8018d497065a38798f9

CC: @tofi86

robertop87 avatar Feb 16 '24 18:02 robertop87

@robertop87 Iam using the spring generator with open feign clients and there is no full application it’s DTO + clients. Iam not aware with the Java generator and which library the Java client is using (there is also more than library) see documentation . Not sure if every library generator supports JsonNullable because it’s depending on Jackson

Here are the templates for the Java client I see no JsonNullable https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator/src/main/resources/Java/pojo.mustache

MelleD avatar Feb 16 '24 19:02 MelleD

@MelleD

I understood, so in short:

currently openapi-generator does not support the generation of java client using JsonNullable<?> for "nullable: true" defined properties.

is that correct?

Update: In the provided link I saw the next lines where JsonNullable is present: image

But maybe I'm wrong because first time I read mustache code.

CC @tofi86

robertop87 avatar Feb 16 '24 19:02 robertop87

How I said iam not sure, iam not using this generator: https://openapi-generator.tech/docs/generators/java/

You see there are lot of library which you can select. Maybe one of this supports JsonNullable

Iam using this generator with spring and open feign. There it is supported. https://openapi-generator.tech/docs/generators/spring

You can generate client + dto/models with open feign without a entire application https://docs.spring.io/spring-cloud-openfeign/reference/index.html

MelleD avatar Feb 16 '24 19:02 MelleD

Just checked out the source code and made a small text search. Looks like there should be something in place for java...

Bildschirmfoto 2024-02-16 um 20 33 44

MelleD avatar Feb 16 '24 19:02 MelleD

@robertop87 I guess you're right. That's what I saw as well when accidentally using the java generator yesterday. No JsonNullable being generated - although openApiNullable is mentioned on the java generator docs page as being supported. Seems as if that's just not correct.

tofi86 avatar Feb 16 '24 19:02 tofi86

Sure I think you have to enable this vendor extension then it should work

  {{#vendorExtensions.x-is-jackson-optional-nullable}}
  {{#isContainer}}
  private JsonNullable<{{{datatypeWithEnum}}}> {{name}} = JsonNullable.<{{{datatypeWithEnum}}}>undefined();
  {{/isContainer}}
  {{^isContainer}}
  private JsonNullable<{{{datatypeWithEnum}}}> {{name}} = JsonNullable.<{{{datatypeWithEnum}}}>{{#defaultValue}}of({{{.}}}){{/defaultValue}}{{^defaultValue}}undefined(){{/defaultValue}};
  {{/isContainer}}
  {{/vendorExtensions.x-is-jackson-optional-nullable}}

Here: https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator/src/main/resources/Java/pojo.mustache#L86

But looks like this vendor extension is missing here in the documentation: https://openapi-generator.tech/docs/generators/java/

So this is maybe the bug here, that the docu is outdated.

MelleD avatar Feb 16 '24 19:02 MelleD

@MelleD thanks for your time, I'm trying to enable the extension in my swagger.yml and also in swagger.json files, for example:

image

But it looks like has no effect to generate the JsonNullable types, so maybe I'm doing something wrong.

I following this guide: https://docs.readme.com/main/docs/openapi-extensions

One question more, does the vendor extension needs to be declared somehow in params for openapi-generator?

robertop87 avatar Feb 16 '24 20:02 robertop87

I have no idea.

The x-field-extra-annotation is working. The jackson not

 tag:
          x-field-extra-annotation: "@javax.persistence.Id"

MelleD avatar Feb 16 '24 21:02 MelleD

Maybe you have to debug: https://github.com/OpenAPITools/openapi-generator/blob/master/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/AbstractJavaCodegen.java#L2475

MelleD avatar Feb 16 '24 22:02 MelleD

@MelleD

When debugging I noticed that JsonNullable is working fine, because the generator's library is configured as WEBCLIENT.

Additionally note: x-is-jackson-optional-nullable was not needed in the configuration.

So I configured my generator like this:

tasks.register('generateClient', GenerateTask) {
    generatorName.set("java")
    library.set("webclient") // only with webclient the JsonNullable is generated properly
    inputSpec.set(swaggerFile.toString())
    outputDir.set(swaggerOutputDir)
    configOptions.set([
            dateLibrary: "java8",
            useJakartaEe: "true",
            openApiNullable: "true" // This is enabled by default
    ])
}

As result the JsonNullable were generated properly.

But, I'll test a bit more in client side if it's working as expected.

robertop87 avatar Feb 17 '24 15:02 robertop87

Hello @MelleD I confirmed that the bug is only present when library configuration is: okhttp-gson or microprofile so I reported in a new issue https://github.com/OpenAPITools/openapi-generator/issues/17919

So I'm closing this issue. 17873

robertop87 avatar Feb 21 '24 18:02 robertop87