Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 3 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,11 @@ This is a simplified backport with the following changes from the original:

These vulnerabilities exist in the upstream OpenJDK sandbox implementation and are reported here for transparency.

## JSON Schema Validator (2020-12)
## JSON Schema Validator

By including a basic schema validator that demonstrates how to build a realistic feature out of the core API. To demonstrate the power of the core API, it follows Data Oriented Programming principles: it parses JSON Schema into an immutable structure of records, then for validation it parses the JSON to the generic structure and uses the thread-safe parsed schema as the model to validate the JSON being checked.

A simple JSON Schema (2020-12 subset) validator is included (module: json-java21-schema).
A simple JSON Schema validator is included (module: json-java21-schema).

```java
var schema = io.github.simbo1905.json.schema.JsonSchema.compile(
Expand Down Expand Up @@ -328,12 +328,9 @@ This backport includes a compatibility report tool that tests against the [JSON

### Running the Compatibility Report

First, build the project and download the test suite:
The test data is bundled as ZIP files and extracted automatically at runtime:

```bash
# Build project and download test suite
mvn clean compile generate-test-resources -pl json-compatibility-suite

# Run human-readable report
mvn exec:java -pl json-compatibility-suite

Expand Down
36 changes: 18 additions & 18 deletions json-compatibility-suite/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,30 +50,30 @@
<build>
<plugins>
<plugin>
<groupId>com.googlecode.maven-download-plugin</groupId>
<artifactId>download-maven-plugin</artifactId>
<executions>
<execution>
<id>download-json-test-suite</id>
<phase>pre-integration-test</phase>
<goals>
<goal>wget</goal>
</goals>
<configuration>
<url>https://github.com/nst/JSONTestSuite/archive/refs/heads/master.zip</url>
<outputDirectory>${project.build.directory}/test-resources</outputDirectory>
<outputFileName>json-test-suite.zip</outputFileName>
<unpack>true</unpack>
</configuration>
</execution>
</executions>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<excludes>
<exclude>src/test/resources/**/*.java</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<exclude>**/JSONTestSuite-20250921/**/*.java</exclude>
<exclude>**/parsers/**/*.java</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.4.1</version>
<configuration>
<mainClass>jdk.sandbox.compatibility.JsonTestSuiteSummary</mainClass>
<mainClass>jdk.sandbox.compatibility.JsonCompatibilitySummary</mainClass>
<includePluginDependencies>false</includePluginDependencies>
</configuration>
</plugin>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,71 @@
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/// Generates a conformance summary report.
/// Run with: mvn exec:java -pl json-compatibility-suite
public class JsonTestSuiteSummary {
/// Test data location: see src/test/resources/json-test-suite-data.zip
public class JsonCompatibilitySummary {

private static final Logger LOGGER = Logger.getLogger(JsonTestSuiteSummary.class.getName());
private static final Path TEST_DIR = Paths.get("json-compatibility-suite/target/test-resources/JSONTestSuite-master/test_parsing");
private static final Logger LOGGER = Logger.getLogger(JsonCompatibilitySummary.class.getName());
private static final Path ZIP_FILE = findZipFile();
private static final Path TARGET_TEST_DIR = Paths.get("target/test-data/json-test-suite/test_parsing");

private static Path findZipFile() {
// Try different possible locations for the ZIP file
Path[] candidates = {
Paths.get("src/test/resources/json-test-suite-data.zip"),
Paths.get("json-compatibility-suite/src/test/resources/json-test-suite-data.zip"),
Paths.get("../json-compatibility-suite/src/test/resources/json-test-suite-data.zip")
};

for (Path candidate : candidates) {
if (Files.exists(candidate)) {
return candidate;
}
}

// If none found, return the first candidate and let it fail with a clear message
return candidates[0];
}

public static void main(String[] args) throws Exception {
boolean jsonOutput = args.length > 0 && "--json".equals(args[0]);
JsonTestSuiteSummary summary = new JsonTestSuiteSummary();
JsonCompatibilitySummary summary = new JsonCompatibilitySummary();
summary.extractTestData();
if (jsonOutput) {
summary.generateJsonReport();
} else {
summary.generateConformanceReport();
}
}

void extractTestData() throws IOException {
if (!Files.exists(ZIP_FILE)) {
throw new RuntimeException("Test data ZIP file not found: " + ZIP_FILE.toAbsolutePath());
}

// Create target directory
Files.createDirectories(TARGET_TEST_DIR.getParent());

// Extract ZIP file
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(ZIP_FILE.toFile()))) {
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
if (!entry.isDirectory() && entry.getName().startsWith("test_parsing/")) {
Path outputPath = TARGET_TEST_DIR.getParent().resolve(entry.getName());
Files.createDirectories(outputPath.getParent());
Files.copy(zis, outputPath, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
}
zis.closeEntry();
}
}
}

