← Back

Methodology

How the Java module loads, validates, and publishes versioned JVM flag catalogs as JSON graphs for the static site.

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.

Source of truth: 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.jsonjava-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:

  1. If testArgs is non-empty → requires + testArgs
  2. Else if testValue is set → requires + testValue
  3. 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

  1. Capture ground truth. Run ./scripts/regenerate-printflagsfinal.sh on JDK 8/11/17/21/25 to refresh json-graph-generator/src/test/resources/printflagsfinal/java-N-hotspot.md from java -XX:+PrintFlagsFinal.
  2. Maintain catalogs. Edit json-graph-generator/src/main/resources/java-N.json: add or move flag nodes, wire edges, set descriptions, and verification fields. Optional Python helpers under scripts/ (for example add-pending-java8-flags.py, enrich-java8-flag-test-values.py) assist bulk updates.
  3. Keep taxonomy aligned. Update catalog-taxonomy.json when adding domains, categories, or subcategories; replicate container nodes in every version file.
  4. 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 live JvmFlagTest for the catalog that matches the running feature release.
  5. Publish to the site. cd json-graph-generator && ./mvnw clean install -Psync-docs-json copies json-graph-generator/src/main/resources/docs/json/.
  6. Browse. Serve docs/ with jwebserver; pages load json/java-N.json for 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.