SJF4J is a lightweight JSON facade and high-performance structural processing layer for Java.
It sits above multiple JSON parsers β including Jackson, Gson, Fastjson2, and JSON-P β while also supporting YAML (via SnakeYAML) and Java Properties.
It provides a consistent programming model across parsers, data formats, and native Java object graphs, built on JSON-related standards and semantics.
It unifies modeling (OBNT), binding (Multi-Format), navigating (JSON Path), patching (JSON Patch), validating (JSON Schema), and mapping (Object-to-object) under one API model.
SJF4J requires JDK 8+, with no external dependencies beyond the data parsers you choose to add.
Gradle:
implementation("org.sjf4j:sjf4j:{version}")Maven:
<dependency>
<groupId>org.sjf4j</groupId>
<artifactId>sjf4j</artifactId>
<version>{version}</version>
</dependency>Optional Runtime Dependencies
Parsers are enabled automatically when their corresponding libraries are present, and can also be configured explicitly when needed.
-
JSON
- Include one of:
Jackson 3.x,Jackson 2.x,Gson,Fastjson2, orJSON-P(withParssonor others). - By default, SJF4J automatically detects and uses the first available implementation in that order.
- If none are detected, it falls back to a built-in simple JSON parser (functional but slower).
- Or configure the backend explicitly, for example:
Sjf4j.builder().jsonFacadeProvider(Jackson2JsonFacade.provider()).build();
- Include one of:
-
YAML
- Include
SnakeYAML(the YAML 1.1 backend). - YAML support requires SnakeYAML at runtime; unlike JSON, there is no built-in YAML parser fallback.
- Include
-
Java Properties
- Built-in support.
- Conversion is inherently limited by its flat key-value structure.
-
In-Memory
- Built-in support.
- Useful even without external data sources (e.g., DB result mapping, complex nested data processing).
Common runtime dependencies (pick as needed):
// Jackson 3
implementation("tools.jackson.core:jackson-databind:{jackson3-version}")
// Jackson 2
implementation("com.fasterxml.jackson.core:jackson-databind:{jackson2-version}")
// Gson
implementation("com.google.code.gson:gson:{gson-version}")
// Fastjson2
implementation("com.alibaba.fastjson2:fastjson2:{fastjson2-version}")
// JSON-P API + Parsson implementation
implementation("jakarta.json:jakarta.json-api:{jsonp-version}")
implementation("org.eclipse.parsson:parsson:{parsson-version}")
// YAML
implementation("org.yaml:snakeyaml:{snakeyaml-version}")Start with JsonObject when you want to parse JSON, access values directly,
and use JSON-semantic navigation and mutation APIs immediately.
JsonObject jo = JsonObject.fromJson(
"{" +
"\"name\":\"Alice\"," +
"\"age\":18," +
"\"scores\":{\"math\":59}" +
"}");
String name = jo.getString("name");
int age = jo.getInt("age");
int math = jo.getIntByPath("$.scores.math");
jo.putByPath("$.scores.art", 95);
System.out.println(jo.toJson());JsonObject is one of SJF4J's JSON object representations. Others include:
Map- Standard Java POJOs
- JOJOs (
JsonObject-based objects)
The following example demonstrates a complete lifecycle for processing structured data:
Modeling β Binding β Navigating β Patching β Validating β Mapping
A standard POJO works out of the box:
public class Student {
private String name;
private Map<String, Integer> scores;
private List<Student> friends;
// getters and setters
}Or, you can also extend JsonObject to create a JOJO, which supports additional dynamic properties while retaining typed fields.
public class StudentJojo extends JsonObject {
private String name;
private Map<String, Integer> scores;
private List<Student> friends;
// Getters and setters
}Learn more β Modeling (OBNT)
Use Sjf4j to bind JSON into Java objects.
String json = """
{
"name": "Alice",
"scores": {"math": 59, "art": 95},
"friends": [
{"name": "Bill", "active": true, "scores": {"math": 83}},
{"name": "Cindy", "friends": [{"name": "David", "scores": {"math": 95}}]}
],
"age": 18
}
""";
Student student = new Sjf4j().fromJson(json, Student.class);Once bound, SJF4J works directly on the Java object graph:
student.getName(); // Alice
student.getInt("age"); // 18Learn more β Binding (Multi-Format)
Navigate and mutate object graphs using JSON Path (RFC 9535) or JSON Pointer (RFC 6901).
JsonPath.parse("$.scores.math").getIntByPath(student);
// 59
JsonPath.parse("$..friends[?@.scores.math >= 90].name").findByPath(student, String.class);
// ["David"]
JsonPath.parse("/friends/0/scores/music").ensurePutByPath(student, 100);
// Bill's scores becomes: {"math": 83, "music": 100}JOJOs additionally provide shortcut methods:
studentJojo.getIntByPath("$.scores.math");
studentJojo.findByPath("$..friends[?@.scores.math >= 90].name", String.class);
studentJojo.ensurePutByPath("/friends/0/scores/music", 100);For performance-critical workloads, @CompiledPath can generate direct access code at compile time
and deliver near hand-written navigation performance.
@CompiledPath
interface StudentPath {
@GetByPath("$.scores.math")
int getScoresMath(Student student);
}Learn more β Navigating (JSON Path)
Apply standard-compliant structural updates using JSON Patch (RFC 6902).
JsonPatch patch = JsonPatch.fromJson("""
[
{ "op": "replace", "path": "/name", "value": "Alice Zhang" },
{ "op": "add", "path": "/scores/physics", "value": 91 }
]
""");
patch.apply(student);Changes are applied directly to the object graph:
student.getName();
// "Alice Zhang"
student.getScores().get("physics");
// 91SJF4J also supports JSON Merge Patch (RFC 7386) and Indexed Merge Patch, a convenient extension for partial array updates.
Learn more β Patching (JSON Patch)
SJF4J fully supports JSON Schema Draft 2020-12, 2019-09, and draft-07,
and can validate Java object graphs directly without first converting them into a dedicated JSON tree.
Example:
JsonSchema schema = JsonSchema.fromJson("""
{
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1
},
"scores": {
"type": "object",
"additionalProperties": {
"type": "integer",
"minimum": 0
}
}
},
"required": ["name"]
}
""");
SchemaPlan plan = schema.createPlan();
ValidationResult result = plan.validate(student);
boolean valid = result.isValid();You can also use @ValidJsonSchema for Bean Validation style integration.
@ValidJsonSchema("""
{
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1
},
"scores": {
"type": "object",
"additionalProperties": {
"type": "integer",
"minimum": 0
}
}
},
"required": ["name"]
}
""")
public class Student {
// ...
}Need Java models from a schema?
You can also use the online Schema-to-Java Generator to generate Java models directly from JSON Schema.
Learn more β Validating (JSON Schema)
Generate object mappers at compile time using @CompiledMapper.
@CompiledMapper
public interface StudentMapper {
@Mapping(target = "studentName", source = "name")
@Mapping(target = "totalScore", sources = "scores",
compute = "scores -> scores.values().stream().mapToInt(i -> i).sum()")
StudentDto toDto(Student student);
}Use it:
StudentMapper mapper = CompiledNodes.of(StudentMapper.class);
StudentDto studentDto = mapper.toDto(student);@CompiledMapper supports direct field mapping, JSON-style paths, computed fields, and nested mappings.
Learn more β Mapping (Object-to-object)
SJF4J is built around a unified structural model called the Object-Based Node Tree (OBNT).
- All structured data are mapped into OBNT.
- All nodes in OBNT are native Java objects rather than a dedicated AST.
- All APIs operate directly on those objects.
- All APIs follow or extend standard JSON semantics.
As a result, SJF4J can apply JSON-style operations directly to your existing Java object graph without first converting it into a dedicated JSON tree.
Learn more β Architecture
SJF4J combines a unified JSON-semantic programming model with top-tier performance across a wide range of workloads, as demonstrated by JMH benchmarks and independent third-party evaluations.
Reflection Access Benchmark
Lambda-based accessor generation minimizes reflection overhead,
delivering performance close to direct field or method invocation.
JSON Binding Benchmark
SJF4J operates on top of underlying JSON parsers while adding structural
capabilities and flexible binding annotations.
In most cases, the additional overhead remains modest compared to native
JSON libraries.
JSON Path Navigating Benchmark
JsonPath provides high-performance querying and mutation operations.
For performance-critical paths, @CompiledPath generates direct access code
and can be tens of times faster than interpreted path evaluation.
JSON Schema Validating Benchmark
SJF4J fully supports JSON Schema Draft 2020-12, 2019-09, and draft-07.
It consistently ranks among the top-performing Java implementations in
Creek Service
and Bowtie benchmarks.
Object-to-object Mapping Benchmark
@CompiledMapper delivers performance close to hand-written mapping code
and ranks among the fastest Java mapping frameworks in the Java Object Mapper Benchmark.
Learn more β Benchmarks
Contributions of all kinds are welcome β including code, documentation, bug reports,
examples, benchmarks, ideas, and feedback.
To get started, please open an issue.
JSON is one of the most widely used structured data formats today, backed by a mature ecosystem of standards, specifications, and RFCs.
Does Java need a JSON-oriented programming model?