Skip to content

Vendored Maven refuses a single-module EAR pom as a multi-module aggregator because two declares_modules disagree #716

Description

[agent] Filed by the scheduled architecture audit routine (ecosystems and formats). Register: discussion #560 register.

Kind: bug. Source: new finding, register E55; child of #715 (E10).

Problem

Vendored Maven decides "is this a reactor?" twice, with two different predicates of the same name:

  1. vendor/jvm/mod.rs#L219-L227 detect routes through maven_reactor::declares_modules. It parses the pom into a `Doc` and counts only `<modules>` / `<subprojects>` whose parent is the project or a profile. Plugin configuration, comments and CDATA don't count, and the test [`plugin_configuration_modules_do_not_make_a_reactor`](https://github.com/SocketDev/socket-patch/blob/045d7ec783d788bf3c5a1310724b51e09fb6505d/crates/socket-patch-core/src/vendor/jvm/maven_reactor.rs#L3783-L3792``) pins that a maven-ear-plugin <configuration><modules> is Shape::Other.
  2. Shape::Other then falls through to the legacy single-pom path. maven_prelude calls the legacy maven_repo::declares_modules,`` which only strips comments and looks for any <modules open tag anywhere, and refuses with `vendor_maven_multimodule_unsupported`.

So every input where the two disagree is refused. A real reactor never reaches the legacy check, because jvm_shape takes it first (vendor_maven L308; the existing test missing_reactor_module_is_refused_without_writes gets vendor_jvm_shape_unsupported, not the legacy code). The legacy refusal fires only on false positives:

  • <modules> inside plugin <configuration>, as in every maven-ear-plugin project (<packaging>ear</packaging>);
  • <modules> inside a CDATA section, for example in a <description>.

Proof by execution (a unit probe in maven_repo::tests using the existing fixture / run_vendor helpers, run twice on 045d7ec, not committed). The pom is a single-module EAR project:

<project xmlns="http://maven.apache.org/POM/4.0.0">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.example</groupId><artifactId>app</artifactId><version>1.0.0</version>
  <packaging>ear</packaging>
  <build><plugins><plugin><artifactId>maven-ear-plugin</artifactId><configuration>
    <modules><jarModule><groupId>x</groupId><artifactId>y</artifactId></jarModule></modules>
  </configuration></plugin></plugins></build>
</project>
PROBE jvm::detect = Other
PROBE reactor::declares_modules = false
PROBE legacy declares_modules = true
PROBE vendor refused vendor_maven_multimodule_unsupported: the root pom.xml declares <modules> (a multi-module aggregator); ...

Symptoms

None filed. Impact: vendor (and scan --mode vendored) refuses every EAR-packaged project with a misleading "multi-module aggregator" error, although neither JVM path treats it as one. The fix is small and removes code.

Proposed change

  • Delete the legacy declares_modules, strip_xml_comments and real_open_tag from vendor/maven_repo.rs (about 45 production lines), along with the vendor_maven_multimodule_unsupported refusal branch in maven_prelude, which is unreachable once the false positives are gone. If a guard is still wanted, call super::jvm::maven_reactor::declares_modules (one predicate).
  • Update CLI_CONTRACT.md (the maven row of the vendored table) to say that aggregators route to the JVM reactor backend, instead of naming the dead code.

Size and scope

vendor/maven_repo.rs and its tests, CLI_CONTRACT.md. About −45 production lines and +30 test lines. Out of scope: the other pom scanners (#715).

Acceptance criteria

  • A regression test: the EAR pom above vendors successfully (or at least is not refused with vendor_maven_multimodule_unsupported), and a pom with <modules> inside a CDATA <description> behaves the same
  • missing_reactor_module_is_refused_without_writes, commented_modules_do_not_refuse and plugin_configuration_modules_do_not_make_a_reactor stay green
  • The legacy declares_modules tests (declares_modules_boundary_and_comment_discipline, declares_modules_fail_closed_edges) are deleted or moved onto the reactor predicate
  • grep -rn 'fn declares_modules' crates finds one definition

Dependencies

None. First child of #715. #690 also edits maven_repo.rs (not this function).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    agent:triagedarch-auditFiled by a scheduled architecture audit routine (see the architecture review discussion)bugSomething isn't workingpm:mavenMavenpriority:p3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions