Overview
The Maven module jvmflags does not
generate catalog JSON at compile time. Catalogs are maintained as hand-authored (or script-assisted)
files under json-graph-generator/src/main/resources/. Java uses Jackson to read those graphs, enforces structural
rules with JUnit tests, and verifies that testable flags are accepted by a live HotSpot JVM.
json-graph-generator/src/main/resources/java-*.json and
catalog-taxonomy.json.
The profile sync-docs-json copies them to
docs/json/ for the browser (D3 pages fetch json/java-N.json).
Graph document format
Each version file (java-8.json … java-25.json) is one JSON object with three top-level keys:
{
"metadata": {
"title": "Java 25 JVM Flags",
"version": "25",
"description": "Graph representation of JVM flags organized by category"
},
"nodes": [ /* root, domains, categories, subcategories, flags */ ],
"edges": [ { "source": "<id>", "target": "<id>" } ]
}
nodes hold every vertex in the tree (and metadata on flag nodes).
edges are directed parent→child links used by the site and by
JvmFlagCatalogGraph for structural checks. There are no edge types or weights.
Node types and hierarchy
Every catalog shares the same container taxonomy. Flags always hang under a subcategory:
type |
Typical fields | Role |
|---|---|---|
root |
id, label |
Graph entry point |
domain |
id, label |
Top grouping (memory, GC, execution, …) |
category |
id, label, parent |
Mid-level; must link to a domain via edge + matching parent |
subcategory |
id, label, parent |
Leaf container; holds flag nodes |
flag |
id, label, flag, description, optional test fields |
Catalog entry parsed by JvmFlagCatalog |
Example edge chain: root → domain-memory → heap → heap-size → flag-initialheapsize.
Flag nodes and verification metadata
JvmFlagCatalog.parseEntries walks nodes, keeps only
type == "flag", and builds a JvmFlag plus
JvmFlagTestSpec for each row:
{
"id": "flag-initialheapsize",
"label": "-XX:InitialHeapSize=<size>",
"type": "flag",
"flag": "-XX:InitialHeapSize=<size>",
"description": "Initial heap size …",
"flagId": "…",
"testValue": "-XX:InitialHeapSize=256m",
"requires": ["-XX:+UnlockExperimentalVMOptions"],
"testable": true,
"acceptNonZeroExit": false
}
| Field | Read by Java tests | Purpose |
|---|---|---|
flag |
Yes | Canonical option string (may include <placeholders>) |
description |
Yes | Human text; must be unique per catalog |
testValue |
Yes | Concrete JVM argument when flag is not literal |
requires |
Yes | Arguments prepended before testValue / flag |
testArgs |
Yes | Full multi-token list (overrides testValue / flag) |
testable |
Yes | Default true; false skips JvmFlagTest |
acceptNonZeroExit |
Yes | Allow non-zero exit when the JVM accepts the flag but -version fails |
flagId |
No (site only) | Stable UUID for cross-version evolution views |
How tests resolve JVM arguments
JvmFlagTestArgumentResolver builds the argument list in this order:
- If
testArgsis non-empty →requires+testArgs - Else if
testValueis set →requires+testValue - Else →
requires+flag
JvmFlagVerifier then runs
java [arguments…] -version and asserts the JVM does not report an unrecognized option.
Pending Java 8 flags (description
Present in Java 8 PrintFlagsFinal; categorization pending.)
fall back to PrintFlagsFinalTestArgumentResolver using snapshots under
json-graph-generator/src/test/resources/printflagsfinal/.
Canonical taxonomy
catalog-taxonomy.json defines every shared domain, category, and subcategory
(id, label, parent). Each java-*.json must
contain the same container node set; only flag nodes differ by release.
CatalogTaxonomy loads this file and JvmFlagCatalogTaxonomyTest compares
it to every version graph.
Java classes
| Class | Package / path | Responsibility |
|---|---|---|
JvmFlagCatalog |
info.jab.jvmflag |
Load java-N.json; extract flag entries for verification |
JvmFlagCatalogGraph |
info.jab.jvmflag |
Read-only graph; orphan flags, empty subcategories, taxonomy violations |
CatalogTaxonomy |
info.jab.jvmflag |
Load catalog-taxonomy.json |
JvmFlag / JvmFlagEntry |
info.jab.jvmflag |
Flag identity + paired test spec |
JvmFlagVerifier |
info.jab.jvmflag |
Execute java subprocess for acceptance checks |
JvmFlagTest |
src/test/java/… |
Parameterized live-JVM test per testable flag |
JvmFlagCatalog*Test |
src/test/java/… |
Structure, taxonomy, orphans, description uniqueness |
PrintFlagsFinalCatalogTest |
src/test/java/… |
Align catalog with -XX:+PrintFlagsFinal snapshots |
Key loader entry points:
JvmFlagCatalog.loadForJavaVersion(25)
JvmFlagCatalogGraph.loadForJavaVersion(25)
CatalogTaxonomy.load()
End-to-end workflow
-
Capture ground truth.
Run
./scripts/regenerate-printflagsfinal.shon JDK 8/11/17/21/25 to refreshjson-graph-generator/src/test/resources/printflagsfinal/java-N-hotspot.mdfromjava -XX:+PrintFlagsFinal. -
Maintain catalogs.
Edit
json-graph-generator/src/main/resources/java-N.json: add or move flag nodes, wireedges, set descriptions, and verification fields. Optional Python helpers underscripts/(for exampleadd-pending-java8-flags.py,enrich-java8-flag-test-values.py) assist bulk updates. -
Keep taxonomy aligned.
Update
catalog-taxonomy.jsonwhen adding domains, categories, or subcategories; replicate container nodes in every version file. -
Verify on the matching JDK.
cd json-graph-generator && ./mvnw test(or./scripts/test-with-jdk.sh N) runs structure tests for all versions plus liveJvmFlagTestfor the catalog that matches the running feature release. -
Publish to the site.
cd json-graph-generator && ./mvnw clean install -Psync-docs-jsoncopiesjson-graph-generator/src/main/resources/→docs/json/. -
Browse.
Serve
docs/withjwebserver; pages loadjson/java-N.jsonfor D3 graphs and tables.
Maintainer commands
# Verify catalog on current JDK (needs matching java-N.json)
cd json-graph-generator && ./mvnw test
# Verify on a specific JDK
./scripts/test-with-jdk.sh 17
# Refresh PrintFlagsFinal snapshots
./scripts/regenerate-printflagsfinal.sh
# Publish JSON to the static site
cd json-graph-generator && ./mvnw clean install -Psync-docs-json
# Serve locally (from repository root)
jwebserver -d docs -p 8080
See also About for site features and GitHub for the full repository.