Skip to content

Fix Maven parent relativePath naming a dir (#534) - #1789

Merged
Mikola Lysenko (mikolalysenko) merged 6 commits into
mainfrom
agent/fix-maven-parent-relativepath-dir
Oct 28, 2026
Merged

Mikola Lysenko (mikolalysenko) merged 6 commits into
mainfrom
agent/fix-maven-parent-relativepath-dir

Conversation

@mikolalysenko

@mikolalysenko Mikola Lysenko (mikolalysenko) commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

LLM Description written by Claude Code:claude-opus-5-5

Fixes #534

Summary

vex refused a correctly vendored Maven reactor when a module's <parent><relativePath> named a directory (../corp-parent or ..). It printed "cannot establish JVM wiring: corp-parent: … is not a regular file" (or unsafe path "" for ..), left the patch out of the VEX document and exited 1. Maven itself reads a directory relativePath as <dir>/pom.xml, so the build was patched the whole time.

Root cause

maven_reactor::local_parent_of probed the bare relativePath before <path>/pom.xml. During vendor a directory read simply misses, so the pom.xml candidate wins. vex liveness (apply::entry_wired_checked) reads through ProjectReader, and that reader records a directory read, or the empty path .. normalizes to, as a read error. That error withholds liveness.

Fix

  • local_parent_of now looks the parent up the same way resolve_module looks up a <module>: <path>/pom.xml first, then the path itself, and never the empty path. The two call sites share one pom_candidates helper, and the parent pom is parsed from a single read.
  • ProjectReader::read now treats a probe that runs through a regular file (pom.xml/pom.xml, when relativePath names the file) as missing instead of a read error. Without this, the reordered probe would break the common ../pom.xml form. Writes, reverts and the created-dir scan still refuse such a path up front (resolve is unchanged for them).

Scope notes

  • On current main, vendor --check no longer reproduces the refusal: check_entry's Maven path doesn't consult the reader's read error. The capstone now asserts both vex and vendor --check.
  • Not fixed (pre-existing, unchanged by this PR): a relativePath naming a directory that has no pom.xml still reads the directory and records a read error. Maven would fall back to the repository there. It is rare, and fixing it means changing what a directory read means for every JVM planner caller, so I left it out of this PR.

Test evidence (red → green)

Issue case Test Without fix With fix
#534 <relativePath>..</relativePath> vendor::jvm::tests::parent_relative_path_naming_a_directory_stays_checkable Err("unsafe path \"\"") pass
#534 <relativePath>../corp-parent</relativePath> same test, second layout Err("corp-parent: … is not a regular file") pass
#534 real Maven 3.9 reactor (capstone b uses ../corp-parent) e2e_vendor_jvm_build -- --ignored maven_reactor (now runs vex + vendor --check) vex: "corp-parent … is not a regular file", "omitting … vendor_jvm_shape_unsupported", exit 1 2 passed
path through a file reads as missing; writes still refuse it vendor::jvm::apply::tests::a_path_through_a_file_reads_as_missing cannot inspect …/pom.xml/pom.xml: Not a directory pass

Commands run locally:

  • cargo fmt --all -- --check: clean
  • cargo clippy --workspace --all-features -- -D warnings: clean
  • cargo test -p socket-patch-core --all-features --lib: 6864 passed, 4 failed. All 4 are chmod-based failure-injection tests (copy_tree::relax_loop_must_not_traverse_symlinked_root, vlt_heal::an_unremovable_hidden_lock_keeps_every_store_entry, pypi_poetry::wire_write_failure_…, pypi_requirements::wire_failure_rolls_back_…). They can't fail as root, which this container runs as, and they're unrelated to this diff.
  • cargo test -p socket-patch-cli --all-features --test vendor_jvm_cli --test maven_sidecar_cli: 28 + 51 passed
  • cargo test -p socket-patch-cli --all-features --test e2e_vendor_jvm_build -- --ignored maven_reactor (Maven 3.9, real Central): 2 passed
  • The full cargo test --workspace --all-features ran out of the container's disk allowance while building test binaries, so CI covers the remaining suites.
  • /code-review high ran on the diff. Fixed: write-path leniency (resolve stays strict for writes), the duplicated candidate list, and the double read of the parent pom. Not fixed: the directory-without-pom.xml case (above), plus two pre-existing nits outside this change (a redundant group_commit::read call, and the created-dir scan's handling of a file prefix, which is no longer reachable now that writes refuse paths through files).

https://claude.ai/code/session_011f9aeRjLPKxKCvazRF8Ean


Generated by Claude Code

Assisted-by: Claude Code:claude-opus-5-5
vex and vendor --check refused a correctly vendored Maven reactor
when a module's <parent><relativePath> named a directory (..,
../corp-parent): the reactor read the bare path before <dir>/pom.xml
and the project reader counted the directory (or the empty path for
..) as a failed read. Both commands exited 1 although the build used
the patched jar.

The parent is now located like a <module>: <dir>/pom.xml first, then
the path itself, never the empty path. A probe that runs through a
regular file (pom.xml/pom.xml) reads as missing instead of failing.

Fixes #534

Assisted-by: Claude Code:claude-opus-5-5
The reactor capstone's module b names its parent with a directory
relativePath (../corp-parent), the layout from #534, but never ran
vendor --check. Run it after vendoring so a regression shows up
against real Maven too.

Refs #534

Assisted-by: Claude Code:claude-opus-5-5
The capstone's module b names its parent with a directory
relativePath (../corp-parent). Without the reactor fix, vex on that
vendored tree printed "corp-parent is not a regular file", dropped
the patch and exited 1. Assert it attests not_affected now.

Refs #534

Assisted-by: Claude Code:claude-opus-5-5
Review follow-up: only project reads treat a path that runs through
a regular file as missing. Writes, reverts and the created-dir scan
still refuse it before anything is written, as they did before.

Also share the <module>/<relativePath> pom lookup between both call
sites, and parse a local parent from a single read.

Refs #534

Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko
Mikola Lysenko (mikolalysenko) marked this pull request as ready for review October 28, 2026 18:17
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Windows reports a path through a regular file as not found rather
than not-a-directory, so resolve() lets it through there just as it
did before this PR. Only assert the up-front refusal on Unix.

Refs #534

Assisted-by: Claude Code:claude-opus-5-5
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

BugBot review


Generated by Claude Code

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 273eef7. Configure here.

@mikolalysenko Mikola Lysenko (mikolalysenko) added the Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review label Oct 28, 2026
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

Ready for review at 273eef7 (burn-down agent).

  • CI: 50/50 check runs on 273eef7 passed (31 success, 19 skipped), with no main-wide failures. Mergeable, no conflicts.
  • Bugbot: reviewed 273eef7 and found no new issues. All review threads are resolved.
  • CHANGELOG.md is untouched.
  • Reviewer focus: ProjectReader::read now treats a path that runs through a regular file (pom.xml/pom.xml) as missing, not as a read error. Writes still refuse such paths. The directory-without-pom.xml case is deliberately left out of scope (see the description).

Generated by Claude Code

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

Final review brief

What it does
When a Maven module's <parent><relativePath> names a directory (.. or ../corp-parent), vex now reads it as Maven does (<dir>/pom.xml) instead of refusing the reactor with "is not a regular file" / unsafe path "" and leaving the patch out of the VEX document (#534). Parent lookup now uses the same candidate order as <module> lookup, and the JVM project reader treats a read through a regular file (pom.xml/pom.xml) as missing rather than a read error.

Risk: low. Read-side only: writes, reverts and the created-dir scan still go through the strict resolve. The probe order flip only matters when <path>/pom.xml exists, which is exactly the Maven case. The default ../pom.xml form still resolves (first probe reads as missing, the second hits).

Look here

  • apply.rs:178: read now uses the lenient resolve_in(rel, true)
  • apply.rs:242: resolve_in, where through_file turns ENOTDIR into "missing" (Windows already reports NotFound)
  • maven_reactor.rs:1857 and :1891:``` shared pom_candidates; the parent pom is parsed from one read
  • mod.rs:993 and apply.rs:1426: the regression tests for both issue layouts and for the read-vs-write split

Verified

Changes I made: none.

Auto-merge is armed, so approving sends it straight to the merge queue.


Generated by Claude Code

Merged via the queue into main with commit d5f5600 Oct 28, 2026
50 checks passed
@mikolalysenko
Mikola Lysenko (mikolalysenko) deleted the agent/fix-maven-parent-relativepath-dir branch October 28, 2026 21:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review

Projects

None yet

3 participants