Skip to content

Fix NPE thrown from serializing/deserializing a structure that has map type with null values #3138

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

Merged
merged 3 commits into from
Mar 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changes/next-release/bugfix-AWSSDKforJavav2-edfb037.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"category": "AWS SDK for Java v2",
"contributor": "",
"type": "bugfix",
"description": "Fix NPE thrown from serializing/deserializing a structure that has map type with null values"
}
Original file line number Diff line number Diff line change
Expand Up @@ -245,12 +245,14 @@ private String copyMethodBody(CodeBlock.Builder code, BuilderTransform builderTr
case BUILDER_TO_BUILDABLE:
String buildableOutput = variableSource.getNew("member");
TypeName buildableOutputType = typeName(inputMember, false, false, builderTransform, enumTransform);
code.add("$T $N = $N.build();", buildableOutputType, buildableOutput, inputVariableName);
code.add("$T $N = $N == null ? null : $N.build();", buildableOutputType, buildableOutput, inputVariableName,
inputVariableName);
return buildableOutput;
case BUILDABLE_TO_BUILDER:
String builderOutput = variableSource.getNew("member");
TypeName builderOutputType = typeName(inputMember, false, false, builderTransform, enumTransform);
code.add("$T $N = $N.toBuilder();", builderOutputType, builderOutput, inputVariableName);
code.add("$T $N = $N == null ? null : $N.toBuilder();", builderOutputType, builderOutput, inputVariableName,
inputVariableName);
return builderOutput;
default:
throw new IllegalStateException();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ static List<Map<String, SimpleStruct>> copyFromBuilder(
} else {
Map<String, SimpleStruct> modifiableMap = new LinkedHashMap<>();
entry.forEach((key, value) -> {
SimpleStruct member = value.build();
SimpleStruct member = value == null ? null : value.build();
modifiableMap.put(key, member);
});
map = Collections.unmodifiableMap(modifiableMap);
Expand All @@ -81,7 +81,7 @@ static List<Map<String, SimpleStruct.Builder>> copyToBuilder(
} else {
Map<String, SimpleStruct.Builder> modifiableMap = new LinkedHashMap<>();
entry.forEach((key, value) -> {
SimpleStruct.Builder member = value.toBuilder();
SimpleStruct.Builder member = value == null ? null : value.toBuilder();
modifiableMap.put(key, member);
});
map = Collections.unmodifiableMap(modifiableMap);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ static List<SimpleStruct> copyFromBuilder(Collection<? extends SimpleStruct.Buil
} else {
List<SimpleStruct> modifiableList = new ArrayList<>();
listOfSimpleStructsParam.forEach(entry -> {
SimpleStruct member = entry.build();
SimpleStruct member = entry == null ? null : entry.build();
modifiableList.add(member);
});
list = Collections.unmodifiableList(modifiableList);
Expand All @@ -48,7 +48,7 @@ static List<SimpleStruct.Builder> copyToBuilder(Collection<? extends SimpleStruc
} else {
List<SimpleStruct.Builder> modifiableList = new ArrayList<>();
listOfSimpleStructsParam.forEach(entry -> {
SimpleStruct.Builder member = entry.toBuilder();
SimpleStruct.Builder member = entry == null ? null : entry.toBuilder();
modifiableList.add(member);
});
list = Collections.unmodifiableList(modifiableList);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ static Map<String, SimpleStruct> copyFromBuilder(Map<String, ? extends SimpleStr
} else {
Map<String, SimpleStruct> modifiableMap = new LinkedHashMap<>();
mapOfEnumToSimpleStructParam.forEach((key, value) -> {
SimpleStruct member = value.build();
SimpleStruct member = value == null ? null : value.build();
modifiableMap.put(key, member);
});
map = Collections.unmodifiableMap(modifiableMap);
Expand All @@ -47,7 +47,7 @@ static Map<String, SimpleStruct.Builder> copyToBuilder(Map<String, ? extends Sim
} else {
Map<String, SimpleStruct.Builder> modifiableMap = new LinkedHashMap<>();
mapOfEnumToSimpleStructParam.forEach((key, value) -> {
SimpleStruct.Builder member = value.toBuilder();
SimpleStruct.Builder member = value == null ? null : value.toBuilder();
modifiableMap.put(key, member);
});
map = Collections.unmodifiableMap(modifiableMap);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ static Map<String, SimpleStruct> copyFromBuilder(Map<String, ? extends SimpleStr
} else {
Map<String, SimpleStruct> modifiableMap = new LinkedHashMap<>();
mapOfStringToSimpleStructParam.forEach((key, value) -> {
SimpleStruct member = value.build();
SimpleStruct member = value == null ? null : value.build();
modifiableMap.put(key, member);
});
map = Collections.unmodifiableMap(modifiableMap);
Expand All @@ -47,7 +47,7 @@ static Map<String, SimpleStruct.Builder> copyToBuilder(Map<String, ? extends Sim
} else {
Map<String, SimpleStruct.Builder> modifiableMap = new LinkedHashMap<>();
mapOfStringToSimpleStructParam.forEach((key, value) -> {
SimpleStruct.Builder member = value.toBuilder();
SimpleStruct.Builder member = value == null ? null : value.toBuilder();
modifiableMap.put(key, member);
});
map = Collections.unmodifiableMap(modifiableMap);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ static List<RecursiveStructType> copyFromBuilder(Collection<? extends RecursiveS
} else {
List<RecursiveStructType> modifiableList = new ArrayList<>();
recursiveListTypeParam.forEach(entry -> {
RecursiveStructType member = entry.build();
RecursiveStructType member = entry == null ? null : entry.build();
modifiableList.add(member);
});
list = Collections.unmodifiableList(modifiableList);
Expand All @@ -48,7 +48,7 @@ static List<RecursiveStructType.Builder> copyToBuilder(Collection<? extends Recu
} else {
List<RecursiveStructType.Builder> modifiableList = new ArrayList<>();
recursiveListTypeParam.forEach(entry -> {
RecursiveStructType.Builder member = entry.toBuilder();
RecursiveStructType.Builder member = entry == null ? null : entry.toBuilder();
modifiableList.add(member);
});
list = Collections.unmodifiableList(modifiableList);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ static Map<String, RecursiveStructType> copyFromBuilder(
} else {
Map<String, RecursiveStructType> modifiableMap = new LinkedHashMap<>();
recursiveMapTypeParam.forEach((key, value) -> {
RecursiveStructType member = value.build();
RecursiveStructType member = value == null ? null : value.build();
modifiableMap.put(key, member);
});
map = Collections.unmodifiableMap(modifiableMap);
Expand All @@ -48,7 +48,7 @@ static Map<String, RecursiveStructType.Builder> copyToBuilder(Map<String, ? exte
} else {
Map<String, RecursiveStructType.Builder> modifiableMap = new LinkedHashMap<>();
recursiveMapTypeParam.forEach((key, value) -> {
RecursiveStructType.Builder member = value.toBuilder();
RecursiveStructType.Builder member = value == null ? null : value.toBuilder();
modifiableMap.put(key, member);
});
map = Collections.unmodifiableMap(modifiableMap);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.io.IOException;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;
import org.junit.jupiter.api.Test;
import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.services.protocolrestjson.model.AllTypesRequest;
Expand All @@ -48,6 +50,14 @@ public void jacksonSerializationWorksForEmptyRequestObjects() throws IOException
validateJacksonSerialization(AllTypesRequest.builder().build());
}

@Test
public void jacksonSerialization_mapWithNullValue_shouldWork() throws IOException {
Map<String, SimpleStruct> mapOfStringToStruct = new HashMap<>();
mapOfStringToStruct.put("test1", null);
mapOfStringToStruct.put("test2", null);
validateJacksonSerialization(AllTypesRequest.builder().mapOfStringToStruct(mapOfStringToStruct).build());
}

@Test
public void jacksonSerializationWorksForPopulatedRequestModels() throws IOException {
SdkBytes blob = SdkBytes.fromUtf8String("foo");
Expand Down