Skip to content

Commit 05577c5

Browse files
committed
backport examples
1 parent 0c298ce commit 05577c5

File tree

1 file changed

+208
-0
lines changed

1 file changed

+208
-0
lines changed

json-java21/AGENTS.md

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
# json-java21 Module AGENTS.md
2+
3+
## Purpose
4+
This module backports the upstream OpenJDK sandbox `java.util.json` API to Java 21.
5+
6+
## Upstream Source
7+
- Repository: https://github.com/openjdk/jdk-sandbox
8+
- Branch: `json` (NOT master!)
9+
- Base path: `src/java.base/share/classes/`
10+
- Public API: `java/util/json/*.java`
11+
- Internal implementation: `jdk/internal/util/json/*.java`
12+
13+
## CRITICAL WARNING
14+
15+
**DO NOT DOWNLOAD THE REPOSITORY ZIP FILE!**
16+
17+
The jdk-sandbox repository is MASSIVE (the entire JDK). We only need ~19 small Java files.
18+
19+
**ALWAYS fetch individual files using raw GitHub URLs one at a time.**
20+
21+
## Sync Process
22+
23+
### Step 1: Prepare Fresh Download Area
24+
```bash
25+
rm -rf .tmp/upstream-sync
26+
mkdir -p .tmp/upstream-sync/java/util/json
27+
mkdir -p .tmp/upstream-sync/jdk/internal/util/json
28+
```
29+
30+
### Step 2: Fetch Upstream Sources (ONE FILE AT A TIME)
31+
32+
**CRITICAL: Fetch each file individually using curl or wget with the raw GitHub URL.**
33+
34+
The URL pattern is:
35+
```
36+
https://raw.githubusercontent.com/openjdk/jdk-sandbox/json/src/java.base/share/classes/<path>
37+
```
38+
39+
Note the branch is `json` in the URL path (NOT `refs/heads/json`, just `json`).
40+
41+
#### Public API files (~10 files):
42+
```bash
43+
curl -o .tmp/upstream-sync/java/util/json/Json.java \
44+
"https://raw.githubusercontent.com/openjdk/jdk-sandbox/json/src/java.base/share/classes/java/util/json/Json.java"
45+
46+
curl -o .tmp/upstream-sync/java/util/json/JsonArray.java \
47+
"https://raw.githubusercontent.com/openjdk/jdk-sandbox/json/src/java.base/share/classes/java/util/json/JsonArray.java"
48+
49+
...
50+
```
51+
52+
#### Internal implementation files (~9 files):
53+
```bash
54+
curl -o .tmp/upstream-sync/jdk/internal/util/json/JsonArrayImpl.java \
55+
"https://raw.githubusercontent.com/openjdk/jdk-sandbox/json/src/java.base/share/classes/jdk/internal/util/json/JsonArrayImpl.java"
56+
57+
curl -o .tmp/upstream-sync/jdk/internal/util/json/JsonBooleanImpl.java \
58+
"https://raw.githubusercontent.com/openjdk/jdk-sandbox/json/src/java.base/share/classes/jdk/internal/util/json/JsonBooleanImpl.java"
59+
60+
...
61+
```
62+
63+
#### Verify downloads succeeded:
64+
```bash
65+
# Should show X files (whatever is currently upstream)
66+
ls -la .tmp/upstream-sync/java/util/json/
67+
68+
# Should show Y files (whatever is currently upstream)
69+
ls -la .tmp/upstream-sync/jdk/internal/util/json/
70+
71+
# Check none are empty or HTML error pages
72+
wc -l .tmp/upstream-sync/java/util/json/*.java
73+
wc -l .tmp/upstream-sync/jdk/internal/util/json/*.java
74+
```
75+
76+
### Step 3: Create Backported Structure
77+
Create parallel structure in `.tmp/backported/` with our package names:
78+
79+
```bash
80+
mkdir -p .tmp/backported/jdk/sandbox/java/util/json
81+
mkdir -p .tmp/backported/jdk/sandbox/internal/util/json
82+
```
83+
84+
### Step 4: Apply Backporting Transformations
85+
For each downloaded file, apply these transformations using Python heredocs (not sed/perl for multi-line):
86+
87+
#### 4.1 Package Renaming
88+
- `java.util.json``jdk.sandbox.java.util.json`
89+
- `jdk.internal.util.json``jdk.sandbox.internal.util.json`
90+
91+
#### 4.2 Remove Preview Feature Annotations
92+
Delete lines containing:
93+
- `import jdk.internal.javac.PreviewFeature;`
94+
- `@PreviewFeature(feature = PreviewFeature.Feature.JSON)`
95+
96+
#### 4.3 StableValue Polyfill
97+
Upstream uses `jdk.internal.lang.stable.StableValue` which is not available in Java 21.
98+
99+
**Replace imports:**
100+
- `import jdk.internal.lang.stable.StableValue;` → (remove, our polyfill is package-local)
101+
102+
**The polyfill `StableValue.java`** (already in our repo) provides:
103+
- `StableValue.of()` - creates empty holder
104+
- `orElse(T defaultValue)` - returns value or default
105+
- `orElseSet(Supplier<T>)` - lazy initialization with double-checked locking
106+
- `setOrThrow(T)` - one-time set
107+
- `StableValue.supplier(Supplier<T>)` - memoizing supplier wrapper
108+
109+
This file is NOT from upstream and must be preserved during sync.
110+
111+
#### 4.4 DO NOT Convert JavaDoc to JEP 467 Markdown
112+
If upstream uses `/** ... */` style, DO NOT convert them to our `/// ...` format; we will not edit the upstream files more than the absolute minimum to get them to run on Java 21.
113+
114+
#### 4.5 Add JsonAssertionException (Our Addition)
115+
The file `JsonAssertionException.java` is a local addition not in upstream. Preserve it.
116+
117+
#### 4.6 Preserve Demo File
118+
The file `jdk/sandbox/demo/JsonDemo.java` is a local addition for demonstration purposes. Preserve it. Fix it.
119+
120+
### Step 5: Verify Compilation with javac
121+
Before copying to the main source tree, verify the backported code compiles:
122+
123+
```bash
124+
# Find all Java files in the backported structure
125+
find .tmp/backported -name "*.java" > .tmp/sources.txt
126+
127+
# Also include our polyfill and local additions
128+
echo "json-java21/src/main/java/jdk/sandbox/internal/util/json/StableValue.java" >> .tmp/sources.txt
129+
echo "json-java21/src/main/java/jdk/sandbox/java/util/json/JsonAssertionException.java" >> .tmp/sources.txt
130+
131+
# Compile with Java 21
132+
javac --release 21 -d .tmp/classes @.tmp/sources.txt
133+
```
134+
135+
### Step 6: Copy to Source Tree (After Verification)
136+
137+
Only after javac succeeds:
138+
139+
```bash
140+
# Backup current sources (optional)
141+
cp -r json-java21/src/main/java/jdk/sandbox .tmp/backup-sandbox
142+
143+
# Copy backported files (excluding our local additions)
144+
cp .tmp/backported/jdk/sandbox/java/util/json/*.java \
145+
json-java21/src/main/java/jdk/sandbox/java/util/json/
146+
147+
cp .tmp/backported/jdk/sandbox/internal/util/json/*.java \
148+
json-java21/src/main/java/jdk/sandbox/internal/util/json/
149+
150+
# Restore our local additions if overwritten
151+
# (StableValue.java, JsonAssertionException.java should not be in backported/)
152+
```
153+
154+
The file `jdk/sandbox/demo/JsonDemo.java` should be the example code in our README.md, as it may have changed to reflect upstream changes. You MUST update the README.md to include examples of the upgraded code in this file, which you must MANUALLY VERIFY IS GOOD post-upgrade.
155+
156+
### Step 7: Full Maven Build
157+
158+
```bash
159+
$(command -v mvnd || command -v mvn || command -v ./mvnw) clean test -pl json-java21 -Djava.util.logging.ConsoleHandler.level=INFO
160+
```
161+
162+
## Files That Are Local Additions (Preserve During Sync)
163+
164+
| File | Purpose |
165+
|------|---------|
166+
| `jdk/sandbox/internal/util/json/StableValue.java` | Java 21 polyfill for future JDK StableValue API |
167+
| `jdk/sandbox/java/util/json/JsonAssertionException.java` | Custom exception for type assertion errors |
168+
| `jdk/sandbox/demo/JsonDemo.java` | Demonstration/example code |
169+
170+
## Transformation Example
171+
172+
**Upstream `JsonStringImpl.java` (excerpt):**
173+
```java
174+
package jdk.internal.util.json;
175+
176+
import java.util.json.JsonString;
177+
import jdk.internal.lang.stable.StableValue;
178+
179+
public final class JsonStringImpl implements JsonString, JsonValueImpl {
180+
private final StableValue<String> jsonStr = StableValue.of();
181+
// ...
182+
}
183+
```
184+
185+
**Backported version:**
186+
```java
187+
package jdk.sandbox.internal.util.json;
188+
189+
import jdk.sandbox.java.util.json.JsonString;
190+
// StableValue is package-local, no import needed
191+
192+
public final class JsonStringImpl implements JsonString, JsonValueImpl {
193+
private final StableValue<String> jsonStr = StableValue.of();
194+
// ...
195+
}
196+
```
197+
198+
## Troubleshooting
199+
200+
### Compilation Errors After Sync
201+
1. Check package names are correctly transformed
202+
2. Verify StableValue polyfill is present
203+
3. Check for new upstream APIs that may need additional polyfills
204+
205+
### Test Failures After Sync
206+
1. Run with verbose logging: `-Djava.util.logging.ConsoleHandler.level=FINE`
207+
2. Check if upstream changed method signatures
208+
3. Review upstream commit history for breaking changes

0 commit comments

Comments
 (0)