void generateConformanceReport() throws Exception {
LOGGER.fine(() -> "Starting conformance report generation");
TestResults results = runTests();
Expand Down Expand Up @@ -84,9 +131,9 @@ void generateJsonReport() throws Exception {
}

private TestResults runTests() throws Exception {
LOGGER.fine(() -> "Walking test files under: " + TEST_DIR.toAbsolutePath());
if (!Files.exists(TEST_DIR)) {
throw new RuntimeException("Test suite not downloaded. Run: ./mvnw clean compile generate-test-resources -pl json-compatibility-suite");
LOGGER.fine(() -> "Walking test files under: " + TARGET_TEST_DIR.toAbsolutePath());
if (!Files.exists(TARGET_TEST_DIR)) {
throw new RuntimeException("Test data not extracted. Run extractTestData() first.");
}

List<String> shouldPassButFailed = new ArrayList<>();
Expand All @@ -98,7 +145,7 @@ private TestResults runTests() throws Exception {
int iAccept = 0, iReject = 0;

List<Path> files;
try (var stream = Files.walk(TEST_DIR)) {
try (var stream = Files.walk(TARGET_TEST_DIR)) {
files = stream
.filter(p -> p.toString().endsWith(".json"))
.sorted()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,26 @@
public class DownloadVerificationTest {
@Test
void testSuiteDownloaded() {
Path testDir = Paths.get("target/test-resources/JSONTestSuite-master/test_parsing");
assertThat(testDir)
.as("JSON Test Suite should be downloaded and extracted")
.exists()
.isDirectory();

// Verify some test files exist
assertThat(testDir.resolve("y_structure_whitespace_array.json"))
.as("Should contain valid test files")
.exists();
// The test data is now extracted from ZIP at runtime
// Create a summary instance and extract the data manually for testing
try {
JsonCompatibilitySummary summary = new JsonCompatibilitySummary();
summary.extractTestData();

// Verify the target directory exists after extraction
Path targetDir = Paths.get("target/test-data/json-test-suite/test_parsing");
assertThat(targetDir)
.as("JSON Test Suite should be extracted to target directory")
.exists()
.isDirectory();

// Verify some test files exist
assertThat(targetDir.resolve("y_valid_sample.json"))
.as("Should contain valid test files")
.exists();

} catch (Exception e) {
throw new RuntimeException("Failed to extract JSON test suite data", e);
}
}
}

This file was deleted.

Binary file not shown.
30 changes: 0 additions & 30 deletions json-java21-schema/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -96,36 +96,6 @@
</includes>
</configuration>
</plugin>

<!-- Download & unzip the official test-suite -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>fetch-json-schema-suite</id>
<phase>pre-integration-test</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<mkdir dir="${project.build.directory}/json-schema-test-suite"/>
<get src="https://github.com/json-schema-org/JSON-Schema-Test-Suite/archive/refs/tags/23.1.0.zip"
dest="${project.build.directory}/json-schema-test-suite.zip"
skipexisting="true"/>
<unzip src="${project.build.directory}/json-schema-test-suite.zip"
dest="${project.build.directory}/json-schema-test-suite"
overwrite="false"/>
<!-- Rename the extracted directory for stable path -->
<move file="${project.build.directory}/json-schema-test-suite/JSON-Schema-Test-Suite-23.1.0"
tofile="${project.build.directory}/json-schema-test-suite"/>
</target>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Loading
Loading