⌘ ZEUS Interface Quality · JSON Schema · CI
The first executable building block of automated interface quality
Automatically Validate JSON Files: From JSON Schema to CI
One delivery contains "quantity": 3. The next one contains "three" in the same place. A third file stops halfway through the JSON document. All three can be checked automatically—but they must not produce the same result.
That is the first building block of ZEUS Interface Quality. It reads a local JSON file, validates it against an agreed contract, and returns a report plus an exit code. This article lets you reproduce the result and follow the decisions that turn a basic validator into a more reliable test.
The larger question—how to test APIs, files, and legacy interfaces automatically—is covered by the English Project Page. This article stays deliberately focused on the completed first iteration.

What this iteration delivers
The CLI distinguishes three cases. An exit code is the number a program returns to the script that invoked it.
- 0 – valid: The JSON document satisfies the selected schema.
- 1 – contract violation: The document is readable, but at least one schema rule is violated.
- 2 – check not possible: For example, a file is unreadable, JSON is malformed, the schema is invalid, or a schema reference is not allowed.
The iteration includes text and JSON output, fixed test data, and CI verification. It does not include HTTP or SFTP retrieval, CSV, XML, YAML, business rules, or tests against real counterparties.
The contract for our delivery
We start with a small delivery that is easy to understand. The data is synthetic and stored as fixtures in the repository: inputs that are reused unchanged by every test run.
{
"deliveryId": "DEL-1001",
"quantity": 3,
"email": "ops@example.org",
"address": {
"street": "Hauptstraße 1",
"postalCode": "10115",
"city": "Berlin"
}
}
The matching schema defines required fields and allowed values:
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "delivery.schema.json",
"title": "Delivery",
"type": "object",
"additionalProperties": false,
"required": ["deliveryId", "quantity", "email", "address"],
"properties": {
"deliveryId": { "type": "string", "minLength": 1 },
"quantity": { "type": "integer", "minimum": 1 },
"email": { "type": "string", "format": "email" },
"address": { "$ref": "refs/address.schema.json" }
}
}
quantity must be an integer of at least one. The string "three" does not satisfy that rule. additionalProperties: false rejects fields that are not part of this object. The address has its own local contract in refs/address.schema.json; its five-digit postal code is a narrow example rule, not an international address model.
A format annotation is not automatically a format check
In Draft 2020-12, format may be only an annotation. We explicitly enable format assertions, so "not-an-email" is reported as an error. The validator checks the format; it does not check whether a mailbox exists or can be reached.
Validate JSON files yourself
You need Git and JDK 21. The Maven Wrapper starts Maven, so a separate Maven installation is not required. The first build downloads Maven and dependencies; validation with the built JAR and local schemas does not need network access. The source example is tied to the tested commit d794151.
Clone the fixed source state
Use a directory where zeus-interface-quality-iteration-1 does not already exist:
git clone https://github.com/gzeuner/zeus-interface-quality.git zeus-interface-quality-iteration-1
cd zeus-interface-quality-iteration-1
git checkout --detach d79415111b7d830f2aa4741f7bec647a2652535c
A “detached HEAD” message is expected: you are inspecting a fixed commit rather than a moving branch.
Windows / PowerShell
.\mvnw.cmd -B package
$iqJar = "target/zeus-interface-quality-0.1.0-SNAPSHOT.jar"
$iqFixtures = "src/test/resources/fixtures"
java -jar $iqJar validate --schema "$iqFixtures/delivery.schema.json" --input "$iqFixtures/valid-delivery.json" --report json
$LASTEXITCODE
java -jar $iqJar validate --schema "$iqFixtures/delivery.schema.json" --input "$iqFixtures/invalid-wrong-type.json" --report json
$LASTEXITCODE
java -jar $iqJar validate --schema "$iqFixtures/delivery.schema.json" --input "$iqFixtures/malformed.json" --report json
$LASTEXITCODE
Linux / macOS
./mvnw -B package
iq_jar="target/zeus-interface-quality-0.1.0-SNAPSHOT.jar"
iq_fixtures="src/test/resources/fixtures"
java -jar "$iq_jar" validate --schema "$iq_fixtures/delivery.schema.json" --input "$iq_fixtures/valid-delivery.json" --report json
echo "$?"
java -jar "$iq_jar" validate --schema "$iq_fixtures/delivery.schema.json" --input "$iq_fixtures/invalid-wrong-type.json" --report json
echo "$?"
java -jar "$iq_jar" validate --schema "$iq_fixtures/delivery.schema.json" --input "$iq_fixtures/malformed.json" --report json
echo "$?"
Use --report text for readable console output; text is also the default. For malformed.json, the error goes to stderr and there is no JSON report on stdout. A missing input or schema path also returns exit code 2.
How to read the JSON report
The valid delivery returns status: VALID, valid: true, and an empty findings list. The wrong-type fixture returns:
{
"status": "INVALID",
"valid": false,
"findings": [
{
"instancePath": "/quantity",
"schemaPath": "/properties/quantity/type",
"keyword": "type",
"message": "string gefunden, integer erwartet"
}
]
}
instancePath identifies the data location. keyword identifies the violated rule. schemaPath identifies the validator’s evaluation path; references may include $ref sections. Findings are sorted deterministically. The current implementation’s human-readable messages are German even on an English host, so automation should use status, paths, and keywords rather than message wording.
What the review uncovered
The first valid and invalid fixtures were green. That was not enough. A validator must also handle inputs the happy path never produces.
The whole file counts
Empty files, whitespace-only files, trailing content after a JSON document, and duplicate object keys are technical errors with exit code 2. The JSON value null remains a valid JSON document; the schema decides whether it is allowed. Duplicate keys are rejected while reading so a later value cannot silently hide the original ambiguity.
The contract can be wrong too
An object such as "required": "deliveryId" is valid JSON but misuses the schema keyword: required expects an array. Schema files, including local references, are validated against the bundled Draft 2020-12 meta-schema. A broken contract must not be reported as a broken delivery.
The real command must match the example
A report-writer unit test does not prove that the actual validate command produces the same content. An end-to-end test compares the CLI result with a frozen report, including under an English host locale. The important question is which failure assumptions the tests exercise—not how many tests happen to be green.
Why schema references stay local
A $ref avoids duplicate definitions, but it can introduce extra files or network access. Referenced schemas must therefore be regular files inside the actual directory of the selected root schema. The implementation checks normalized and resolved paths, rejects symbolic-link escapes, and rejects HTTP references or foreign hosts before retrieval.
The HTTPS value in $schema names the dialect; the matching meta-schema is bundled with the library. The validation run does not need internet access.
A clear boundary is not a sandbox
This version assumes controlled local inputs and schema directories. It does not promise protection against files changed while being read or fixed resource and runtime limits for hostile inputs. It is not yet a public validation service.
Technology-neutral with a small Java core
Java 21 and one Maven module are enough for this iteration:
| Component | Responsibility |
|---|---|
core |
Project-owned result objects, deterministic ordering, and the validator interface |
adapter.jsonschema |
Jackson reads JSON; NetworkNT validates schemas and data |
report |
Writes the agreed text or JSON report |
cli |
Picocli handles options and maps results or failures to exit codes |
“Technology-neutral” means library details stay behind project interfaces, not that Java becomes language-neutral. Spring Boot is not forbidden, but this local CLI needs neither a server nor a server runtime.
What the automated evidence shows
The original GitHub Actions run at commit d794151 passed all 36 tests on Linux without failures or skips. On Windows, 34 passed and two symbolic-link tests were skipped because the local permission was unavailable. The pipeline also builds the package and starts the generated JAR with valid and invalid fixtures; the invalid case must return exit code 1.
This proves the agreed local flow—not a complete interface test. A real SFTP counterparty, HTTP endpoint, business rules, and load behavior are outside this iteration.
Conclusion: the first building block is ready
We can validate JSON files automatically and distinguish valid data, contract violations, and technical failures. Schema, fixtures, report, and CLI form one reproducible state.
The valuable work was the hardening: read the whole file, validate the schema itself, constrain references, and test the real command. That is a meaningful Iteration 1.
The English Project Page places this building block in the larger interface-quality approach.
Code and sources
Source edition status: September 15, 2026. The examples are tied to commit d79415111b7d830f2aa4741f7bec647a2652535c.
Transparency Notice
Content published on tiny-tool.de is carefully researched, editorially reviewed, and updated regularly. Sources and quotations are provided in a transparent and traceable manner wherever possible. However, we do not guarantee the accuracy, completeness, or timeliness of the information provided. Errors cannot be ruled out.
Editorial Responsibility and Use of AI: Digital tools – including AI-based assistance systems – may be used to support research, structuring, language refinement, translation, code analysis, or visual production. Published content is editorially reviewed, revised, and approved by Guido Zeuner. Content selection, contextualisation, and publication remain under human responsibility. AI-generated output is not treated as an independent source. AI systems are not responsible authors or editors. More information about our use of AI in texts, images, videos, and digital personas is available on our AI Transparency page, which is currently available in German.
Audience Measurement (VG WORT / METIS): VG WORT tracking markers may be used to measure the reach of individual texts. As part of the METIS audience measurement process, a client ID may be generated and a so-called “METIS Session Cookie” may be set. The measurement is used to determine statistical access figures and as a basis for possible VG WORT remuneration. According to VG WORT, no personal usage profiles are created, and the measurement is not used for advertising or marketing tracking. More information is available in our Privacy Notice, which is currently available in German.
Please note: The content provided on this website is for general informational purposes only and does not constitute professional advice, including legal, tax, medical, technical, financial, or other specialist advice. Use of the content is at your own responsibility.
Advertising and Affiliate Links: Some posts may contain promotional references or affiliate links. These are identified accordingly. Clicking such links does not result in any additional cost to you; we may receive a small commission.
Trademark Notice: All brand names, logos, and product names are the property of their respective rights holders and are used solely for identification and descriptive purposes. No affiliation with the companies mentioned is implied unless explicitly stated.
External Links: This website contains links to external third-party websites. Although links are reviewed carefully, we assume no responsibility for the content of external websites. If we become aware of unlawful content, the respective links will be reviewed and removed where appropriate.



tiny-tool.de
tiny-tool.de