diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 120000bc..25ef45bc 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,11 +13,11 @@ jobs: - name: Checkout uses: actions/checkout@v4 - - name: Set up JDK 24 + - name: Set up JDK 25 uses: actions/setup-java@v4 with: distribution: oracle - java-version: '24' + java-version: '25' cache: 'maven' - name: Build and verify diff --git a/jdt2jar/Dockerfile b/jdt2jar/Dockerfile index 19433ff1..959a1f66 100644 --- a/jdt2jar/Dockerfile +++ b/jdt2jar/Dockerfile @@ -1,6 +1,6 @@ # syntax=docker/dockerfile:1 -FROM eclipse-temurin:24-jdk AS build +FROM eclipse-temurin:25-jdk AS build WORKDIR /build COPY . . RUN ["./mvnw", "-pl", "jdt2jar", "-am", "package", "-DskipTests", "-Dsurefire.failIfNoSpecifiedTests=false"] @@ -10,6 +10,7 @@ RUN ["mkdir", "-p", "/empty-work/tmp", "/empty-app"] FROM gcr.io/distroless/base-debian13:nonroot COPY --from=build --chown=65532:65532 /empty-work /work COPY --from=build --chown=65532:65532 /empty-app /app +WORKDIR /work ENV JAVA_TOOL_OPTIONS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -Djava.io.tmpdir=/work/tmp -XX:+ExitOnOutOfMemoryError" COPY --from=build /opt/jre /jre COPY --from=build /build/jdt2jar/target/jdt2jar.jar /app/jdt2jar.jar diff --git a/jdt2jar/README.md b/jdt2jar/README.md index 5768c7be..8aef2d29 100644 --- a/jdt2jar/README.md +++ b/jdt2jar/README.md @@ -1,14 +1,14 @@ # jdt2jar -`jdt2jar` compiles a JTD schema into a standalone validator JAR at build time. The generated JAR runs on JDK 21+ with no JDK 24+ runtime dependency. +`jdt2jar` compiles a JTD schema into a standalone validator JAR at build time. The generated JAR runs on JDK 21+ with no JDK 25+ runtime dependency. ## Use Case This tool bridges the gap between the interpreter and codegen paths: - **Interpreter** ([`json-java21-jtd`](../json-java21-jtd/README.md)): ideal for infrequent config parsing — simple, no build step, runs on JDK 21+. -- **Codegen** ([`json-java21-jtd-codegen`](../json-java21-jtd-codegen/README.md)): ideal for repeated hot-path validation — ~9x faster, but requires JDK 24+ at runtime. -- **jdt2jar**: pre-compiles schemas into validator JARs at build time (using JDK 24+), then deploys them to any JDK 21+ runtime. Best for CI/CD pipelines, distroless containers, or environments where you want JIT-optimised validators without shipping a JDK 24+ runtime. +- **Codegen** ([`json-java21-jtd-codegen`](../json-java21-jtd-codegen/README.md)): ideal for repeated hot-path validation — ~9x faster, but requires JDK 25+ at runtime. +- **jdt2jar**: pre-compiles schemas into validator JARs at build time (using JDK 25+), then deploys them to any JDK 21+ runtime. Best for CI/CD pipelines, distroless containers, or environments where you want JIT-optimised validators without shipping a JDK 25+ runtime. > **Future note**: `java.util.json` has entered the JDK incubator (`jdk.incubator.json`). Once the API stabilises in the JDK itself, generated bytecode validators can depend directly on future JDK classes rather than this backport, making them even more efficient with zero library overhead. @@ -35,16 +35,13 @@ A minimal distroless container image is available for offline schema compilation ### Pre-built Image (GitHub Container Registry) ```bash -# Pull the latest image docker pull ghcr.io/simbo1905/java.util.json.java21/jdt2jar:latest - -# Pull a specific release version -docker pull ghcr.io/simbo1905/java.util.json.java21/jdt2jar:2026.02.05 +docker pull ghcr.io/simbo1905/java.util.json.java21/jdt2jar:2026.05.20 ``` ### Build Locally -Requires Docker and JDK 24+ (for the build stage). Build from the repository root: +Requires Docker and JDK 25+ (for the build stage). Build from the repository root: ```bash docker build -t jdt2jar -f jdt2jar/Dockerfile . @@ -52,31 +49,38 @@ docker build -t jdt2jar -f jdt2jar/Dockerfile . ### Usage +The container's working directory is `/work`. Mount your project directory there: + +```bash +docker run --rm -v "$(pwd):/work" jdt2jar:latest schema.jtd.json --output schema-validator.jar --main +``` + +Validate a payload with the generated JAR: + +```bash +java -jar schema-validator.jar --validate payload.json +``` + +Or validate inside a container: + +```bash +docker run --rm -v "$(pwd):/work" --entrypoint /jre/bin/java jdt2jar:latest -jar /work/schema-validator.jar --validate /work/payload.json +``` + +### Helper Script + +For environments where volume mounts are restricted (e.g., Colima on macOS with projects outside `~/`), use the helper script: + ```bash -# Show help -docker run --rm ghcr.io/simbo1905/java.util.json.java21/jdt2jar:latest --help - -# Compile a schema to a validator JAR (using docker cp for file I/O) -cid=$(docker create --name jdt2jar-build ghcr.io/simbo1905/java.util.json.java21/jdt2jar:latest /work/person.jtd.json --output /work/person-validator.jar --main) -docker cp person.jtd.json jdt2jar-build:/work/person.jtd.json -docker start -a jdt2jar-build -docker cp jdt2jar-build:/work/person-validator.jar . -docker rm jdt2jar-build - -# Validate a payload with the generated JAR -java -jar person-validator.jar --validate payload.json -# Or validate inside a container -cid=$(docker create --name jdt2jar-validate --entrypoint /jre/bin/java ghcr.io/simbo1905/java.util.json.java21/jdt2jar:latest -jar /work/person-validator.jar --validate /work/payload.json) -docker cp person-validator.jar jdt2jar-validate:/work/person-validator.jar -docker cp payload.json jdt2jar-validate:/work/payload.json -docker start -a jdt2jar-validate -docker rm jdt2jar-validate +./scripts/jdt2jar.sh schema.jtd.json --output schema-validator.jar --main ``` +The script syncs source to `~/tmp/jdt2jar-work`, runs the container, and syncs output back. + ### Image Properties - **Base**: `gcr.io/distroless/base-debian13:nonroot` -- **Runtime**: jlink-minimized JDK 24 (~40 MB) +- **Runtime**: jlink-minimized JDK 25 LTS (~40 MB) - **Total size**: ~111 MB disk / ~31 MB content - **User**: `nonroot` (uid 65532) - **Shell**: none (distroless) diff --git a/jdt2jar/pom.xml b/jdt2jar/pom.xml index 3b748faa..fd78e2fb 100644 --- a/jdt2jar/pom.xml +++ b/jdt2jar/pom.xml @@ -8,7 +8,7 @@ io.github.simbo1905.json parent - 0.1.9 + 2026.05.20 jdt2jar diff --git a/json-compatibility-suite/pom.xml b/json-compatibility-suite/pom.xml index 338522f5..03e3c708 100644 --- a/json-compatibility-suite/pom.xml +++ b/json-compatibility-suite/pom.xml @@ -7,7 +7,7 @@ io.github.simbo1905.json parent - 0.1.9 + 2026.05.20 json-compatibility-suite diff --git a/json-java21-api-tracker/pom.xml b/json-java21-api-tracker/pom.xml index 591724ea..23c9cc52 100644 --- a/json-java21-api-tracker/pom.xml +++ b/json-java21-api-tracker/pom.xml @@ -7,7 +7,7 @@ io.github.simbo1905.json parent - 0.1.9 + 2026.05.20 json-java21-api-tracker diff --git a/json-java21-jsonpath/pom.xml b/json-java21-jsonpath/pom.xml index aa4b3660..a6ff1722 100644 --- a/json-java21-jsonpath/pom.xml +++ b/json-java21-jsonpath/pom.xml @@ -8,7 +8,7 @@ io.github.simbo1905.json parent - 0.1.9 + 2026.05.20 java.util.json.jsonpath diff --git a/json-java21-jtd-codegen/pom.xml b/json-java21-jtd-codegen/pom.xml index 9a67d57b..7addb5d0 100644 --- a/json-java21-jtd-codegen/pom.xml +++ b/json-java21-jtd-codegen/pom.xml @@ -8,7 +8,7 @@ io.github.simbo1905.json parent - 0.1.9 + 2026.05.20 java.util.json.jtd.codegen diff --git a/json-java21-jtd/pom.xml b/json-java21-jtd/pom.xml index 65bd9a92..e139d9c9 100644 --- a/json-java21-jtd/pom.xml +++ b/json-java21-jtd/pom.xml @@ -8,7 +8,7 @@ io.github.simbo1905.json parent - 0.1.9 + 2026.05.20 java.util.json.jtd diff --git a/json-java21/pom.xml b/json-java21/pom.xml index 70e602ef..e1683552 100644 --- a/json-java21/pom.xml +++ b/json-java21/pom.xml @@ -7,7 +7,7 @@ io.github.simbo1905.json parent - 0.1.9 + 2026.05.20 java.util.json diff --git a/pom.xml b/pom.xml index 6f983d97..d619570a 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ io.github.simbo1905.json parent - 0.1.9 + 2026.05.20 pom java.util.json Java21 Backport Parent diff --git a/scripts/jdt2jar.sh b/scripts/jdt2jar.sh new file mode 100755 index 00000000..7f979cb0 --- /dev/null +++ b/scripts/jdt2jar.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# jdt2jar helper script for environments where volume mounts are restricted +# (e.g., Colima on macOS with projects outside ~/). +# +# Usage: +# ./scripts/jdt2jar.sh [options...] +# +# Example: +# ./scripts/jdt2jar.sh .tmp/test.jtd.json --output .tmp/test.jar --main + +set -euo pipefail + +WORK_DIR="$HOME/tmp/jdt2jar-work" +IMAGE="${JDT2JAR_IMAGE:-jdt2jar:latest}" + +mkdir -p "$WORK_DIR" + +# Sync source (respecting .gitignore) +rsync -a --filter=':- .gitignore' --exclude='.git/' . "$WORK_DIR/" + +# Run jdt2jar in container +docker run --rm -v "$WORK_DIR:/work" "$IMAGE" "$@" + +# Sync output back (any new .jar or .java files in the work dir) +rsync -a --include='*.jar' --include='*.java' --exclude='*' "$WORK_DIR/" ./