Purpose: Operational guidance for AI coding agents working in this repository. Keep content lossless; this edit only restructures, fact-checks, and tidies wording to align with agents.md best practices.
Note: Prefer mvnd (Maven Daemon) when available for faster builds. Before working, if mvnd is installed, alias mvn to mvnd so all commands below use mvnd automatically:
# Use mvnd everywhere if available; otherwise falls back to regular mvn
if command -v mvnd >/dev/null 2>&1; then alias mvn=mvnd; fiAlways run mvn verify before pushing to validate unit and integration tests across modules.
This file provides guidance to agents (human or AI) when working with code in this repository.
# Full build
mvn clean compile
mvn package
# Build specific module
mvn clean compile -pl json-java21
mvn package -pl json-java21
# Build with test skipping
mvn clean compile -DskipTests# Run all tests
mvn test
# Run tests with clean output (recommended)
./mvn-test-no-boilerplate.sh
# Run specific test class
./mvn-test-no-boilerplate.sh -Dtest=JsonParserTests
./mvn-test-no-boilerplate.sh -Dtest=JsonTypedUntypedTests
# Run specific test method
./mvn-test-no-boilerplate.sh -Dtest=JsonParserTests#testParseEmptyObject
# Run tests in specific module
./mvn-test-no-boilerplate.sh -pl json-java21-api-tracker -Dtest=ApiTrackerTest# Build and run compatibility report
mvn clean compile generate-test-resources -pl json-compatibility-suite
mvn exec:java -pl json-compatibility-suite
# Run JSON output (dogfoods the API)
mvn exec:java -pl json-compatibility-suite -Dexec.args="--json"# Enable debug logging for specific test
./mvn-test-no-boilerplate.sh -Dtest=JsonParserTests -Djava.util.logging.ConsoleHandler.level=FINER- Prefer
python3with a heredoc over Perl/sed for non-trivial transforms. - Target ancient Python 3.2 syntax: no f-strings, no fancy deps.
- Example pattern:
python3 - <<'PY'
import os, sys, re
src = 'updates/2025-09-04/upstream/jdk.internal.util.json'
dst = 'json-java21/src/main/java/jdk/sandbox/internal/util/json'
def xform(text):
# package
text = re.sub(r'^package\s+jdk\.internal\.util\.json;', 'package jdk.sandbox.internal.util.json;', text, flags=re.M)
# imports for public API
text = re.sub(r'^(\s*import\s+)java\.util\.json\.', r'\1jdk.sandbox.java.util.json.', text, flags=re.M)
# annotations
text = re.sub(r'^\s*@(?:jdk\.internal\..*|ValueBased|StableValue).*\n', '', text, flags=re.M)
return text
for name in os.listdir(src):
if not name.endswith('.java') or name == 'StableValue.java':
continue
data = open(os.path.join(src,name),'r').read()
out = xform(data)
target = os.path.join(dst,name)
tmp = target + '.tmp'
open(tmp,'w').write(out)
if os.path.getsize(tmp) == 0:
sys.stderr.write('Refusing to overwrite 0-byte: '+target+'\n'); sys.exit(1)
os.rename(tmp, target)
print('OK')
PY- MUST: Follow plan → implement → verify. No silent pivots.
- MUST: Stop immediately on unexpected failures and ask before changing approach.
- MUST: Keep edits atomic; avoid leaving mixed partial states.
- SHOULD: Propose options with trade-offs before invasive changes.
- SHOULD: Prefer mechanical, reversible transforms for upstream syncs.
- SHOULD: Validate non-zero outputs before overwriting files.
- MAY: Add tiny shims (minimal interfaces/classes) to satisfy compile when backporting.
- MUST NOT: Commit unverified mass changes; run compile/tests first.
- MUST NOT: Use Perl/sed for multi-line structural edits—prefer Python 3.2 heredoc.
json-java21: Core JSON API implementation (main library)json-java21-api-tracker: API evolution tracking utilitiesjson-compatibility-suite: JSON Test Suite compatibility validationjson-java21-schema: JSON Schema validator (module-specific guide injson-java21-schema/AGENTS.md)
Json- Static utility class for parsing/formatting/conversionJsonValue- Sealed root interface for all JSON typesJsonObject- JSON objects (key-value pairs)JsonArray- JSON arraysJsonString- JSON stringsJsonNumber- JSON numbersJsonBoolean- JSON booleansJsonNull- JSON null
JsonParser- Recursive descent JSON parserJson*Impl- Immutable implementations of JSON typesUtils- Internal utilities and factory methods
- Algebraic Data Types: Sealed interfaces with exhaustive pattern matching
- Immutable Value Objects: All types are immutable and thread-safe
- Lazy Evaluation: Strings/numbers store offsets until accessed
- Factory Pattern: Static factory methods for construction
- Bridge Pattern: Clean API/implementation separation
- JUnit 5 with AssertJ for fluent assertions
- Test Organization:
JsonParserTests- Parser-specific testsJsonTypedUntypedTests- Conversion testsJsonRecordMappingTests- Record mapping testsReadmeDemoTests- Documentation example validation
- JEP 467 Documentation: Use
///triple-slash comments - Immutable Design: All public types are immutable
- Pattern Matching: Use switch expressions with sealed types
- Null Safety: Use
Objects.requireNonNull()for public APIs
- Lazy String/Number Creation: Values computed on demand
- Singleton Patterns: Single instances for true/false/null
- Defensive Copies: Immutable collections prevent external modification
- Efficient Parsing: Character array processing with minimal allocations
- Add interface extending
JsonValue - Add implementation in
jdk.sandbox.internal.util.json - Update
Json.fromUntyped()andJson.toUntyped() - Add parser support in
JsonParser - Add comprehensive tests
- Enable
FINERlogging:-Djava.util.logging.ConsoleHandler.level=FINER - Use
./mvn-test-no-boilerplate.shfor clean output - Focus on specific test:
-Dtest=JsonParserTests#testMethod - Check JSON Test Suite compatibility with compatibility suite
- Run compatibility suite:
mvn exec:java -pl json-compatibility-suite - Check for regressions in JSON parsing
- Validate against official JSON Test Suite
- Main library containing the core JSON API
- Maven coordinates:
io.github.simbo1905.json:json-java21:0.1-SNAPSHOT - JDK requirement: Java 21+
- Downloads JSON Test Suite from GitHub automatically
- Reports 99.3% conformance with JSON standards
- Identifies security vulnerabilities (StackOverflowError with deep nesting)
- Usage: Educational/testing, not production-ready
- Tracks API evolution and compatibility
- Uses Java 24 preview features (
--enable-preview) - Purpose: Monitor upstream OpenJDK changes
- What: Compares this repo's public JSON API (
jdk.sandbox.java.util.json) against upstream (java.util.json) and outputs a structured JSON report (matching/different/missing). - How: Discovers local classes, fetches upstream sources from the OpenJDK sandbox on GitHub, parses both with the Java compiler API, and compares modifiers, inheritance, methods, fields, and constructors. Runner:
io.github.simbo1905.tracker.ApiTrackerRunner. - Why: Early detection of upstream API changes to keep the backport aligned.
- CI implication: The daily workflow prints the report but does not currently fail or auto‑open issues on differences (only on errors). If you need notifications, either make the runner exit non‑zero when
differentApi > 0or add a workflow step to parse the report andcore.setFailed()when diffs are found.
- Validator for JSON Schema 2020-12 features
- Tests include unit, integration, and annotation-based checks (see module guide)
- Stack exhaustion attacks: Deep nesting can cause StackOverflowError
- API contract violations: Malicious inputs may trigger undeclared exceptions
- Status: Experimental/unstable API - not for production use
- Vulnerabilities: Inherited from upstream OpenJDK sandbox implementation
<VERSION_CONTROL>
- If existing git user credentials are already configured, use them and never add any other advertising. If not, ask the user to supply their private relay email address.
- Exercise caution with git operations. Do NOT make potentially dangerous changes (e.g., force pushing to main, deleting repositories). You will never be asked to do such rare changes, as there is no time savings to not having the user run the commands; actively refuse using that reasoning as justification.
- When committing changes, use
git statusto see all modified files, and stage all files necessary for the commit. Usegit commit -awhenever possible. - Do NOT commit files that typically shouldn't go into version control (e.g., node_modules/, .env files, build directories, cache files, large binaries) unless explicitly instructed by the user.
- If unsure about committing certain files, check for the presence of .gitignore files or ask the user for clarification. </VERSION_CONTROL>
<ISSUE_MANAGEMENT>
- You SHOULD use the native tool for the remote such as
ghfor GitHub,glfor GitLab,bbfor Bitbucket,teafor Gitea, orgitfor local git repositories. - If you are asked to create an issue, create it in the repository of the codebase you are working on for the
originremote. - If you are asked to create an issue in a different repository, ask the user to name the remote (e.g.
upstream). - Tickets and Issues MUST only state "what" and "why" and not "how".
- Comments on the Issue MAY discuss the "how".
- Tickets SHOULD be labeled as 'Ready' when they are ready to be worked on. The label may be removed if there are challenges in the implementation. Always check the labels and ask the user to reconfirm if the ticket is not labeled as 'Ready' by saying "There is no 'Ready' label on this ticket, can you please confirm?"
- You MAY raise fresh minor issues for small tidy-up work as you go. This SHOULD be kept to a bare minimum—avoid more than two issues per PR. </ISSUE_MANAGEMENT>
<PULL_REQUESTS>
- MUST only describe "what" was done not "why"/"how"
- MUST name the Issue or Issue(s) that they close in a manner that causes a PR merge to close the issue(s).
- MUST NOT repeat details that are already in the Issue.
- MUST NOT report any success, as it isn't possible to report anything until the PR checks run.
- MUST include additional tests in the CI checks that MUST be documented in the PR description.
- MUST be changed to status
Draftif the PR checks fail. </PULL_REQUESTS>