Skip to content

AtomicIntegerArray deserializer crashes on JSON null (IllegalStateException) — symmetric fix to #3038 #3047

Description

@mahirhir

Bug

Deserializing a JSON array that contains a null element into an AtomicIntegerArray crashes with an uncaught IllegalStateException:

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:

public AtomicIntegerArray read(JsonReader in) throws IOException {
  List<Integer> 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:

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:

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions