← 返回
未分类

Gradle转Maven

这是一个通用的 Gradle → Maven 迁移 skill。 使用本Skill,注意自己完成本地操作的风险把控;无偿分享,本Skill作者不对最终结果和产出质量负责。
User201314
未分类 community v0.1.0 1 版本 100000 Key: 无需
★ 1
Stars
📥 104
下载
💾 0
安装
1
版本
#latest

概述

gradle2maven — Gradle 转 Maven 工程迁移 Skill

触发条件

当用户提出以下任意意图时,加载并执行本 Skill:

  • "把 Gradle 项目转换成 Maven"
  • "将 Gradle 工程迁移到 Maven"
  • "gradle to maven"、"gradle2maven"
  • 任何关于 Gradle → Maven 工程转换的需求

输出目标

输出到独立目录,而非原地修改原 Gradle 项目。

目录命名约定:${原项目名}_mvn 或用户指定名称。\

示例:atlasdb_pltr_officialatlasdb_pltr_official_mvn

这样做的好处:

  • 原项目目录中的 build.gradlesettings.gradlegradlew 等 Gradle 文件完全保留,用户可随时回滚
  • Maven 构建产物(target/ 目录)不会污染原始源码
  • 便于在同一工作空间内对比 Gradle 版和 Maven 版

操作方式:将整个项目目录复制一份到新目录,在副本中生成 pom.xml。


工作原则

你是 Gradle → Maven 迁移专家。目标是:在独立目录中生成 pom.xml 文件(根模块 + 所有子模块),让项目可以直接用 mvn compile / mvn package 编译。

流程:

  1. 将原项目复制到 ${原项目名}_mvn 独立目录
  2. 在副本中读取所有 Gradle 配置并转换为 pom.xml
  3. mvn validate 验证通过后,清理副本中的所有 Gradle 文件
  4. 原项目目录中的 build.gradle / settings.gradle / gradlew完全保留,用户可随时回滚

迁移步骤

Step 0:侦察阶段(必须)

在动手前,完整理解项目结构:

# 1. 列出根目录
ls <project_root>/

# 2. 找到所有 build.gradle / build.gradle.kts / settings.gradle
find <project_root> -maxdepth 3 \
  \( -name "build.gradle" -o -name "build.gradle.kts" \
     -o -name "settings.gradle" -o -name "settings.gradle.kts" \
     -o -name "gradle.properties" -o -name "versions.props" \
     -o -name "versions.lock" \) | sort

# 3. 读取关键文件
# - settings.gradle / settings.gradle.kts   → 子模块列表
# - 根 build.gradle                          → group/version/全局依赖/插件
# - versions.props / gradle.properties       → 依赖版本
# - 1~3 个典型子模块的 build.gradle           → 依赖声明模式

# 4. 复制项目到独立 Maven 目录
#    生成目录名为 ${原项目名}_mvn,或用户指定
mvn_dir="${project_root}_mvn"
cp -r <project_root> <mvn_dir>
# 确认复制成功
find <mvn_dir> -name "pom.xml" | wc -l   # 应为 0(还没有 pom.xml)

