AtomicIntegerArray deserializer crashes on JSON null (IllegalStateException) — symmetric fix to #3038
- Dominant language
- Java
- Stars
- 24.2k
- Forks
- 4.5k
- Avg merge
- 6d 4h
- Merged PRs (30d)
- 12
Description
## Bug
Deserializing a JSON array that contains a `null` element into an `AtomicIntegerArray` crashes with an uncaught `IllegalStateException`:
```java
new Gson().fromJson("[1,null,3]", AtomicIntegerArray.class);
// throws IllegalStateException: Expected an int but was NULL at line 1 column 4 path $[1]
```
## Root cause
In `TypeAdapters.java`, the `ATOMIC_INTEGER_ARRAY` adapter's `read()` method calls `in.nextInt()` inside a loop that only catches `NumberFormatException`:
```java
public AtomicIntegerArray read(JsonReader in) throws IOException {
List list = new ArrayList<>();
in.beginArray();
while (in.hasNext()) {
try {
int integer = in.nextInt();
list.add(integer);
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
}
}
in.endArray();
...
}
```
When the `JsonReader` is positioned at a `NULL` token, `nextInt()` throws `IllegalStateException` — which is **not** caught here, so it propagates raw instead of being converted to a `JsonSyntaxException`.
## Relationship to #3038
PR #3038 (merged 2026-06-22) fixed the symmetric issue in `AtomicLongArray`. That adapter delegates to `longAdapter.read(in)`, which returns `null` for a JSON null; the fix added an explicit null-check:
```java
Number value = longAdapter.read(in);
if (value == null) {
throw new JsonSyntaxException("null is not a valid AtomicLongArray element");
}
list.add(value.longValue());
```
`AtomicIntegerArray` was not updated with the same treatment.
## Expected behaviour
A JSON null element inside an `AtomicIntegerArray` should throw a `JsonSyntaxException` (same as `AtomicLongArray` after #3038), not a raw `IllegalStateException`.
## Suggested fix
Mirror the approach used in the `AtomicLongArray` adapter — either:
**Option A** — peek before reading:
```java
while (in.hasNext()) {
try {
if (in.peek() == com.google.gson.stream.JsonToken.NULL) {
throw new JsonSyntaxException("null is not a valid AtomicIntegerArray element");
}
int integer = in.nextInt();
list.add(integer);
} catch (NumberFormatException e) {
throw new JsonSyntaxException(e);
}
}
```
**Option B** — delegate to `INTEGER` type adapter (returns `null` for JSON null, already handles this safely) and add a null-check, consistent with the `AtomicLongArray` pattern.
A regression test analogous to the one added in #3038 for `AtomicLongArray` should also be added.
## Environment
- Gson latest main branch (after #3038 merge)
- Reproducible with any Gson version where `AtomicIntegerArray` deserialization is supported
Contributor guide
Research direction
Start in TypeAdapters.java by comparing the ATOMIC_INTEGER_ARRAY adapter with the AtomicLongArray change from PR #3038. Run the existing AtomicLongArray regression test as a guide, add an analogous test for a null element in AtomicIntegerArray, and confirm it produces JsonSyntaxException rather than IllegalStateException.
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
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 88/100