Common: Fix NPE when binding AlwaysNull field in DynFields
- Dominant language
- Java
- Stars
- 9.2k
- Forks
- 3.5k
- Avg merge
- 2d 11h
- Merged PRs (30d)
- 132
Description
**Apache Iceberg version**
main @ 035fc1e40
**Query engine**
N/A — engine-agnostic, in `common/`
**Please describe the bug**
`DynFields.Builder.build(target)` / `.buildChecked(target)` throws a `NullPointerException` instead of returning a field bound to `null`, when `defaultAlwaysNull()` is set and no matching field is found.
`DynFields.AlwaysNull` (`common/src/main/java/org/apache/iceberg/common/DynFields.java` line 120-149) is a singleton constructed with a `null` `Field` (`super(null, "AlwaysNull")`, line 124). It does not override `bind(Object)`, so calls fall through to the parent `UnboundField.bind()` (line 86-96), which dereferences the null field via `field.getDeclaringClass()` (line 90).
The sibling class `DynMethods.UnboundMethod.NOOP` (`DynMethods.java` line 134-137) already avoids this exact problem by overriding `bind()` to return `new BoundMethod(this, receiver)` directly, without touching the null `method` field.
**Steps to reproduce**
```java
DynFields.builder().defaultAlwaysNull().build(new Object());
```
Expected: returns a `BoundField` whose `get()` returns `null` (per `defaultAlwaysNull()`'s contract).
Actual: `NullPointerException: Cannot invoke "java.lang.reflect.Field.getDeclaringClass()" because "this.field" is null` at `DynFields.java:90`.
**Additional context**
Reproduced by running against the compiled `common` module (same failure via `buildChecked(target)`).
Contributor guide
Research direction
Start in common/src/main/java/org/apache/iceberg/common/DynFields.java, focusing on AlwaysNull and UnboundField.bind(), then compare DynMethods.UnboundMethod.NOOP. Reproduce with DynFields.builder().defaultAlwaysNull().build(new Object()); done when it returns a BoundField whose get() returns null, including for buildChecked(target).
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 82/100