Introduction
JSON (JavaScript Object Notation) has become the de facto standard for data interchange in modern software development. From REST APIs to configuration files, JSON is everywhere. Yet, for years, Java developers have had to rely on third-party libraries like Jackson, Gson, or JSON-B to parse and generate JSON. While these libraries are powerful, they introduce external dependencies, version conflicts, and learning curves. The Java community has long awaited a native, lightweight solution.
In July 2026, the OpenJDK project took a significant step forward by releasing JEP 540: Simple JSON API as an incubator module. This proposal, now available for preview in JDK 24, aims to provide a standard, minimal JSON parsing and generation API directly in the JDK. The goal is not to replace full-featured libraries but to offer a simple, zero-dependency alternative for common use cases.
This article delves into the details of JEP 540, explores its design principles, and provides practical examples. We will analyze how this new API can simplify your codebase, reduce build complexity, and improve maintainability. Whether you are a seasoned Java architect or a junior developer, understanding this JEP is crucial for staying ahead in the evolving Java ecosystem.
What is JEP 540?
JEP 540, officially titled "Simple JSON API," is a proposal to introduce a minimal JSON API into the Java Development Kit (JDK). It is currently in the incubator stage, meaning it is not yet a permanent part of the platform. Incubator modules allow developers to test and provide feedback on experimental features before they are finalized.
The API is designed around three core principles:
1. Simplicity: It provides only the essential operations for parsing and generating JSON.
2. Immutability: Parsed JSON objects are immutable by default, promoting thread safety.
3. No dependencies: The API relies solely on the JDK, eliminating the need for external libraries for basic JSON tasks.
According to the official JEP description, the API targets use cases such as processing simple JSON data from web services, reading configuration files, or generating JSON for logging. It intentionally avoids advanced features like data binding, streaming, or schema validation, leaving those to dedicated libraries.
The incubator module is available in JDK 24 and later builds. Developers can enable it using the --add-modules jdk.json flag.
Key Features and Examples
Let's explore the main components of the API with practical code snippets.
1. Parsing JSON
The entry point for parsing is the Json class. It provides static methods to parse a JSON string or an InputStream into a JsonValue. The JsonValue class is sealed, with three subtypes: JsonObject, JsonArray, and JsonPrimitive.
import jdk.json.*;
String jsonString = "{\"name\": \"Alice\", \"age\": 30, \"active\": true}";
JsonObject user = Json.parse(jsonString).asObject();
String name = user.get("name").asString(); // "Alice"
int age = user.get("age").asInt(); // 30
boolean active = user.get("active").asBoolean(); // true
Notice the use of asObject(), asString(), etc. These methods perform safe type conversions and throw exceptions if the types mismatch. This design ensures type safety without requiring generics.
2. Generating JSON
Generating JSON is equally straightforward. You can build a JsonObject using its builder pattern:
JsonObject person = Json.object()
.add("name", "Bob")
.add("age", 25)
.add("address", Json.object()
.add("city", "New York")
.add("zip", "10001"))
.build();
String output = person.toString();
// {"name":"Bob","age":25,"address":{"city":"New York","zip":"10001"}}
Arrays are built similarly:
JsonArray scores = Json.array()
.add(95)
.add(87)
.add(92)
.build();
3. Working with Primitive Values
The API supports the standard JSON primitives: strings, numbers (integer and floating-point), booleans, and null. JsonPrimitive provides methods like asString(), asInt(), asDouble(), asBoolean(), and isNull(). For example:
JsonPrimitive value = Json.value(42);
int number = value.asInt(); // 42
JsonPrimitive nullValue = Json.nullValue();
boolean isNull = nullValue.isNull(); // true
4. Error Handling
Parsing invalid JSON throws a JsonException, which is a subclass of RuntimeException. This design choice simplifies error handling in simple scripts but may require explicit try-catch blocks in production code.
try {
Json.parse("{invalid}");
} catch (JsonException e) {
System.err.println("Invalid JSON: " + e.getMessage());
}
Comparison with Third-Party Libraries
To understand the value of JEP 540, it is helpful to compare it with popular alternatives. The table below highlights key differences:
| Feature | JEP 540 (Incubator) | Jackson | Gson |
|---|---|---|---|
| Dependencies | None (JDK only) | External library | External library |
| API Size | Minimal (~10 classes) | Extensive (~1000 classes) | Moderate (~100 classes) |
| Data Binding | No (manual mapping) | Yes (automatic) | Yes (automatic) |
| Streaming | No | Yes (JsonParser, JsonGenerator) | No (but can be simulated) |
| Performance | Good for small payloads | Excellent for large payloads | Good for most cases |
| License | GPL v2 + CE | Apache 2.0 | Apache 2.0 |
| Maturity | Experimental | Mature (20+ years) | Mature (15+ years) |
As the table shows, JEP 540 is not a competitor to Jackson or Gson for complex scenarios. Instead, it is a lightweight alternative for projects that want to avoid external dependencies, such as microservices, CLI tools, or educational projects.
Real-World Use Cases
1. Configuration Files
Many applications read JSON configuration files. With JEP 540, you can do this without adding a library:
import java.nio.file.*;
import jdk.json.*;
Path configPath = Path.of("config.json");
String content = Files.readString(configPath);
JsonObject config = Json.parse(content).asObject();
String dbUrl = config.get("database").asObject().get("url").asString();
int port = config.get("server").asObject().get("port").asInt();
2. Simple REST API Client
When making HTTP requests to REST APIs that return small JSON payloads, JEP 540 can be used directly:
import java.net.http.*;
import jdk.json.*;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/user/123"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
JsonObject user = Json.parse(response.body()).asObject();
3. Logging and Metrics
Generating JSON for logs or metrics is simplified:
JsonObject logEntry = Json.object()
.add("level", "INFO")
.add("message", "User logged in")
.add("timestamp", System.currentTimeMillis())
.build();
logger.info(logEntry.toString());
Potential Limitations and Considerations
While JEP 540 is promising, developers should be aware of its limitations:
- No data binding: You must manually extract values, which can be verbose for deep nested objects.
- No streaming: For large JSON files (e.g., gigabytes), the API loads the entire data into memory. Use Jackson or a streaming parser for such cases.
- Incubator status: The API is subject to change. Future JDK versions may modify or remove it.
- Limited numeric precision: The API uses double for floating-point numbers, which may lose precision for very large values. Workarounds involve using string parsing.
How to Get Started
To try JEP 540 today:
1. Download JDK 24 or later from jdk.java.net.
2. Compile your code with --add-modules jdk.json:
bash
javac --add-modules jdk.json MyClass.java
3. Run with the same flag:
bash
java --add-modules jdk.json MyClass
4. Experiment with the examples above.
Conclusion
JEP 540 marks a significant milestone for the Java platform. By providing a native, minimal JSON API, the OpenJDK project addresses a long-standing gap in the standard library. While it is not a replacement for full-featured libraries, it offers a clean, dependency-free solution for simple JSON tasks.
As the incubator evolves, the community's feedback will shape its future. Developers are encouraged to test the API, report bugs, and suggest improvements. If you are working on a project that currently uses Jackson or Gson just for basic parsing, consider switching to JEP 540. It might simplify your build and reduce technical debt.
For more details, refer to the official JEP document: Source
Stay tuned for future updates as this API matures and potentially becomes a permanent part of the JDK.
Excerpt: JEP 540 introduces a simple, dependency-free JSON API as an incubator module in JDK 24. This article explores its features, provides code examples, and compares it with Jackson and Gson. Learn how to parse and generate JSON without external libraries.
Comments