aws / aws/aws-sdk-java-v2

TableSchema.fromImmutableClass() introspection fails when the item class has fields starting with "is"

Open
#4,446 6 comments 4 reactions 0 assignees View on GitHub
bug dynamodb-enhanced p2
Dominant language
Java
Stars
2.6k
Forks
1k
Avg merge
2d 9h
Merged PRs (30d)
51

Description

### Describe the bug

When an immutable item class has fields that begin with "is" (e.g., "isComplete" or "isIncluded"), `TableSchema.fromImmutableClass()` throws an `ExceptionInInitializerError`. Also in stack traces this appears: `Caused by: java.lang.IllegalArgumentException: A method was found on the immutable class that does not appear to have a matching setter on the builder class. Use the @DynamoDbIgnore annotation on the method if you do not want it to be included in the TableSchema introspection`, despite no methods except getters being present in the item class, and a setter for the field actually being present for the corresponding builder class.

The `TableSchema.fromImmutableClass()` method needs to work for item class fields no matter the composition of their names. Or, the documentation needs to be updated with correct restrictions on field naming based on the behavior of [`ImmutableInstrospector`](https://github.com/aws/aws-sdk-java-v2/blob/584ccb59e770177aeaa4c3b6bda4e24015b8ece9/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/immutable/ImmutableIntrospector.java).

### Expected Behavior

TableSchema.fromImmutableClass(itemClass) should return a proper `DynamoDbTable` when called on an itemClass containing any field name, without restriction.

### Current Behavior

Errors were thrown (see description).

### Reproduction Steps

```
@DynamoDbImmutable(builder = Car.Builder.class)
public final class Car {
private final String licensePlate;
private final boolean isRusty;
private final boolean isImpounded;

private Car(final Builder b) {
this.licensePlate = b.licensePlate;
this.isRusty = b.isRusty;
this.isImpounded = b.isImpounded;
}

public static Builder builder() {
return new Builder();
}

@DynamoDbPartitionKey
public String licensePlate() {
return this.licensePlate;
}

public boolean isRusty() {
return this.isRusty;
}

public boolean isImpounded() {
return this.isImpounded;
}

public static final class Builder {
private String licensePlate;
private boolean isRusty;
private boolean isImpounded;

private Builder() {
}

public Builder licensePlate(final String licensePlate) {
this.licensePlate = licensePlate;
return this;
}

public Builder isRusty(final boolean isRusty) {
this.isRusty = isRusty;
return this;
}

public Builder isImpounded(final boolean isImpounded) {
this.isImpounded = isImpounded;
return this;
}

public Car build() {
return new Car(this);
}
}
}
```

Calling `TableSchema.fromImmutableClass(Car.class)` and subsequently calling table operations on the resulting table will result in errors described above.

### Possible Solution

The behavior of the [ImmutableIntrospector](https://github.com/aws/aws-sdk-java-v2/blob/584ccb59e770177aeaa4c3b6bda4e24015b8ece9/services-custom/dynamodb-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/internal/immutable/ImmutableIntrospector.java) and how it parses method names is likely at large.

### Additional Information/Context

_No response_

### AWS Java SDK version used

2.20

### JDK version used

openjdk version "17.0.8" 2023-07-18 LTS OpenJDK Runtime Environment Corretto-17.0.8.7.1 (build 17.0.8+7-LTS) OpenJDK 64-Bit Server VM Corretto-17.0.8.7.1 (build 17.0.8+7-LTS, mixed mode, sharing)

### Operating System and version

MacOS, Amazon Linux 2

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.