diff --git a/CHANGELOG.md b/CHANGELOG.md
index f85eaecf78..75a4cdc859 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -23,6 +23,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- Add document lifecycle guide and runnable sample ([#2017](https://github.com/opensearch-project/opensearch-java/pull/2017))
### Fixed
+- Fix `NullPointerException` in `_listAddAll` when server returns JSON `null` for a list field ([#2041](https://github.com/opensearch-project/opensearch-java/pull/2041))
## [Unreleased 3.x]
### Added
diff --git a/java-client/src/generated/java/org/opensearch/client/opensearch/core/search/ShardProfile.java b/java-client/src/generated/java/org/opensearch/client/opensearch/core/search/ShardProfile.java
index 8640b1d2d6..15085ab581 100644
--- a/java-client/src/generated/java/org/opensearch/client/opensearch/core/search/ShardProfile.java
+++ b/java-client/src/generated/java/org/opensearch/client/opensearch/core/search/ShardProfile.java
@@ -64,8 +64,8 @@ public class ShardProfile implements PlainJsonSerializable, ToCopyableBuilder aggregations;
- @Nullable
- private final FetchProfile fetch;
+ @Nonnull
+ private final List fetch;
@Nonnull
private final String id;
@@ -77,7 +77,7 @@ public class ShardProfile implements PlainJsonSerializable, ToCopyableBuilder aggregations() {
/**
* API name: {@code fetch}
*/
- @Nullable
- public final FetchProfile fetch() {
+ @Nonnull
+ public final List fetch() {
return this.fetch;
}
@@ -136,9 +136,13 @@ protected void serializeInternal(JsonGenerator generator, JsonpMapper mapper) {
}
generator.writeEnd();
- if (this.fetch != null) {
+ if (ApiTypeHelper.isDefined(this.fetch)) {
generator.writeKey("fetch");
- this.fetch.serialize(generator, mapper);
+ generator.writeStartArray();
+ for (FetchProfile item0 : this.fetch) {
+ item0.serialize(generator, mapper);
+ }
+ generator.writeEnd();
}
generator.writeKey("id");
@@ -171,7 +175,7 @@ public static Builder builder() {
public static class Builder extends ObjectBuilderBase implements CopyableBuilder {
private List aggregations;
@Nullable
- private FetchProfile fetch;
+ private List fetch;
private String id;
private List searches;
@@ -179,14 +183,14 @@ public Builder() {}
private Builder(ShardProfile o) {
this.aggregations = _listCopy(o.aggregations);
- this.fetch = o.fetch;
+ this.fetch = _listCopy(o.fetch);
this.id = o.id;
this.searches = _listCopy(o.searches);
}
private Builder(Builder o) {
this.aggregations = _listCopy(o.aggregations);
- this.fetch = o.fetch;
+ this.fetch = _listCopy(o.fetch);
this.id = o.id;
this.searches = _listCopy(o.searches);
}
@@ -237,15 +241,36 @@ public final Builder aggregations(Function
+ * Adds all elements of list to fetch.
+ *
+ */
+ @Nonnull
+ public final Builder fetch(List list) {
+ this.fetch = _listAddAll(this.fetch, list);
+ return this;
+ }
+
+ /**
+ * API name: {@code fetch}
+ *
+ *
+ * Adds one or more values to fetch.
+ *
*/
@Nonnull
- public final Builder fetch(@Nullable FetchProfile value) {
- this.fetch = value;
+ public final Builder fetch(FetchProfile value, FetchProfile... values) {
+ this.fetch = _listAdd(this.fetch, value, values);
return this;
}
/**
* API name: {@code fetch}
+ *
+ *
+ * Adds a value to fetch using a builder lambda.
+ *
*/
@Nonnull
public final Builder fetch(Function> fn) {
@@ -325,7 +350,7 @@ public ShardProfile build() {
protected static void setupShardProfileDeserializer(ObjectDeserializer op) {
op.add(Builder::aggregations, JsonpDeserializer.arrayDeserializer(AggregationProfile._DESERIALIZER), "aggregations");
- op.add(Builder::fetch, FetchProfile._DESERIALIZER, "fetch");
+ op.add(Builder::fetch, JsonpDeserializer.arrayDeserializer(FetchProfile._DESERIALIZER), "fetch");
op.add(Builder::id, JsonpDeserializer.stringDeserializer(), "id");
op.add(Builder::searches, JsonpDeserializer.arrayDeserializer(SearchProfile._DESERIALIZER), "searches");
}
diff --git a/java-client/src/main/java/org/opensearch/client/util/ObjectBuilderBase.java b/java-client/src/main/java/org/opensearch/client/util/ObjectBuilderBase.java
index e1aa0627c9..524b478148 100644
--- a/java-client/src/main/java/org/opensearch/client/util/ObjectBuilderBase.java
+++ b/java-client/src/main/java/org/opensearch/client/util/ObjectBuilderBase.java
@@ -95,10 +95,15 @@ protected static List _listAdd(List list, T value, T... values) {
/** Add all elements of a list to a (possibly {@code null}) list */
protected static List _listAddAll(List list, List values) {
+ if (values == null) {
+ // Server returned JSON null for a list field; treat as empty to avoid NPE.
+ // See https://github.com/opensearch-project/opensearch-java/issues/1813
+ return list;
+ }
if (list == null) {
// Keep the original list to avoid an unnecessary copy.
// It will be copied if we add more values.
- return Objects.requireNonNull(values);
+ return values;
} else {
list = _mutableList(list);
list.addAll(values);
diff --git a/java-codegen/opensearch-openapi.yaml b/java-codegen/opensearch-openapi.yaml
index b4829f72a0..468f21a1c0 100644
--- a/java-codegen/opensearch-openapi.yaml
+++ b/java-codegen/opensearch-openapi.yaml
@@ -52512,7 +52512,9 @@ components:
items:
$ref: '#/components/schemas/_core.search___SearchProfile'
fetch:
- $ref: '#/components/schemas/_core.search___FetchProfile'
+ type: array
+ items:
+ $ref: '#/components/schemas/_core.search___FetchProfile'
required:
- aggregations
- id