Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] [JAVA] [webclient] addXYZ Builder Method in Pojo produces NullPointerException for nullable array properties #14583

Closed
5 tasks done
kzander91 opened this issue Feb 1, 2023 · 16 comments · Fixed by #14703

Comments

@kzander91
Copy link

kzander91 commented Feb 1, 2023

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?
Description

For nullable arrays, the POJO generated by 6.3.0 no longer initializes the property with an empty list when using the addXYZ(T item) builder method to add an item to the property. This produces a NullPointerException. With 6.2.1, if the JsonNullable didn't contain a value, it was initialized with a new ArrayList.

Generated builder method with 6.2.1:

public class TestObject {
  // other stuff

  private JsonNullable<List<String>> nullableArrayProp = JsonNullable.<List<String>>undefined();

  // other stuff

  public TestObject addNullableArrayPropItem(String nullableArrayPropItem) {
    if (this.nullableArrayProp == null || !this.nullableArrayProp.isPresent()) {
      this.nullableArrayProp = JsonNullable.<List<String>>of(new ArrayList<>()); // <-- initialized with empty list
    }
    try {
      this.nullableArrayProp.get().add(nullableArrayPropItem); // <-- no NPE here
    } catch (java.util.NoSuchElementException e) {
      // this can never happen, as we make sure above that the value is present
    }
    return this;
  }

  // other stuff
}

Generated builder method with 6.3.0:

public class TestObject {
  // other stuff

  private JsonNullable<List<String>> nullableArrayProp = JsonNullable.<List<String>>undefined();

  // other stuff

  public TestObject addNullableArrayPropItem(String nullableArrayPropItem) {
    if (this.nullableArrayProp == null || !this.nullableArrayProp.isPresent()) {
      this.nullableArrayProp = JsonNullable.<List<String>>of(null); // <-- initialized with null
    }
    try {
      this.nullableArrayProp.get().add(nullableArrayPropItem); // NPE here
    } catch (java.util.NoSuchElementException e) {
      // this can never happen, as we make sure above that the value is present
    }
    return this;
  }

  // other stuff
}
openapi-generator version

6.3.0 (no errors with 6.2.1)

OpenAPI declaration file content or url
openapi: 3.0.3
info:
    title: Title
    version: "1"
paths:
  /test:
    get:
      responses:
        200:
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TestObject'
components:
  schemas:
    TestObject:
      type: object
      properties:
        myNullableArrayProp:
          type: array
          nullable: true
          items:
            type: string
Generation Details

java -jar openapi-generator-cli-6.3.0.jar generate -g java --library webclient -i spec.yaml -o out

Steps to reproduce
  1. Model with attribute of type array and nullable: true.
  2. Generate with generator java and library webclient.
  3. TestObject#addMyNullableArrayPropItem initializes property value with null, causing a NullPointerException in the next statement.
Related issues/PRs

#14130

Suggest a fix

Check if the property's type is array, initialize it with an empty ArrayList, as before.

@kzander91 kzander91 changed the title [BUG] [JAVA] [webclient] addXYZ Builder Method in Pojo produces NullPointerException [BUG] [JAVA] [webclient] addXYZ Builder Method in Pojo produces NullPointerException for nullable array properties Feb 1, 2023
@wing328
Copy link
Member

wing328 commented Feb 1, 2023

can you set the option containerDefaultToNull to true to see if that works?

@kzander91
Copy link
Author

Both
java -jar openapi-generator-cli-6.3.0.jar generate -g java --library webclient --additional-properties=containerDefaultToNull=false -i spec.yaml -o out
and
java -jar openapi-generator-cli-6.3.0.jar generate -g java --library webclient --additional-properties=containerDefaultToNull=true -i spec.yaml -o out
produce identical output and don't fix this.

@wing328
Copy link
Member

wing328 commented Feb 1, 2023

what about setting nullable to false instead?

@kzander91
Copy link
Author

kzander91 commented Feb 1, 2023

With nullable: false and containerDefaultToNull=false, the NPE is fixed:

  public TestObject addMyNullableArrayPropItem(String myNullableArrayPropItem) {
    if (this.myNullableArrayProp == null) {
      this.myNullableArrayProp = new ArrayList<>();
    }
    this.myNullableArrayProp.add(myNullableArrayPropItem);
    return this;
  }

With nullable: false and containerDefaultToNull=true, it is not:

  public TestObject addMyNullableArrayPropItem(String myNullableArrayPropItem) {
    if (this.myNullableArrayProp == null) {
      this.myNullableArrayProp = null;
    }
    this.myNullableArrayProp.add(myNullableArrayPropItem);
    return this;
  }

For completeness, here's the other two permutations:
nullable: true, containerDefaultToNull=false:

  public TestObject addMyNullableArrayPropItem(String myNullableArrayPropItem) {
    if (this.myNullableArrayProp == null || !this.myNullableArrayProp.isPresent()) {
      this.myNullableArrayProp = JsonNullable.<List<String>>of(null);
    }
    try {
      this.myNullableArrayProp.get().add(myNullableArrayPropItem);
    } catch (java.util.NoSuchElementException e) {
      // this can never happen, as we make sure above that the value is present
    }
    return this;
  }

nullable: true, containerDefaultToNull=true (identical):

  public TestObject addMyNullableArrayPropItem(String myNullableArrayPropItem) {
    if (this.myNullableArrayProp == null || !this.myNullableArrayProp.isPresent()) {
      this.myNullableArrayProp = JsonNullable.<List<String>>of(null);
    }
    try {
      this.myNullableArrayProp.get().add(myNullableArrayPropItem);
    } catch (java.util.NoSuchElementException e) {
      // this can never happen, as we make sure above that the value is present
    }
    return this;
  }

@wing328
Copy link
Member

wing328 commented Feb 1, 2023

thanks for the info. i'll try to come up with a PR to address it this or next week.

@wing328
Copy link
Member

wing328 commented Feb 2, 2023

We want to use nullable to determine whether we should use null (nullable: true) or empty array/maps/set (nullable: false).

@tofi86
Copy link

tofi86 commented Feb 9, 2023

Also happens for the JavaSpring generator.

@MelleD
Copy link
Contributor

MelleD commented Feb 14, 2023

@wing328 do you know why this changes from a empty collection to a null value? Make this sense into a JsonNullable?

For us the empty collection (List or Set) was fine and works.

@wing328
Copy link
Member

wing328 commented Feb 15, 2023

Hi all,

I've file a fix: #14703. Please test it when you've time to confirm it addresses the issues in your use cases.

Thank you.

@kzander91
Copy link
Author

@wing328: The SNAPSHOT jar produces identical output and thus doesn't fix the issue.
I tried all four scenarios from my previous comment.

@wing328
Copy link
Member

wing328 commented Feb 17, 2023

Can you try https://oss.sonatype.org/content/repositories/snapshots/org/openapitools/openapi-generator-cli/6.4.0-SNAPSHOT/openapi-generator-cli-6.4.0-20230216.072505-21.jar instead ? (6.4.0-SNAPSHOT JAR)

Sorry that the one I provided earlier was for v6.3.0 (which was released already).

@kzander91
Copy link
Author

kzander91 commented Feb 17, 2023

The new snapshot fixed the issue for the example spec. Give me a bit more time to verify that with my actual application.

@wing328
Copy link
Member

wing328 commented Feb 17, 2023

Please run more tests 🙏

@kzander91
Copy link
Author

kzander91 commented Feb 17, 2023

@wing328: I successfully tested the snapshot with my actual application, so this fix works for me, thanks for the fix.

@VinceGall
Copy link

Same issue

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

Successfully merging a pull request may close this issue.

5 participants