Review fixes-javac-fail PRs
These PRs repair test sources or test dependencies after an existing library is bumped and the new version no longer compiles with the old test code. Review them more lightly than library-new-request PRs: the library already exists, so the goal is to preserve working coverage across the version update rather than prove a brand-new metadata contribution from scratch.
The rules below implement the contribution contract: block only on a concrete violation of a must — the shape limits (§FS-contribution-contract.2), the coverage gates (§FS-contribution-contract.3), the cheating patterns (§FS-contribution-contract.4), and the test contract's musts (§FS-test-contract) — while shoulds stay advisory in review (§FS-contribution-contract.1).
Chunked dynamic-access PRs
When the PR has the chunked-dynamic-access label, skip every repair coverage
comparison in this skill, including for the final chunk. Request changes for
coverage only when the reported dynamicAccess.coveredCalls is 0. Keep every
non-coverage rule. §FS-contribution-contract.3
The PR number or URL can be passed as an optional argument (for example, 1234, https://github.com/oracle/graalvm-reachability-metadata/pull/1234). If the user says "review this PR" without an argument, infer the PR from the surrounding conversation or gh pr status; only ask the user when it cannot be inferred. Use gh pr view <pr>, gh pr diff <pr>, and gh pr checks <pr> against the resolved PR throughout the workflow below.
Review Principles
- Confirm the PR has label
fixes-javac-fail.
- Expect compile-focused changes plus the normal generated support files for the newly tested version: test source updates, imports, renamed APIs, dependency adjustments, a new metadata-version directory, stats, and metadata index changes.
- Be more relaxed than
library-new-request: do not reject only because a test resembles older coverage, stays in an existing package layout, or contains compatibility branches for multiple supported versions.
- Do not accept changes that remove meaningful test coverage just to make
javac pass.
- Native-image execution should remain enabled by default when the repaired test reaches the native lane. Do not accept changes that skip or short-circuit native-image behavior. When a test exercises behavior that fundamentally relies on open-ended dynamic class loading that native image cannot support, such as loading classes, JARs, generated bytecode, plugin implementations, or other class definitions that are only discovered after the native executable is built, accept the
NativeImageSupport.isUnsupportedFeatureError(e) catch pattern from org.graalvm.internal.tck. Reject raw native-only skips, bare catch (Error) blocks, and use of this pattern for ordinary reflection, resources, serialization, dynamic proxies, JNI, or missing reachability metadata.
- Treat dynamic-access coverage preservation as the main quality gate. Apply the
ordered repair comparison in the workflow below independently to the overall
report and every breakdown present in either version.
- Use the reported stats evidence as-is. Do not inspect generation filters,
agent configuration, or metadata contents to second-guess the reported
totalCalls, coveredCalls, or coverage ratios.
- Treat metadata entry counts as telemetry only. Never request changes or apply
human-intervention because the new version reports fewer metadata entries.
- A new version that reports zero total dynamic-access calls has no comparable
call surface and passes the numeric coverage gate. The compile fix itself must still pass and must not be made green by
deleting meaningful coverage or disabling native-image behavior.
- Accept only
reachability-metadata.json files as metadata files. Reject legacy native-image metadata config files such as reflect-config.json, resource-config.json, proxy-config.json, serialization-config.json, jni-config.json, or predefined-classes-config.json.
- Prefer small, targeted review comments. This label is for repair work, not a full redesign of historical tests.
Workflow
Inspect the PR summary.
- Resolve the target PR from the optional argument, or infer it from context when possible.
- Confirm the PR has label
fixes-javac-fail.
- Identify the target coordinate, the previous tested version, and the new tested version from the PR body, title, changed
index.json, and changed test path.
- Gather files, reviews, inline comments, and CI checks.
Validate the diff scope.
- Expected files are usually limited to the target coordinate's generated new-version support:
metadata/<group>/<artifact>/<new-version>/reachability-metadata.json
metadata/<group>/<artifact>/index.json
stats/<group>/<artifact>/<new-version>/stats.json
tests/src/<group>/<artifact>/<new-version>/**
- Accept compatibility edits that keep one test source working across multiple tested versions.
- Treat a new
reachability-metadata.json for the tested version as normal for this label, including {} when validation and stats are coherent.
- Treat generated test project files such as
.gitignore, build.gradle, gradle.properties, settings.gradle, and user-code-filter.json as normal when they live under the target version's test directory.
- Be suspicious of unrelated build logic, workflows, generated sources, other libraries, or broad refactors.
- Reject legacy native-image metadata config files. Metadata for generated support and test-only metadata must use
reachability-metadata.json.
- Reject or request changes if the PR removes tests, disables test classes, catches and ignores the failing exception, or disables native-image behavior.
- Accept the
NativeImageSupport.isUnsupportedFeatureError(e) catch pattern for tests that exercise behavior fundamentally requiring unsupported open-ended dynamic class loading. Reject bare catch (Error) blocks without the isUnsupportedFeatureError verification.
Review the compile fix.
- Confirm the edit addresses the actual Java compilation failure, such as renamed classes, changed method signatures, module boundaries, annotation processors, or dependency coordinates.
- Compatibility branches are acceptable when they keep older and newer tested versions covered by the same test.
- Version-specific logic is acceptable when the upstream API genuinely changed, but it should be narrow and documented by the code structure or assertions.
- Do not require the stricter
library-new-request rules about scaffold-only tests or test package placement unless the PR is also adding a new library.
Check dynamic-access coverage across versions.
- Compare
stats/<group>/<artifact>/<old-metadata-version>/stats.json and
stats/<group>/<artifact>/<new-metadata-version>/stats.json when stats are
present in the PR or available on the branch.
- Apply the following ordered comparison independently to the overall
dynamicAccess report and every dynamicAccess.breakdown scope present in
either version. Treat N/A on either side as 0/0: zero totalCalls and
zero coveredCalls.
- Pass when the new scope reports
totalCalls == 0.
- Fail when the new scope reports
totalCalls > 0 and coveredCalls == 0.
- Pass when new
coveredCalls is at least old coveredCalls, or when the
new coverage percentage is at least the old percentage.
- When both scopes report fewer than 10
totalCalls, fail only when old
coveredCalls - new coveredCalls > 2.
- Otherwise, fail only when coverage drops by more than 20 percentage
points.
- Reach step 4 only after both covered calls and percentage decreased, so the
subtraction is always positive. A failing scope is blocking unless the PR
gives a concrete, credible explanation of the changed upstream surface.
- For every failing scope, inspect the old and new stats and the test diff,
then relevant upstream API/runtime or CI evidence, before deciding. State
the evidence-backed cause. If the evidence does not establish one, say
Cause not established from the available evidence and ask for an
explanation. Never guess or present speculation as the cause.
- For reference:
8/8 -> 7/9 and 8/8 -> 6/9 pass the small-report rule;
8/8 -> 5/9 fails it; 10/10 -> 15/20 passes because covered calls grew;
and 20/20 -> 15/20 fails the large-report rule.
- Do not compare metadata entry counts; they are telemetry, not a review gate.
- If required old or new stats are missing or stale, ask for
generateLibraryStats or the relevant CI stats job before approving.
Check CI before deciding.
- Expected minimum:
compileTestJava or equivalent changed-metadata compile checks are green for the target coordinate.
- Prefer seeing the full target
test lane green because a compile fix can still reduce runtime or native coverage.
- If current-defaults and future-defaults lanes both run, both should pass unless the PR clearly targets only one failing lane and the other failure is unrelated infrastructure noise.
- If CI is flaky but the diff and coverage comparison are sound, ask for a rerun instead of blocking on speculation.
Disposition
Finding a violation is half the review. Read §FS-contribution-contract.5 and take the disposition it assigns — grund FS-contribution-contract.5 --full, or section 5 of docs/functional-spec/contribution-contract.md in the checkout. That section is authoritative and this table is only a dispatch: it tells you which case you are in, not what the case permits. You are the party that acts, because the PR was generated and no author is waiting to answer a review comment.
| Case |
When |
What you do |
| 5.1 |
The violation is in the PR's own metadata/, stats/, and tests/src/ files |
Repair it on the PR head, push, re-run the affected checks, and say what you changed and why |
| 5.2 |
The only possible fix is build logic, harness code, workflows, or another coordinate |
Do not repair there; revert such a change if the PR already carries one, then take 5.3 |
| 5.3 |
The cause is a defect in shared repository code |
Find or open one issue for the defect, comment that the PR is blocked on it rather than on its own content, then take 5.5 |
| 5.4 |
The library's dynamic access is reachable only through behavior Native Image cannot support |
Close the PR, label the linked issue library-unsupported-version, and close that issue |
| 5.5 |
Anything else, uncertainty included |
Label the PR human-intervention and comment with the rule at issue, what you tried, and what you could not decide |
Never close a PR under any case but 5.4. Read §FS-contribution-contract.5.1 before you repair: it bounds what a repair may do, and it carries the one exception that lets you drop a test scenario rather than fix it.
Decision Rules
These decide the verdict. Disposition above decides what you then do with it: a violation you can correct inside the PR's own files is repaired and pushed, not requested from an author who is not there.
Approve when all of these are true:
- The PR is scoped to the target existing library and the compile failure it fixes.
- Tests still exercise the same meaningful library behavior after the compile repair.
- The overall report and every breakdown pass the ordered repair coverage gate, or any failing scope is convincingly explained by a changed upstream surface.
- Required compile and metadata test checks are green.
Request changes when any of these are true:
- The fix makes compilation pass by weakening or bypassing the test instead of adapting it to the changed API while preserving meaningful coverage.
- The fix disables native-image behavior instead of using the
NativeImageSupport.isUnsupportedFeatureError(e) catch pattern for unsupported open-ended dynamic class loading.
- The overall report or a breakdown fails the ordered repair coverage gate without a credible explanation and replacement coverage.
- CI failures indicate the compile problem is not actually fixed.
Ask for follow-up instead of rejecting when:
- Stats needed for the old/new version comparison are missing or stale.
- CI failed in a way that looks like infrastructure noise. A transient external failure is waited out; a reproducible defect in the repository's own code is case 5.3 of Disposition (§FS-contribution-contract.5.3).
- A failing repair-coverage scope may reflect a plausible upstream API or runtime change, but the PR does not explain it.
Output Style
Keep comments short and factual:
- For coverage failures: name the failing overall or breakdown scope, report old
and new
coveredCalls, totalCalls, and percentages, and identify whether it
failed the zero-covered, small-report, or large-report rule. Ask for restored
coverage or a concrete explanation. Explain why the regression happened
using evidence from the stats, test diff, upstream changes, or CI. If the
cause cannot be established, say so explicitly and request an explanation;
never guess. Do not report a change that an earlier step of the ordered gate
accepts.
- For deleted coverage: say that the PR fixes compilation by removing coverage and should instead adapt the test to the new API.
- For native skips that does not depend on the open-ended dynamic class loading: say that the PR avoids the failing native path instead of fixing it, so it does not demonstrate native-image runtime coverage.
- For unverified
catch (Error): say that dynamic class loading tests should verify Native Image failures with NativeImageSupport.isUnsupportedFeatureError(e) and re-throw any other error.
- For version-pinned tests: say that tests should not reference the exact library version because the same test should support multiple library versions.
- For unrelated changes: say the PR should stay scoped to the
fixes-javac-fail repair and remove unrelated files.
- For legacy metadata files: say that metadata must use
reachability-metadata.json and ask for old config files such as reflect-config.json or resource-config.json to be replaced.
- For missing stats: ask for regenerated library stats or CI evidence before approval.
Examples
Use these examples as representative patterns, not exhaustive matchers.
- Bad compile repair that removes coverage:
@Test
void parsesDocument() {
// Removed assertions because the new API no longer compiles.
}
@Test
void parsesDocument() {
assumeFalse("runtime".equals(System.getProperty("org.graalvm.nativeimage.imagecode")));
Document document = Parser.parse("name=value");
assertThat(document.get("name")).isEqualTo("value");
}
- Approved dynamic-class-loading pattern:
@Test
void loadsGeneratedHandlerClass() throws Exception {
try {
Class<?> handlerClass = compileAndLoadHandler();
assertThat(HandlerRegistry.register(handlerClass).name()).isEqualTo("generated");
} catch (Error e) {
if (!NativeImageSupport.isUnsupportedFeatureError(e)) {
throw e;
}
// Expected: Native Image cannot load generated classes discovered after build.
}
}
- Bad version-pinned assertion:
@Test
void reportsVersion() {
assertThat(LibraryVersion.current()).isEqualTo("1.2.3");
}
1---2name: review-fixes-javac-fail3description: Review pull requests with the `fixes-javac-fail` label in graalvm-reachability-metadata. Use when asked to review or triage a PR that fixes Java compilation failures for an existing library version update. Focus on validating the compile fix, keeping the diff scoped, and applying the repair coverage gate to overall and breakdown dynamic-access reports.4---56# Review `fixes-javac-fail` PRs78These PRs repair test sources or test dependencies after an existing library is bumped and the new version no longer compiles with the old test code. Review them more lightly than `library-new-request` PRs: the library already exists, so the goal is to preserve working coverage across the version update rather than prove a brand-new metadata contribution from scratch.910The rules below implement the contribution contract: block only on a concrete violation of a must — the shape limits (§FS-contribution-contract.2), the coverage gates (§FS-contribution-contract.3), the cheating patterns (§FS-contribution-contract.4), and the test contract's musts (§FS-test-contract) — while shoulds stay advisory in review (§FS-contribution-contract.1).1112## Chunked dynamic-access PRs1314When the PR has the `chunked-dynamic-access` label, skip every repair coverage15comparison in this skill, including for the final chunk. Request changes for16coverage only when the reported `dynamicAccess.coveredCalls` is `0`. Keep every17non-coverage rule. §FS-contribution-contract.31819The PR number or URL can be passed as an optional argument (for example, `1234`, `https://github.com/oracle/graalvm-reachability-metadata/pull/1234`). If the user says "review this PR" without an argument, infer the PR from the surrounding conversation or `gh pr status`; only ask the user when it cannot be inferred. Use `gh pr view <pr>`, `gh pr diff <pr>`, and `gh pr checks <pr>` against the resolved PR throughout the workflow below.2021## Review Principles2223- Confirm the PR has label `fixes-javac-fail`.24- Expect compile-focused changes plus the normal generated support files for the newly tested version: test source updates, imports, renamed APIs, dependency adjustments, a new metadata-version directory, stats, and metadata index changes.25- Be more relaxed than `library-new-request`: do not reject only because a test resembles older coverage, stays in an existing package layout, or contains compatibility branches for multiple supported versions.26- Do not accept changes that remove meaningful test coverage just to make `javac` pass.27- Native-image execution should remain enabled by default when the repaired test reaches the native lane. Do not accept changes that skip or short-circuit native-image behavior. When a test exercises behavior that fundamentally relies on open-ended dynamic class loading that native image cannot support, such as loading classes, JARs, generated bytecode, plugin implementations, or other class definitions that are only discovered after the native executable is built, accept the `NativeImageSupport.isUnsupportedFeatureError(e)` catch pattern from `org.graalvm.internal.tck`. Reject raw native-only skips, bare `catch (Error)` blocks, and use of this pattern for ordinary reflection, resources, serialization, dynamic proxies, JNI, or missing reachability metadata.28- Treat dynamic-access coverage preservation as the main quality gate. Apply the29 ordered repair comparison in the workflow below independently to the overall30 report and every breakdown present in either version.31- Use the reported stats evidence as-is. Do not inspect generation filters,32 agent configuration, or metadata contents to second-guess the reported33 `totalCalls`, `coveredCalls`, or coverage ratios.34- Treat metadata entry counts as telemetry only. Never request changes or apply35 `human-intervention` because the new version reports fewer metadata entries.36- A new version that reports zero total dynamic-access calls has no comparable37 call surface and passes the numeric coverage gate. The compile fix itself must still pass and must not be made green by38 deleting meaningful coverage or disabling native-image behavior.39- Accept only `reachability-metadata.json` files as metadata files. Reject legacy native-image metadata config files such as `reflect-config.json`, `resource-config.json`, `proxy-config.json`, `serialization-config.json`, `jni-config.json`, or `predefined-classes-config.json`.40- Prefer small, targeted review comments. This label is for repair work, not a full redesign of historical tests.4142## Workflow43441. Inspect the PR summary.45 - Resolve the target PR from the optional argument, or infer it from context when possible.46 - Confirm the PR has label `fixes-javac-fail`.47 - Identify the target coordinate, the previous tested version, and the new tested version from the PR body, title, changed `index.json`, and changed test path.48 - Gather files, reviews, inline comments, and CI checks.49502. Validate the diff scope.51 - Expected files are usually limited to the target coordinate's generated new-version support:52 - `metadata/<group>/<artifact>/<new-version>/reachability-metadata.json`53 - `metadata/<group>/<artifact>/index.json`54 - `stats/<group>/<artifact>/<new-version>/stats.json`55 - `tests/src/<group>/<artifact>/<new-version>/**`56 - Accept compatibility edits that keep one test source working across multiple tested versions.57 - Treat a new `reachability-metadata.json` for the tested version as normal for this label, including `{}` when validation and stats are coherent.58 - Treat generated test project files such as `.gitignore`, `build.gradle`, `gradle.properties`, `settings.gradle`, and `user-code-filter.json` as normal when they live under the target version's test directory.59 - Be suspicious of unrelated build logic, workflows, generated sources, other libraries, or broad refactors.60 - Reject legacy native-image metadata config files. Metadata for generated support and test-only metadata must use `reachability-metadata.json`.61 - Reject or request changes if the PR removes tests, disables test classes, catches and ignores the failing exception, or disables native-image behavior.62 - Accept the `NativeImageSupport.isUnsupportedFeatureError(e)` catch pattern for tests that exercise behavior fundamentally requiring unsupported open-ended dynamic class loading. Reject bare `catch (Error)` blocks without the `isUnsupportedFeatureError` verification.63643. Review the compile fix.65 - Confirm the edit addresses the actual Java compilation failure, such as renamed classes, changed method signatures, module boundaries, annotation processors, or dependency coordinates.66 - Compatibility branches are acceptable when they keep older and newer tested versions covered by the same test.67 - Version-specific logic is acceptable when the upstream API genuinely changed, but it should be narrow and documented by the code structure or assertions.68 - Do not require the stricter `library-new-request` rules about scaffold-only tests or test package placement unless the PR is also adding a new library.69704. Check dynamic-access coverage across versions.71 - Compare `stats/<group>/<artifact>/<old-metadata-version>/stats.json` and72 `stats/<group>/<artifact>/<new-metadata-version>/stats.json` when stats are73 present in the PR or available on the branch.74 - Apply the following ordered comparison independently to the overall75 `dynamicAccess` report and every `dynamicAccess.breakdown` scope present in76 either version. Treat `N/A` on either side as `0/0`: zero `totalCalls` and77 zero `coveredCalls`.78 1. Pass when the new scope reports `totalCalls == 0`.79 2. Fail when the new scope reports `totalCalls > 0` and `coveredCalls == 0`.80 3. Pass when new `coveredCalls` is at least old `coveredCalls`, or when the81 new coverage percentage is at least the old percentage.82 4. When both scopes report fewer than 10 `totalCalls`, fail only when old83 `coveredCalls - new coveredCalls > 2`.84 5. Otherwise, fail only when coverage drops by more than 20 percentage85 points.86 - Reach step 4 only after both covered calls and percentage decreased, so the87 subtraction is always positive. A failing scope is blocking unless the PR88 gives a concrete, credible explanation of the changed upstream surface.89 - For every failing scope, inspect the old and new stats and the test diff,90 then relevant upstream API/runtime or CI evidence, before deciding. State91 the evidence-backed cause. If the evidence does not establish one, say92 `Cause not established from the available evidence` and ask for an93 explanation. Never guess or present speculation as the cause.94 - For reference: `8/8 -> 7/9` and `8/8 -> 6/9` pass the small-report rule;95 `8/8 -> 5/9` fails it; `10/10 -> 15/20` passes because covered calls grew;96 and `20/20 -> 15/20` fails the large-report rule.97 - Do not compare metadata entry counts; they are telemetry, not a review gate.98 - If required old or new stats are missing or stale, ask for99 `generateLibraryStats` or the relevant CI stats job before approving.1001015. Check CI before deciding.102 - Expected minimum: `compileTestJava` or equivalent changed-metadata compile checks are green for the target coordinate.103 - Prefer seeing the full target `test` lane green because a compile fix can still reduce runtime or native coverage.104 - If current-defaults and future-defaults lanes both run, both should pass unless the PR clearly targets only one failing lane and the other failure is unrelated infrastructure noise.105 - If CI is flaky but the diff and coverage comparison are sound, ask for a rerun instead of blocking on speculation.106107## Disposition108109Finding a violation is half the review. **Read §FS-contribution-contract.5 and take the disposition it assigns** — `grund FS-contribution-contract.5 --full`, or section 5 of `docs/functional-spec/contribution-contract.md` in the checkout. That section is authoritative and this table is only a dispatch: it tells you which case you are in, not what the case permits. You are the party that acts, because the PR was generated and no author is waiting to answer a review comment.110111| Case | When | What you do |112|---|---|---|113| 5.1 | The violation is in the PR's own `metadata/`, `stats/`, and `tests/src/` files | Repair it on the PR head, push, re-run the affected checks, and say what you changed and why |114| 5.2 | The only possible fix is build logic, harness code, workflows, or another coordinate | Do not repair there; revert such a change if the PR already carries one, then take 5.3 |115| 5.3 | The cause is a defect in shared repository code | Find or open one issue for the defect, comment that the PR is blocked on it rather than on its own content, then take 5.5 |116| 5.4 | The library's dynamic access is reachable only through behavior Native Image cannot support | Close the PR, label the linked issue `library-unsupported-version`, and close that issue |117| 5.5 | Anything else, uncertainty included | Label the PR `human-intervention` and comment with the rule at issue, what you tried, and what you could not decide |118119Never close a PR under any case but 5.4. Read §FS-contribution-contract.5.1 before you repair: it bounds what a repair may do, and it carries the one exception that lets you drop a test scenario rather than fix it.120121## Decision Rules122123These decide the verdict. **Disposition** above decides what you then do with it: a violation you can correct inside the PR's own files is repaired and pushed, not requested from an author who is not there.124125Approve when all of these are true:126127- The PR is scoped to the target existing library and the compile failure it fixes.128- Tests still exercise the same meaningful library behavior after the compile repair.129- The overall report and every breakdown pass the ordered repair coverage gate, or any failing scope is convincingly explained by a changed upstream surface.130- Required compile and metadata test checks are green.131132Request changes when any of these are true:133134- The fix makes compilation pass by weakening or bypassing the test instead of adapting it to the changed API while preserving meaningful coverage.135- The fix disables native-image behavior instead of using the `NativeImageSupport.isUnsupportedFeatureError(e)` catch pattern for unsupported open-ended dynamic class loading.136- The overall report or a breakdown fails the ordered repair coverage gate without a credible explanation and replacement coverage.137- CI failures indicate the compile problem is not actually fixed.138139Ask for follow-up instead of rejecting when:140141- Stats needed for the old/new version comparison are missing or stale.142- CI failed in a way that looks like infrastructure noise. A transient external failure is waited out; a reproducible defect in the repository's own code is case 5.3 of **Disposition** (§FS-contribution-contract.5.3).143- A failing repair-coverage scope may reflect a plausible upstream API or runtime change, but the PR does not explain it.144145## Output Style146147Keep comments short and factual:148149- For coverage failures: name the failing overall or breakdown scope, report old150 and new `coveredCalls`, `totalCalls`, and percentages, and identify whether it151 failed the zero-covered, small-report, or large-report rule. Ask for restored152 coverage or a concrete explanation. Explain why the regression happened153 using evidence from the stats, test diff, upstream changes, or CI. If the154 cause cannot be established, say so explicitly and request an explanation;155 never guess. Do not report a change that an earlier step of the ordered gate156 accepts.157- For deleted coverage: say that the PR fixes compilation by removing coverage and should instead adapt the test to the new API.158- For native skips that does not depend on the open-ended dynamic class loading: say that the PR avoids the failing native path instead of fixing it, so it does not demonstrate native-image runtime coverage.159- For unverified `catch (Error)`: say that dynamic class loading tests should verify Native Image failures with `NativeImageSupport.isUnsupportedFeatureError(e)` and re-throw any other error.160- For version-pinned tests: say that tests should not reference the exact library version because the same test should support multiple library versions.161- For unrelated changes: say the PR should stay scoped to the `fixes-javac-fail` repair and remove unrelated files.162- For legacy metadata files: say that metadata must use `reachability-metadata.json` and ask for old config files such as `reflect-config.json` or `resource-config.json` to be replaced.163- For missing stats: ask for regenerated library stats or CI evidence before approval.164165## Examples166167Use these examples as representative patterns, not exhaustive matchers.168169- Bad compile repair that removes coverage:170171```java172@Test173void parsesDocument() {174 // Removed assertions because the new API no longer compiles.175}176```177178- Bad native-image skip:179180```java181@Test182void parsesDocument() {183 assumeFalse("runtime".equals(System.getProperty("org.graalvm.nativeimage.imagecode")));184185 Document document = Parser.parse("name=value");186 assertThat(document.get("name")).isEqualTo("value");187}188```189190- Approved dynamic-class-loading pattern:191192```java193@Test194void loadsGeneratedHandlerClass() throws Exception {195 try {196 Class<?> handlerClass = compileAndLoadHandler();197 assertThat(HandlerRegistry.register(handlerClass).name()).isEqualTo("generated");198 } catch (Error e) {199 if (!NativeImageSupport.isUnsupportedFeatureError(e)) {200 throw e;201 }202 // Expected: Native Image cannot load generated classes discovered after build.203 }204}205```206207- Bad version-pinned assertion:208209```java210@Test211void reportsVersion() {212 assertThat(LibraryVersion.current()).isEqualTo("1.2.3");213}214```