Skip to content

Treat a model built from a POM file as the project, whatever its validation level - #13394

Merged
slachiewicz merged 1 commit into
maven-3.10.xfrom
agent/pomfile-is-project-mode
Oct 23, 2026
Merged

slachiewicz merged 1 commit into
maven-3.10.xfrom
agent/pomfile-is-project-mode

Conversation

@slachiewicz

@slachiewicz slachiewicz commented Oct 9, 2026 •

Copy link
Copy Markdown
Member

Fixes #13347.

The repository-model restrictions from #12953 (interpolation) and #13114 (profile activation sandbox) decided "this POM came from a repository" by validationLevel < VALIDATION_LEVEL_MAVEN_2_0 alone. IDEs build the user's own project from its POM file at VALIDATION_LEVEL_MINIMAL for leniency (NetBeans MavenEmbedder.readProjectWithDependencies, m2e MavenImpl.readProject), so their projects were sandboxed: -D profile activation stopped working, and maven.model.dependencyInterpolation.full only restored the interpolation half (apache/netbeans#9642).

Both checks now also require getPomFile() == null. ModelBuildingRequest.setPomFile already documents a POM file as project mode, and the repository paths never set one: DefaultArtifactDescriptorReader sets it only for WorkspaceRepository POMs, BOM imports use setModelSource, and DefaultProjectBuilder.build(Artifact) passes a POM file only for a project in the reactor. Callers that set neither keep the validation-level fallback, so nothing changes for the CLI or for repository resolution. No API change.

master needs the equivalent change in the v3 bridge (DefaultProjectBuilder request type), tracked in #13395.

Verified: mvn -pl maven-model-builder,maven-resolver-provider,maven-core -am install → BUILD SUCCESS (maven-core 402 tests). With the main-code change reverted, the new testProjectModeAtMinimalValidationEvaluatesUserPropertyAndFileActivators fails (expected: <activated> but was: <null>). The core ITs covering the hardening (MavenIT0085, mng3586, mng4379, mng4590) have not been run locally.

@gnodet gnodet left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the fix — the IDE regression is real and this unblocks NetBeans/m2e users.

The pomFile == null addition is a pragmatic fix for a heuristic that was always indirect: validationLevel was never designed to carry the "this is a repository model" semantic, and now pomFile is being recruited for the same kind of duty. It works because DefaultArtifactDescriptorReader never sets a POM file for repository POMs, but it's a convention that callers need to know about — a tool that loads a project POM via setModelSource(new FileModelSource(f)) without calling setPomFile() would still be sandboxed.

For context, the v4 model builder (impl/maven-impl) solves this cleanly with RequestType + source provenance (isRepositoryResolved checks whether the source carries coordinates), so there's no heuristic at all. The compat layer can't easily use the same approach without API changes, so the pomFile check is the right tradeoff for 3.10.x and for the compat bridge on master.

A couple of observations:

  1. The setPomFile() Javadoc says it indicates "project mode", but this is the first time it's load-bearing for security-relevant sandboxing. It might be worth adding a note in ModelBuildingRequest.setPomFile() that callers building their own project POM must use setPomFile() (not just setModelSource) to avoid being sandboxed.

  2. In restrictExternalModelInterpolation (the interpolation side), the pomFile check is added but the maven.model.dependencyInterpolation.full escape hatch still exists. Should the escape hatch also restore profile activation, or is the intent that pomFile makes it unnecessary? Right now a caller that can't set pomFile for some reason has no workaround for the profile half.

The fix itself looks correct for the cases it targets. The test coverage (project-at-MINIMAL vs repository-at-MINIMAL) is good.

Claude Code on behalf of Guillaume Nodet

@gnodet

gnodet commented Oct 13, 2026

Copy link
Copy Markdown
Contributor

Fully automatic review from Claude Code

This PR (#13394, fixing #13347) and #13451 (fixing #13390) are complementary fixes to the same externalActivationContext sandbox on maven-3.10.x:

Both are needed. The production code changes are in different methods and merge cleanly. There will be a textual conflict in ResolvedDependencyProfileActivationTest.java since both PRs modify and add tests in the same file — trivial to resolve on rebase.

…dation level

The repository-model sandbox (restricted interpolation, profile activation
without user properties or file activation) keyed only on
validationLevel < MAVEN_2_0. Embedders build their own project at MINIMAL,
so -D profile activation broke for them (#13347). getPomFile() is the
documented project-mode signal; repository models never set it.
@slachiewicz
slachiewicz force-pushed the agent/pomfile-is-project-mode branch from f5f978e to ba9605b Compare October 20, 2026 22:30
@cstamas

cstamas commented Oct 21, 2026

Copy link
Copy Markdown
Member

Why is this draft? Any special reason?

@slachiewicz
slachiewicz marked this pull request as ready for review October 21, 2026 19:05

@gnodet-bot gnodet-bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Clean, minimal, well-tested fix for a real regression affecting IDE embedders (NetBeans, m2e) that build projects at VALIDATION_LEVEL_MINIMAL.

The fix correctly adds getPomFile() == null as an additional guard in both isExternalModelBuildingRequest() and restrictExternalModelInterpolation() — consistently applied. The invariant holds: the documented contract of ModelBuildingRequest.setPomFile already guarantees that repository-resolved POMs never set a POM file, so this is a safe discriminator.

The two new tests form a precise pair — same POM, same validation level, only setPomFile vs setModelSource differs — exactly covering the behavioral change. The PR description confirms the new test was failing before the fix, satisfying pre-fix validation.

The isFullExternalModelBuild opt-out path is preserved and unaffected. Javadoc update is accurate. No compat-layer changes. The companion fix for master's v3 bridge is tracked in #13395.

This review was generated by an AI agent, Hermès on behalf of @gnodet.

@slachiewicz
slachiewicz merged commit d443a15 into maven-3.10.x Oct 23, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working mvn3

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants