Skip to content

fix(maven): 子模块继承父 POM build plugins 以识别 Spring Boot 服务 (#942) - #1017

Open
chdtiger wants to merge 3 commits into
1lck:previewfrom
chdtiger:fix/942-maven-parent-plugin-inheritance
Open

chdtiger wants to merge 3 commits into
1lck:previewfrom
chdtiger:fix/942-maven-parent-plugin-inheritance

Conversation

@chdtiger

@chdtiger chdtiger commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

关联 Issue

#942

根因

Maven 会把父 POM 的 <build><plugins> 合并进每个子模块,但 declared_modules 只收集模块自身 POM 的 plugins。

rust/lithe-core/src/execution/detectors/maven.rs 的 service_provider() 依赖 DeclaredModule::applies_plugin() 判断框架 plugin,因此:

  • 父 POM(packaging=pom)声明 spring-boot-maven-plugin
  • 子模块只写 <parent>,自己不声明
  • → 子模块 plugins 为空 → 不会产出 spring-boot.maven service → 落入普通 java.main

改动内容

rust/lithe-core/src/project/maven.rs(+38 / -3)

  1. Descriptor 增加 parent_artifact_id,记录 <parent><artifactId>
  2. descriptor() 新增 project/parent/artifactId 解析分支 —— 该字段此前完全未被解析
  3. collect_modules() 增加 inherited_plugins 参数,沿 reactor 递归链逐层合并去重

沿 reactor 树传递而非按坐标匹配,因此天然覆盖:

  • 多级嵌套(曾祖父 → 父 → 子)
  • <relativePath> 显式书写或省略(默认即 ../pom.xml)
  • 子模块未写全 groupId 的常见写法

语义边界

继承集合只来自 project/build/plugins,<pluginManagement> 声明的 plugin 依旧不激活 —— 因为 descriptor 本身就不收集该路径。新增回归测试锁定这一点,避免"修好继承"的同时引入"pluginManagement 误激活"的新问题。

现有测试 maven_detector_skips_the_aggregator_that_configures_its_children(聚合器自身不作为服务)与继承语义正确共存。

验证

自动化检查

检查 结果
cargo test --lib maven -- --test-threads=1 89 passed / 0 failed
cargo test --lib(全量单线程) 751 passed / 0 failed
cargo fmt --check 通过
scripts/verify-platform-feature-matrix-change.sh 通过
scripts/verify-platform-feature-matrix.sh 通过

新增回归测试

  • maven_detector_inherits_the_boot_plugin_from_the_aggregator —— 单级继承
  • maven_detector_inherits_the_boot_plugin_across_several_levels —— 多级嵌套 + 显式 relativePath
  • maven_detector_does_not_inherit_a_plugin_managed_parent —— pluginManagement 保持不生效

真实项目 A/B 对照

构造最小 Spring Boot 多模块项目(父 POM 声明 plugin,两个子模块只写 <parent>),直接调用 lithe_core::execute_json("runConfig.generate") —— 即应用内部同一条代码路径:

识别结果
修复前(origin/preview) detected 0 run configuration(s)
修复后 detected 2,均为 spring-boot.maven

修复前一个运行配置都识别不出来,与 #942 描述的"子模块被识别成其他运行配置"一致。

平台功能矩阵

rust/lithe-core 属受管路径且本改动影响用户可观察的服务识别,因此更新 shared/platform-feature-matrix.json 的 run-discovery 行(evidence 与 verification),并重新生成 platform-parity-matrix.md / .csv。未使用 matrix-exempt。

未覆盖的部分

#942 的第二项"启动后无法手动停止"本次未处理。owner 已指出该问题可能与识别错误同源,也可能独立;本 PR 只修复配置识别,停止行为需要真实启动 Java 服务后另行验证。

liqiuhu added 2 commits October 1, 2026 18:35
1lck#942 报告 Spring Boot 多模块项目中,子模块因未直接声明 spring-boot-maven-plugin
而被识别成普通运行配置、服务无法启动。

Maven 会把父 POM 的 <build><plugins> 合并进每个子模块,但 declared_modules
只收集模块自身 POM 的 plugins,导致 service_provider() 看不到继承来的框架
plugin,detector 便不会为该模块产出 spring-boot.maven service。

改动:
- Descriptor 记录 <parent><artifactId>,descriptor() 解析此前被忽略的
  project/parent/artifactId;
- collect_modules() 沿 reactor 递归链传递 inherited_plugins,逐层合并去重,
  天然覆盖多级嵌套且不依赖 relativePath 是否显式书写。

语义边界:继承集合仍然只来自 project/build/plugins,因此 <pluginManagement>
声明的 plugin 依旧不激活——新增回归测试锁定这一点。

验证:
- cargo test --lib maven:89 passed / 0 failed
- cargo test --lib(单线程全量):751 passed / 0 failed
- cargo fmt --check 通过;
- 真实 Spring Boot 多模块项目 A/B 对照:修复前识别 0 个运行配置,修复后识别出
  2 个 spring-boot.maven 服务。
@ghfind-review ghfind-review Bot added the review: low ghfind author score; see https://ghfind.com label Oct 1, 2026

@1lck 1lck left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

已按仓库 lithe-code-review / develop-lithe 规则审查。结论:存在运行配置误识别问题,建议修复后合并。当前无文本合并冲突。

审查 head:a2c7229b52f97e009fa1d146f11c3ce24ec0fd81,共 5 个变更文件及直接调用链。

1. [P1] 将 Maven 聚合关系当成继承关系,导致错误选择运行框架

位置:maven.rs:807–813

代码向所有 <modules> 子模块传递插件,不检查子模块实际 <parent>。新增的 parent_artifact_id 也只写入、未用于判断。

可构造的输入:聚合器声明 Spring Boot 插件,所聚合的子模块不继承它、自己使用 Quarkus。修改后子模块同时被赋予两种插件,execution/detectors/maven.rs 的 service_provider() 按表中顺序优先选择 Spring Boot,生成错误运行配置。Maven 明确区分聚合与继承,聚合的项目可以不继承聚合器:官方说明。

来源:本次引入。建议从 Maven 的有效模型获取实际插件集合,不能用目录递归代替继承链;补充“聚合但不继承”“父 POM 位于另一位置”的回归测试。当前结论来自静态调用链与 Maven 官方语义,未运行真实 Java 服务复现。

2. [P2] 忽略 <inherited>false>,把明确禁止继承的插件传播下去

位置:maven.rs:776–780

父 POM 的 Spring Boot 插件配置 <inherited>false>、子模块未声明该插件时,当前合并逻辑仍会把子模块识别为 Spring Boot 服务。解析器只保留插件名称,没有保留继承标志:Maven 插件继承规则。

来源:本次引入。建议遵循有效模型的继承结果,至少覆盖插件级禁止继承及子模块自行重新声明的情况。P2 为建议修改项,不单独作为阻塞项。

3. [P2] 检测规则改变,但已有生成配置不会因升级而失效

变更入口:maven.rs:792

关联位置:configuration.rs:17

GENERATOR_REVISION 仍为 "8"。已有 .lithe/run/generated.json 的工作区,如果 POM 和其他输入没变,fingerprint_from_inputs 无法发现检测算法变化,可能继续保留旧分类,且不提示重新生成。PR 的 A/B 验证直接调用生成接口,没有覆盖升级后的加载路径。

来源:本次检测语义变更遗漏了已有缓存的失效处理。建议递增生成器版本,并测试旧配置加载后的过期识别及重新生成。P2 为建议修改项,不单独作为阻塞项。

冲突、需求范围与验证

  • 使用 git merge-tree --write-tree --name-only 与远端 preview(4773688eb91b04c56caaf8d909b0e220de5d98f6)进行合并预演,无文本冲突。此结论对应上述精确提交。
  • #942 本次仅处理配置识别;“无法停止、运行状态图标不变化”仍未处理。PR 已明确说明,不能视为整个 Issue 完成。
  • 已有 CI 记录通过。本次实际通过:Rust Core 注释验证(含 Rustdoc)、运行时资源只读、变更测试稳定性静态检查、功能矩阵一致性及变更检查、git diff --check。
  • 新增测试覆盖正向继承及 pluginManagement,没有覆盖上述反例。本次未运行完整测试、Windows 实机或真实 Java 服务。
  • 本次仅审查,未修改实现或推送代码。

This branch has not been deployed

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

Labels

review: low ghfind author score; see https://ghfind.com

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants