Skip to content

iamdudeman/sola-json

Repository files navigation

sola-json

SolaJson is a lightweight JSON parsing library for Java 17+ that uses no additional libraries internally. It started as a project to continue learning about building parsers based on language grammars.

Java CI Javadocs Link

Parser definition based on json.org

Download

Gradle + Jitpack:

repositories {
    maven {
        url = uri("https://jitpack.io")
    }
}

dependencies {
    implementation("com.github.iamdudeman:sola-json:2.1.3")
}

sola-json jar downloads hosted on GitHub releases.

Example usages

Basic Usage

public class BasicUsage {
    public static void main(String[] args) {
        String jsonString = """
            {
              "key": "value"
            }
            """;
        SolaJson solaJson = new SolaJson();
        JsonObject root = solaJson.parse(jsonString).asObject();
        System.out.println(root.getString("key"));

        root.put("key2", 10);
        System.out.println(solaJson.stringify(root));
    }
}
# Output
value
{"key":"value","key2":10}

Usage with JsonMapper

public class JsonMapperUsage {
    public static void main(String[] args) {
        String input = """
            {
              "value": 1
            }
            """;
        SolaJson solaJson = new SolaJson();
        Pojo result = solaJson.parse(input, JSON_MAPPER);
        System.out.println(result.value());

        Pojo pojo = new Pojo(10);
        System.out.println(solaJson.stringify(pojo, JSON_MAPPER));
    }

    public record Pojo(int value) {
    }

    static JsonMapper<Pojo> JSON_MAPPER = new JsonMapper<>() {
        @Override
        public JsonObject toJson(Pojo object) {
            JsonObject jsonObject = new JsonObject();

            jsonObject.put("value", object.value());

            return jsonObject;
        }

        @Override
        public TestPojo toObject(JsonObject jsonObject) {
            return new Pojo(jsonObject.getInt("value"));
        }
    };
}
# Output
1
{"value":1}

Grammar

Terminals

COLON      := :
COMMA      := ,
FALSE      := false
L_BRACKET  := [
L_CURLY    := {
NULL       := null
NUMBER     := ((-[1-9])|0)[0-9]+(.[0-9]+)?([eE][-+]?[0-9]+)
R_BRACKET  := ]
R_CURLY    := }
STRING     := " (Any codepoint except " or \ or control characters) "
TRUE       := true

Rules

<root>    := <object> | <array>
<object>  := L_CURLY (<pair> (COMMA <pair>)*)? R_BRACKET
<array>   := L_BRACKET (<value> (COMMA <value>)*)? R_BRACKET
<pair>    := STRING COLON <value>
<value>   := STRING | NUMBER | <object> | <array> | TRUE | FALSE | NULL

Testing

Validity

Used test files from JSON.org to verify parsers functionality.

Performance

Used data from JSON placeholder (small files) and San Francisco data (big file) for performance testing.

Benchmarked against Google gson and Jackson.

jmh benchmark file can be viewed here

Execute benchmark view gradle task jmhBenchmark in verification category.

Results:

Benchmark                                  Mode  Cnt   Score   Error  Units
SolaJsonBenchmark.gsonBig                    ss   50  21.239 ± 2.119  ms/op
SolaJsonBenchmark.gsonSmall                  ss   50   3.238 ± 0.234  ms/op
SolaJsonBenchmark.jacksonBig                 ss   50  16.775 ± 1.209  ms/op
SolaJsonBenchmark.jacksonSmall               ss   50   3.436 ± 0.438  ms/op
SolaJsonBenchmark.solaJsonBig                ss   50  26.956 ± 1.810  ms/op
SolaJsonBenchmark.solaJsonBigTokenizeOnly    ss   50  17.729 ± 0.857  ms/op
SolaJsonBenchmark.solaJsonSmall              ss   50   5.865 ± 0.296  ms/op

About

A lightweight, zero-dependency JSON parser for Java

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages