Skip to content

ArrayDeserializer.acceptedEvents() returns incorrect EventsSets when use concurrently #402

Closed
@ClaasWilke

Description

@ClaasWilke

Java API client version

8.4.1

Java version

Azul Zulu 17.0.1

Elasticsearch Version

8.4.1

Problem description

The JsonbDeserializerBase.ArrayDeserializer.acceptedEvents() Method returns a lazily initialized Set of accepted Events which can be initialized only partially when called concurrently:

public EnumSet<Event> acceptedEvents() {
    // Accepted events is computed lazily
    // no need for double-checked lock, we don't care about computing it several times
    if (acceptedEvents == null) {
        acceptedEvents = EnumSet.of(Event.START_ARRAY);
        acceptedEvents.addAll(itemDeserializer.acceptedEvents());
    }
    return acceptedEvents;
}

In our case, a concurrent caller called the methode between the execution of the statements acceptedEvents = EnumSet.of(Event.START_ARRAY); and acceptedEvents.addAll(itemDeserializer.acceptedEvents());, which led to a Set containing only the START_ARRAY event and a very confusing Parsing error:

Error deserializing co.elastic.clients.elasticsearch._types.analysis.StandardAnalyzer: co.elastic.clients.json.UnexpectedJsonEventException: Unexpected JSON event 'VALUE_STRING' instead of '[START_ARRAY, KEY_NAME, VALUE_STRING, VALUE_NUMBER, VALUE_TRUE, VALUE_FALSE]'

Solution: the acceptedEvents Set should be initialized completely before assigned to the acceptedEvents field, to avoid the returning of partially initialized sets in concurrent method calls:

if (acceptedEvents == null) {
    EnumSet<Event> events = EnumSet.of(Event.START_ARRAY);
    events.addAll(itemDeserializer.acceptedEvents());
    acceptedEvents = events;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions