ppkarwasz opened a new pull request, #23: URL: https://github.com/apache/commons-xml/pull/23
Adds a `native-xalan` Maven profile that builds the test suite into a GraalVM native image, and a GraalVM entry in the CI matrix that activates it. ## Why `native-image` resolves the JAXP providers at build time under the closed-world assumption, rather than at run time through `ServiceLoader`. That is a different provider-resolution path from anything the JVM matrix exercises, even though the JAXP sources are identical. ## What runs A native binary carries a single classpath, so only `test-stockjdk` runs; the other JAXP combinations stay on the JVM matrix. Saxon-HE is dropped, because its JAXP entry points carry no reachability metadata and every `ServiceLoader` lookup fails on a missing no-arg constructor. That execution already excludes the `xpath3` group, which is the group needing Saxon. ## Why Apache Xalan rather than the stock XSLTC The stock JDK's XSLTC compiles each stylesheet into translet bytecode and defines the class at run time, which a closed-world image cannot do. With XSLTC the transform tests fail on: ``` UnsupportedFeatureError: No classes have been predefined during the image build to load from bytecodes ``` Predefining the translets does not help either. The tracing agent does capture them, and [JDK-8274535](https://bugs.openjdk.org/browse/JDK-8274535) made the generated bytecode deterministic precisely so that GraalVM could match them by hash, but the image builder still rejects the class: ``` VMError$HostedError: Cannot define class die.verwandlung.fixture from byte[0..3019] using class loader: com.oracle.svm.hosted.NativeImageClassLoader ``` Interpretive Xalan needs no bytecode at run time. This is the workaround named on JDK-8274535 itself ("use interpretive xalan (not xsltc) via an external dependency"). Xalan and its serializer are declared as project dependencies rather than through surefire's `additionalClasspathDependencies`, which `native-image` never sees: it builds its classpath from the project's. With them on the classpath, the unmodified `test-stockjdk` execution picks Xalan up for TrAX in both the JVM and the native run. ## Reachability metadata Generated by the tracing agent rather than committed. Xalan reflects on `org.apache.xalan.templates.*` setters and reads its serializer defaults from property files, none of which static analysis sees, and a hand-written config would rot against every Xalan and JDK update. The native binary replays the same tests the JVM run recorded, so the captured metadata covers it by construction. The attack fixtures under `src/test/resources/leaked/` are embedded explicitly with `-H:IncludeResources`, since the agent records only the resources a given run happened to open. The plugin's bundled reachability metadata is disabled: it pins JUnit versions older than the one this project resolves, and its class-initialization directives conflict with them. ## Verification Run locally with GraalVM 21, using the exact command CI runs (the pom's `defaultGoal`, so checkstyle / spotbugs / pmd / javadoc / verify, not just `test`): ``` mvn --errors --show-version --batch-mode --no-transfer-progress -Pnative-xalan ``` `BUILD SUCCESS`: 123 tests on the JVM, and the same 123 in the native binary, zero failures. The default build is unchanged, with all 7 surefire executions green on Temurin 25. The matrix entry pins the latest published GraalVM, 25. That specific version was not exercised locally (the local toolchain has GraalVM 21), so this PR's own CI run is the first check of it. 🤖 Generated with [Claude Code](https://claude.com/claude-code) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
