Actson: a reactive (or non-blocking, or asynchronous) JSON parser

Datetime:2016-08-22 23:01:22          Topic:          Share

Today I’m happy to announce the very first version of Actson, a reactive JSON parser (sometimes referred to as non-blocking or asynchronous). Actson is event-based and can be used together with reactive libraries/tool-kits such as RxJava or Vert.x . The library is very small and has no dependencies. It only requires Java 7 (or higher).

Download the Actson binaries from http://search.maven.org or the source code from the GitHub repository . Actson is released under the MIT license .

Why another JSON parser?

  • Non-blocking. Other JSON parsers use blocking I/O (i.e. they read from an InputStream ). If you want to develop a reactive application you should use non-blocking I/O (see the Reactive Manifesto ).
  • Big Data. Most parsers read the full JSON text into memory to map it to a POJO, for example. Actson can handle arbitrarily large JSON text. It is event-based and can be used for streaming.
  • GeoRocket. Actson was primarily developed for GeoRocket , a high-performance reactive data store for geospatial files. We use Aalto XML to parse XML in a non-blocking way and we needed something similar for GeoRocket’s GeoJSON support.

Usage

The JSON parser gets its input data from a feeder. Actson uses a push-pull approach: push data into the feeder until it is full. Then call the parser until it wants more data. Repeat this process until the whole JSON text has been parsed.

The following snippet demonstrates how you can use the parser sequentially.

// JSON text to parse
byte[] json = "{\"name\":\"Elvis\"}".getBytes(StandardCharsets.UTF_8);

JsonParser parser = new JsonParser(StandardCharsets.UTF_8);

int pos = 0; // position in the input JSON text
int event; // event returned by the parser
do {
    // proceed until the parser returns a new event or until it needs more input
    while ((event = parser.nextEvent()) == JsonEvent.NEED_MORE_INPUT) {
        // provide the parser with more input
        pos += parser.getFeeder().feed(json, pos, json.length - pos);

        // indicate end of input to the parser
        if (pos == json.length) {
            parser.getFeeder().done();
        }
    }

    // handle event
    System.out.println("JSON event: " + event);
    if (event == JsonEvent.ERROR) {
        throw new IllegalStateException("Syntax error in JSON text");
    }
} while (event != JsonEvent.EOF);

Reactive, non-blocking examples

Find more complex and elaborate usage examples in the GitHub repository .

Similar libraries

  • Jackson has a streaming API that produces JSON tokens/events. However, it uses blocking I/O because it reads from an InputStream .
  • Aalto XML is similar to Actson but parses XML instead of JSON.

Acknowledgments

The event-based parser code and the JSON files used for testing are largely based on the file JSON_checker.c and the JSON test suite from JSON.org originally released under this license (basically MIT license).