需要搞清楚:

  • 项目 group、version
  • Java 版本(sourceCompatibility / javaVersions { libraryTarget }
  • 全部子模块路径及其 dependencies {} 内容
  • 依赖版本管理方式(versions.propsext.versions、硬编码)
  • 特殊构型:Annotation Processor、Protobuf、Conjure 代码生成等

注意:所有后续操作(生成 pom.xml、验证)都在 副本目录中进行,原 保持不变。


Step 1:解析 Gradle DSL → 数据模型

读取每个 build.gradle 并提取:

Gradle 配置Maven 映射
---------------------------------------------------------------
api 'group:artifact'compile
implementation '...'compile
compileOnly '...'provided
runtimeOnly '...'runtime
testImplementation '...'test
testCompileOnly '...'test + true
testRuntimeOnly '...'test
annotationProcessor '...'provided 或配置 maven-compiler-pluginannotationProcessorPaths
project(':sub-module') 本地模块坐标
exclude (group: 'g', module: 'm')

版本号从 versions.props / ext.versions 中查找;找不到的保留占位符


Step 2:生成根 pom.xml

pom.xml 必须包含:

<project>
  <modelVersion>4.0.0</modelVersion>
  <groupId>${group}</groupId>
  <artifactId>${rootProjectName}</artifactId>
  <version>${version}</version>
  <packaging>pom</packaging>

  <!-- 子模块列表 -->
  <modules>
    <module>sub-module-dir</module>
    ...
  </modules>

  <!-- 全局属性:Java 版本、编码 -->
  <properties>
    <java.version>17</java.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <!-- 各依赖版本变量 -->
  </properties>

  <!-- dependencyManagement:来自 versions.props 的统一版本 -->
  <dependencyManagement>
    <dependencies>
      ...
    </dependencies>
  </dependencyManagement>

  <!-- 全局 build 配置 -->
  <build>
    <pluginManagement>
      <plugins>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.13.0</version>
          <configuration>
            <source>${java.version}</source>
            <target>${java.version}</target>
            <release>${java.version}</release>
          </configuration>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>3.5.0</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

Step 3:生成每个子模块 pom.xml

每个子模块的 pom.xml

<project>
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>${group}</groupId>
    <artifactId>${rootProjectName}</artifactId>
    <version>${version}</version>
    <relativePath>../pom.xml</relativePath>  <!-- 嵌套子模块用 ../../pom.xml -->
  </parent>

  <artifactId>${submodule-name}</artifactId>
  <packaging>jar</packaging>

  <dependencies>
    <!-- 按 scope 分组:compile → provided → runtime → test -->
  </dependencies>
</project>

注意

  • 子模块之间的 project(':xxx') 依赖,转换为同一 groupId + 对应 artifactId,不写 (由 parent 的 dependencyManagement 管理)
  • annotationProcessor 依赖放入 maven-compiler-plugin

Step 4:处理嵌套子模块

settings.gradle 中形如 :parent:child 的路径,对应目录 parent/child/

  • parent/pom.xmlpom 包含 child
  • child/pom.xml relativePath 为 ../pom.xml
  • pom.xml 包含 parent(不直接包含 child

Step 5:Annotation Processor 特殊处理

<plugin>
  <artifactId>maven-compiler-plugin</artifactId>
  <configuration>
    <annotationProcessorPaths>
      <path>
        <groupId>org.immutables</groupId>
        <artifactId>value</artifactId>
        <version>${immutables.version}</version>
      </path>
      <!-- 其他 processor -->
    </annotationProcessorPaths>
  </configuration>
</plugin>

compileOnly 'org.immutables:value::annotations' 对应的 classifier 依赖:

<dependency>
  <groupId>org.immutables</groupId>
  <artifactId>value</artifactId>
  <classifier>annotations</classifier>
  <scope>provided</scope>
</dependency>

Step 6:验证

生成完成后运行:

# 验证 pom.xml 格式正确
mvn -f <mvn_dir>/pom.xml validate -q 2>&1 | head -40

# 尝试解析依赖(不下载)
mvn -f <mvn_dir>/pom.xml dependency:resolve -o -q 2>&1 | head -60

如有错误,修复后再次验证。只有当 mvn validate 零错误通过时,才继续执行 Step 7。


Step 7:清理 Gradle 文件(仅在新目录中)

前提:mvn validate 必须零错误通过。

验证通过后,在 副本目录中删除所有 Gradle 相关文件,保持 Maven 工程目录整洁:

# 删除 Gradle 构建脚本
find <mvn_dir> -maxdepth 4 \( \
  -name "build.gradle" -o -name "build.gradle.kts" \
  -o -name "settings.gradle" -o -name "settings.gradle.kts" \
  -o -name "gradle.properties" \
  -o -name "versions.props" -o -name "versions.lock" \
  \) -delete

# 删除 Gradle Wrapper
rm -f <mvn_dir>/gradlew <mvn_dir>/gradlew.bat
rm -rf <mvn_dir>/gradle/

# 删除 Gradle 缓存目录
rm -rf <mvn_dir>/.gradle/

# 删除各模块下的 Gradle 构建产物(build/ 目录)
find <mvn_dir> -maxdepth 4 -type d -name "build" -exec rm -rf {} + 2>/dev/null

# 确认清理结果
echo "=== 剩余 Gradle 文件 ===" && find <mvn_dir> -name "*.gradle*" 2>/dev/null || echo "(无)"
echo "=== pom.xml 数量 ===" && find <mvn_dir> -name "pom.xml" | wc -l

注意

  • 以上操作只在 副本中执行,原 Gradle 项目完全不受影响
  • 如果 mvn validate 未通过,不要执行清理,等修复后再说

Step 8:输出迁移报告

生成一份 MAVEN_MIGRATION_REPORT.md,包含:

  • 转换的模块数量
  • 解析到的依赖总数
  • 无法自动解析版本的依赖列表(TODO 项)
  • 需要手工处理的特殊情况(代码生成、Protobuf 等)
  • 如何用 Maven 编译的命令说明

注意事项

  1. 输出到独立目录 + 验证后清理 Gradle 文件:复制项目 → 生成 pom.xml → mvn validate 通过 → 删除新目录中所有 Gradle 文件,原 Gradle 项目目录完全不受影响
  2. 版本策略:所有版本变量集中在根 pom.xml 中,子模块不写版本号
  3. 本地模块依赖:同一个项目内的模块互相依赖,${project.version} 或直接省略(parent 管理)
  4. Palantir 特有插件baselineconjureconsistent-versions 等):这些是 Gradle 专属工具,Maven 没有等价物,直接跳过,在报告中注明
  5. 大项目建议:超过 20 个子模块时,先生成根 pom + 最核心的几个子模块,验证通过后再批量生成其余模块
  6. 清理条件mvn validate 未通过时,不要执行清理步

快速参考:Gradle scope → Maven scope

GradleMaven scope说明
--------------------------------------------------------------
apicompile传递性依赖
implementationcompile不传递
compileOnlyprovided编译期,运行时不需要
runtimeOnlyruntime
testImplementationtest
testCompileOnlytest
testRuntimeOnlytest
annotationProcessor见 Step 5放入 compiler plugin

版本历史

共 1 个版本

  • v0.1.0 完整的 DSL 映射规则(scope 对应关系)、多模块嵌套处理、Annotation Processor 特殊处理、以及循环依赖等常见陷阱的解决方案。 当前
    2026-05-01 09:28 安全

安全检测

腾讯云安全 (Keen)

安全,无风险
查看报告

腾讯云安全 (Sanbu)

suspicious
查看报告

🔗 相关推荐

dev-programming

Github

steipete
使用 `gh` CLI 与 GitHub 交互,通过 `gh issue`、`gh pr`、`gh run` 和 `gh api` 管理议题、PR、CI 运行及高级查询。
★ 686 📥 331,147
dev-programming

YouTube

byungkyu
使用托管OAuth集成YouTube Data API,支持搜索视频、管理播放列表、获取频道数据及评论互动,适用于用户需要时使用此技能。
★ 142 📥 42,123
dev-programming

Mcporter

steipete
使用 mcporter CLI 直接列出、配置、认证及调用 MCP 服务器/工具(支持 HTTP 或 stdio),涵盖临时服务器、配置编辑及 CLI/类型生成功能。
★ 198 📥 68,243