Skip to content

Commit 12623b9

Browse files
committed
Issue #122 update docs
1 parent 4b60358 commit 12623b9

File tree

3 files changed

+211
-884
lines changed

3 files changed

+211
-884
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,7 @@ WISDOM.md
3636
.vscode/
3737
pom.xml.versionsBackup
3838
.tmp
39+
40+
# Local JTD debug logs
41+
jtd*.log
42+
**/jtd*.log

index.html

Lines changed: 207 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -5,146 +5,259 @@
55
<meta name="viewport" content="width=device-width, initial-scale=1.0">
66
<title>java.util.json Backport for JDK 21+</title>
77
<style>
8+
:root {
9+
--bg: #f6f1e8;
10+
--paper: #fffaf2;
11+
--ink: #1f2933;
12+
--muted: #52616b;
13+
--accent: #0f766e;
14+
--accent-2: #b45309;
15+
--border: rgba(31, 41, 51, 0.12);
16+
--shadow: 0 18px 60px rgba(16, 24, 40, 0.10);
17+
}
18+
19+
* { box-sizing: border-box; }
20+
821
body {
9-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
10-
line-height: 1.6;
11-
color: #333;
12-
max-width: 900px;
13-
margin: 0 auto;
14-
padding: 20px;
15-
background-color: #f5f5f5;
22+
margin: 0;
23+
padding: 24px;
24+
color: var(--ink);
25+
line-height: 1.65;
26+
font-family: "Iowan Old Style", "Palatino Linotype", Palatino, "Book Antiqua", serif;
27+
background:
28+
radial-gradient(1200px 600px at 18% 12%, rgba(15, 118, 110, 0.10), transparent 55%),
29+
radial-gradient(900px 500px at 85% 18%, rgba(180, 83, 9, 0.10), transparent 60%),
30+
linear-gradient(180deg, var(--bg), #f9f6ef);
1631
}
32+
1733
.container {
18-
background-color: white;
19-
padding: 30px;
20-
border-radius: 8px;
21-
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
34+
max-width: 980px;
35+
margin: 0 auto;
36+
padding: 28px;
37+
border-radius: 16px;
38+
background: var(--paper);
39+
border: 1px solid var(--border);
40+
box-shadow: var(--shadow);
2241
}
23-
h1, h2, h3 {
24-
color: #2c3e50;
42+
43+
header {
44+
padding: 6px 0 18px;
45+
border-bottom: 1px solid var(--border);
46+
margin-bottom: 22px;
2547
}
48+
2649
h1 {
27-
border-bottom: 3px solid #3498db;
28-
padding-bottom: 10px;
50+
margin: 0 0 6px;
51+
font-size: clamp(28px, 3.3vw, 38px);
52+
letter-spacing: -0.02em;
53+
}
54+
55+
h2 {
56+
margin: 22px 0 10px;
57+
font-size: 20px;
58+
letter-spacing: -0.01em;
59+
}
60+
61+
h3 {
62+
margin: 14px 0 8px;
63+
font-size: 16px;
64+
}
65+
66+
p, li {
67+
color: var(--ink);
68+
}
69+
70+
.subhead {
71+
margin: 0;
72+
color: var(--muted);
73+
max-width: 70ch;
74+
}
75+
76+
.callout {
77+
margin: 14px 0 0;
78+
padding: 12px 14px;
79+
border-radius: 12px;
80+
border: 1px solid rgba(15, 118, 110, 0.25);
81+
background: rgba(15, 118, 110, 0.06);
82+
}
83+
84+
.grid {
85+
display: grid;
86+
grid-template-columns: 1fr;
87+
gap: 14px;
88+
}
89+
90+
@media (min-width: 900px) {
91+
.grid {
92+
grid-template-columns: 1.1fr 0.9fr;
93+
gap: 18px;
94+
}
2995
}
96+
3097
pre {
31-
background-color: #f4f4f4;
32-
border: 1px solid #ddd;
33-
border-radius: 4px;
34-
padding: 15px;
98+
margin: 10px 0 0;
99+
padding: 14px;
35100
overflow-x: auto;
101+
border-radius: 12px;
102+
border: 1px solid var(--border);
103+
background: rgba(31, 41, 51, 0.04);
36104
}
105+
37106
code {
38-
background-color: #f4f4f4;
39-
padding: 2px 4px;
40-
border-radius: 3px;
41-
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
107+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
108+
font-size: 0.95em;
109+
}
110+
111+
pre code {
112+
background: transparent;
42113
}
43-
.highlight {
44-
background-color: #fff3cd;
45-
border-left: 4px solid #ffc107;
46-
padding: 10px;
47-
margin: 15px 0;
114+
115+
.links {
116+
display: flex;
117+
flex-wrap: wrap;
118+
gap: 10px;
119+
margin-top: 12px;
48120
}
121+
49122
.button {
50123
display: inline-block;
51-
padding: 10px 20px;
52-
background-color: #3498db;
53-
color: white;
124+
padding: 10px 14px;
125+
border-radius: 999px;
54126
text-decoration: none;
55-
border-radius: 5px;
56-
margin-right: 10px;
57-
margin-top: 10px;
127+
font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
128+
font-weight: 650;
129+
border: 1px solid rgba(15, 118, 110, 0.35);
130+
background: rgba(15, 118, 110, 0.10);
131+
color: var(--ink);
58132
}
133+
59134
.button:hover {
60-
background-color: #2980b9;
135+
background: rgba(15, 118, 110, 0.16);
61136
}
137+
62138
.button.secondary {
63-
background-color: #95a5a6;
139+
border-color: rgba(180, 83, 9, 0.35);
140+
background: rgba(180, 83, 9, 0.10);
64141
}
142+
65143
.button.secondary:hover {
66-
background-color: #7f8c8d;
144+
background: rgba(180, 83, 9, 0.16);
145+
}
146+
147+
.meta {
148+
color: var(--muted);
149+
font-size: 14px;
67150
}
68151
</style>
69152
</head>
70153
<body>
71154
<div class="container">
72-
<h1>java.util.json Backport for JDK 21+</h1>
155+
<header>
156+
<h1>java.util.json Backport for JDK 21+</h1>
157+
<p class="subhead">A backport of the experimental <code>java.util.json</code> API from the OpenJDK jdk-sandbox “json” branch, plus an incubating JSON Type Definition (JTD) validator (RFC 8927).</p>
158+
<div class="callout">
159+
<strong>Early access / unstable:</strong> APIs and behaviour may change as upstream evolves.
160+
</div>
161+
<div class="links">
162+
<a href="https://central.sonatype.com/artifact/io.github.simbo1905.json/java.util.json" class="button">Maven Central</a>
163+
<a href="https://github.com/simbo1905/java.util.json.Java21" class="button">GitHub</a>
164+
<a href="Towards%20a%20JSON%20API%20for%20the%20JDK.pdf" class="button secondary">Design Paper (PDF)</a>
165+
<a href="https://github.com/openjdk/jdk-sandbox/tree/json" class="button secondary">OpenJDK jdk-sandbox</a>
166+
</div>
167+
</header>
73168

74-
<div class="highlight">
75-
<strong>Early Access:</strong> This is an unofficial backport of the experimental <code>java.util.json</code> API from OpenJDK sandbox,
76-
enabling developers to use future JSON API patterns today on JDK 21+.
169+
<div class="grid">
170+
<section>
171+
<h2>Quick Start</h2>
172+
173+
<h3>Maven</h3>
174+
<pre><code>&lt;dependency&gt;
175+
&lt;groupId&gt;io.github.simbo1905.json&lt;/groupId&gt;
176+
&lt;artifactId&gt;java.util.json&lt;/artifactId&gt;
177+
&lt;version&gt;2026.01.26&lt;/version&gt;
178+
&lt;/dependency&gt;
179+
</code></pre>
180+
181+
<h3>Parse and access</h3>
182+
<pre><code>import jdk.sandbox.java.util.json.*;
183+
184+
JsonObject obj = (JsonObject) Json.parse("{\"name\":\"Alice\",\"age\":30}");
185+
186+
String name = obj.get("name").string();
187+
long age = obj.get("age").toLong();</code></pre>
188+
</section>
189+
190+
<section>
191+
<h2>What’s Included</h2>
192+
<ul>
193+
<li><strong>Immutable JSON values:</strong> <code>JsonObject</code>, <code>JsonArray</code>, <code>JsonString</code>, <code>JsonNumber</code>, <code>JsonBoolean</code>, <code>JsonNull</code></li>
194+
<li><strong>Typed factories:</strong> build JSON with <code>JsonObject.of</code>, <code>JsonArray.of</code>, <code>JsonString.of</code>, <code>JsonNumber.of</code>, <code>JsonBoolean.of</code></li>
195+
<li><strong>Type-safe accessors:</strong> <code>obj.get("x").string()</code>, <code>value.toLong()</code>, <code>value.toDouble()</code>, <code>value.bool()</code></li>
196+
<li><strong>JTD validator (RFC 8927):</strong> module <code>json-java21-jtd</code> for real-world JSON-heavy logic</li>
197+
</ul>
198+
</section>
77199
</div>
78200

79-
<h2>Quick Start</h2>
80-
81-
<h3>Maven Dependency</h3>
82-
<pre><code>
83-
&lt;dependency&gt;
84-
&lt;groupId&gt;io.github.simbo1905.json&lt;/groupId&gt;
85-
&lt;artifactId&gt;java.util.json&lt;/artifactId&gt;
86-
&lt;version&gt;0.1.8&lt;/version&gt;
87-
&lt;/dependency&gt;
88-
</code></pre>
89-
90-
<h3>Simple Example</h3>
201+
<h2>Record Mapping (explicit, typed)</h2>
91202
<pre><code>import jdk.sandbox.java.util.json.*;
203+
import java.util.*;
92204

93-
// Parse JSON
94-
JsonValue value = Json.parse("{\"name\":\"Alice\",\"age\":30}");
95-
JsonObject obj = (JsonObject) value;
96-
97-
// Access values
98-
String name = ((JsonString) obj.members().get("name")).value();
99-
int age = ((JsonNumber) obj.members().get("age")).toNumber().intValue();</code></pre>
100-
101-
<h2>Key Features</h2>
102-
<ul>
103-
<li><strong>Future-Compatible API:</strong> Write code today that will work with tomorrow's official <code>java.util.json</code></li>
104-
<li><strong>Sealed Type Hierarchy:</strong> Type-safe JSON values using Java's sealed classes</li>
105-
<li><strong>Record Integration:</strong> Seamless mapping between Java records and JSON</li>
106-
<li><strong>Pattern Matching:</strong> Leverage modern Java features for elegant JSON handling</li>
107-
<li><strong>Immutable Values:</strong> Thread-safe by design</li>
108-
</ul>
109-
110-
<h2>Record Mapping Example</h2>
111-
<pre><code>// Domain model
112205
record User(String name, String email, boolean active) {}
113206
record Team(String teamName, List&lt;User&gt; members) {}
114207

115-
// Convert to JSON
116208
Team team = new Team("Engineering", List.of(
117209
new User("Alice", "alice@example.com", true),
118210
new User("Bob", "bob@example.com", false)
119211
));
120212

121-
JsonValue teamJson = Json.fromUntyped(Map.of(
122-
"teamName", team.teamName(),
123-
"members", team.members().stream()
124-
.map(u -> Map.of(
125-
"name", u.name(),
126-
"email", u.email(),
127-
"active", u.active()
128-
))
129-
.toList()
213+
JsonValue teamJson = JsonObject.of(Map.of(
214+
"teamName", JsonString.of(team.teamName()),
215+
"members", JsonArray.of(team.members().stream()
216+
.map(u -&gt; JsonObject.of(Map.of(
217+
"name", JsonString.of(u.name()),
218+
"email", JsonString.of(u.email()),
219+
"active", JsonBoolean.of(u.active())
220+
)))
221+
.toList())
130222
));</code></pre>
131223

132-
<h2>Resources</h2>
133-
<a href="https://github.com/simbo1905/java.util.json.Java21" class="button">View on GitHub</a>
134-
<a href="Towards%20a%20JSON%20API%20for%20the%20JDK.pdf" class="button secondary">Original Proposal</a>
135-
<a href="https://github.com/openjdk/jdk-sandbox/tree/json" class="button secondary">OpenJDK Sandbox</a>
224+
<h2>Run the README Examples</h2>
225+
<pre><code>mvn package
226+
java -cp ./json-java21/target/java.util.json-*.jar:./json-java21/target/test-classes \
227+
jdk.sandbox.java.util.json.examples.ReadmeExamples</code></pre>
228+
<p class="meta">Replace <code>*</code> with the actual version number from the JAR filename.</p>
229+
230+
<h2>JSON Test Suite Compatibility</h2>
231+
<pre><code># Run human-readable report
232+
mvn exec:java -pl json-compatibility-suite
233+
234+
# Run JSON output (dogfoods the API)
235+
mvn exec:java -pl json-compatibility-suite -Dexec.args="--json"</code></pre>
236+
237+
<h2>JSON Type Definition (JTD) Validator</h2>
238+
<p class="meta">This repo includes an incubating JTD validator (RFC 8927) in module <code>json-java21-jtd</code>. Per RFC 8927, the empty schema <code>{}</code> accepts all JSON instances.</p>
239+
<pre><code>import json.java21.jtd.Jtd;
240+
import jdk.sandbox.java.util.json.*;
241+
242+
JsonValue schema = Json.parse("""
243+
{
244+
"properties": {
245+
"name": {"type": "string"},
246+
"age": {"type": "int32"}
247+
}
248+
}
249+
""");
250+
251+
JsonValue data = Json.parse("{\"name\":\"Alice\",\"age\":30}");
252+
253+
Jtd.Result result = new Jtd().validate(schema, data);
254+
// result.isValid() == true</code></pre>
136255

137256
<h2>Status</h2>
138-
<p>
139-
This code (as of 2025-09-04) is derived from the OpenJDK jdk-sandbox repository “json”
140-
branch at commit
141-
<a href="https://github.com/openjdk/jdk-sandbox/commit/a8e7de8b49e4e4178eb53c94ead2fa2846c30635">Produce path/col during path building</a>.
142-
The API may evolve as the official specification develops.
143-
</p>
257+
<p class="meta">This code (as of 2026-01-25) is derived from the OpenJDK jdk-sandbox repository “json” branch. The API may evolve as the upstream design develops.</p>
144258

145259
<h2>License</h2>
146-
<p>Licensed under the GNU General Public License version 2 with Classpath exception,
147-
same as the OpenJDK project.</p>
260+
<p class="meta">GNU General Public License version 2 with Classpath exception (same as OpenJDK).</p>
148261
</div>
149262
</body>
150263
</html>

0 commit comments

Comments
 (0)