欢迎加入开源鸿蒙 PC 社区:https://harmonypc.csdn.net/
欢迎在 PC 社区平台申请新建项目:https://atomgit.com/OpenHarmonyPCDeveloper
适配开源地址:https://atomgit.com/OpenHarmonyPCDeveloper/ohos_maven
环境搭建文章:本项目不是 Electron 或 Qt 工程,适配过程主要依赖 JDK 17、DevEco Studio、OpenHarmony SDK、HNP 打包工具和真机签名安装流程,因此不引用 Electron/Qt 环境搭建文章。
一、为什么要适配 Apache Maven
Apache Maven 是 Java 生态中使用最广的构建工具之一。它负责项目模型解析、依赖管理、插件执行、生命周期编排、编译、测试和打包;很多企业项目的日常开发、CI 构建和制品发布都围绕 pom.xml 与 mvn 命令展开。对鸿蒙 PC 来说,适配 Maven 的价值不只是让终端里多一个命令,而是让 Java 开发者能在新系统上继续沿用成熟的工程组织方式。
这类工具还有一个很现实的生态意义。Java 项目通常不是孤立运行的:Maven 需要 JDK、用户目录、网络仓库、本地缓存、插件仓库、证书与终端权限共同配合。只要其中一环不稳定,用户看到的就不是"跨平台工具",而是下载失败、插件找不到、缓存不可写或构建产物无法生成。把 Maven 适配到鸿蒙 PC,等于把 JVM 命令行开发工具在 HAP/HNP 交付体系中的关键路径完整走一遍。
本次适配没有重写 Maven Core,也没有给 Maven 强行做一个图形化构建界面。Maven 的核心价值在命令行和插件生态,保留上游发行结构比重新包装一个私有启动器更稳妥。因此项目采用"Apache Maven 官方二进制发行目录 + public HNP + 2in1 HAP 安装入口"的方案:HAP 负责安装、展示说明和携带 HNP,真正的 mvn 命令在鸿蒙 PC 的 HiShell 中运行。
二、先确定边界:Maven 是命令行构建工具,不是桌面 GUI
Maven 表面上只有一条 mvn 命令,但它启动后会读取 Maven Home、m2.conf、用户 settings.xml、本地仓库、远端插件仓库和项目目录。如果只把几个 JAR 拷贝到设备上,很容易出现能启动主类、但插件解析或生命周期执行失败的半成品。
本次适配把链路拆成四层:
| 层次 | 核心问题 | 鸿蒙侧实现 |
|---|---|---|
| Maven 发行层 | 保持 Maven 原始目录语义 | 直接使用官方二进制发行包中的 bin、boot、conf、lib |
| 命令注册层 | 让用户在系统终端直接调用 | 通过 public HNP 暴露 mvn、mvnDebug、mvnenc、mvnup、mvnsh |
| 安装交付层 | HNP 必须进入最终 HAP | Stage 模型 HAP 面向 2in1,在打包阶段注入 maven.hnp |
| 运行验证层 | 构建必须在真实用户环境完成 | 在华为 HiShell 中验证 JDK、Maven Central、编译、打包和运行 |
这条路线的重点是尽量减少平台补丁。Maven 自身仍由 ClassWorlds 和上游启动脚本组织,鸿蒙侧只处理安装、命令发现和终端可用性。这样后续跟进 Maven 上游版本时,适配层不会和核心代码深度耦合。
三、适配后的工程结构
仓库保留 Apache Maven 上游多模块源码,鸿蒙 PC 相关内容集中在 hnp/、ohos/ 和 tools/ohos/:
text
ohos_maven/
├── apache-maven/ # Maven 二进制发行包输出模块
├── api/ compat/ impl/ src/ # Maven 上游核心源码与实现模块
├── hnp/
│ └── maven/hnp.json # public HNP 命令链接配置
├── ohos/
│ ├── AppScope/ # 应用级配置、名称和图标
│ ├── entry/src/main/
│ │ ├── ets/pages/Index.ets # Apache Maven 安装说明页
│ │ └── module.json5 # 2in1 模块与 public HNP 声明
│ └── hnp/arm64-v8a/maven.hnp # Maven HNP 产物
├── tools/ohos/
│ ├── build_maven_hnp.sh # 构建 Maven 发行包并打成 HNP
│ ├── verify_maven_hnp.sh # 校验 HNP 结构和关键入口
│ └── build_hap.sh # 编译 HAP 并注入 HNP
└── reports/
├── migration-report.md # 迁移与真机验证记录
└── evidence/ # 真机运行截图与证据
从源码到用户终端的交付链路可以概括为:
text
Apache Maven 4.1.0-SNAPSHOT 源码
└── apache-maven-*-bin.tar.gz
└── maven.hnp
└── org.apache.maven.ohos HAP
└── HarmonyOS PC 安装
└── HiShell 执行 mvn clean package
当前验证使用 Apache Maven 4.1.0-SNAPSHOT,目标设备为 HarmonyOS PC 2in1,运行时使用设备侧 BiSheng OpenJDK 17.0.13+6。Maven HNP 本身不内置 JDK,这样可以避免应用包重复携带一套大型运行时,也让 JDK 更新继续由系统或公共运行时包管理。
四、真机上的五个核心功能验证
以下五张图均来自 HarmonyOS PC 真机,原始截图分辨率为 3120 x 2080。验证不是在开发机上模拟命令输出,而是在设备的 HAP 页面和 HiShell 中实际启动、解析依赖、编译源码、生成 JAR 并运行结果。
1. HAP 安装后能够打开 Maven 说明页
安装 org.apache.maven.ohos 后,EntryAbility 正常启动,页面展示 Apache Maven 4.1.0 的安装说明和推荐命令。这个页面不承担构建工作,它的职责是把 HNP 已安装、需要在系统终端中执行 mvn --version 和 mvn clean package 这件事讲清楚。

这一屏验证了 HAP 安装、EntryAbility 启动、2in1 窗口显示和 ArkUI 资源加载。页面本身不替代命令行构建,后续验证仍回到 HiShell 中完成。
2. HiShell 中识别 JDK 与 Maven HNP
在真机 HiShell 中执行 java -version; mvn --version,终端返回 BiSheng OpenJDK 17.0.13+6,Maven 返回 Apache Maven 4.1.0-SNAPSHOT,并识别 Maven Home 为 /data/service/hnp/maven.org/maven_4.1.0。

这一屏验证了三个关键点:系统存在可用 JDK,public HNP 命令已经进入用户终端,Maven 能按原始发行目录找到自己的 boot、conf 和 lib。如果 Maven Home 解析不正确,后续生命周期和插件执行都会很快失败。
3. Maven Central 插件下载与版本表达式执行成功
执行 mvn -B help:evaluate -Dexpression=maven.version -DforceStdout 时,真机从 Maven Central 下载 Help 插件及其传递依赖,并最终输出 4.1.0-SNAPSHOT 和 BUILD SUCCESS。

这一步比单纯的 mvn --version 更接近真实项目使用。它覆盖了 HTTPS 仓库访问、插件前缀解析、传递依赖下载、插件执行和标准输出回传。截图里能看到多个 repo.maven.apache.org 下载记录,说明设备侧网络仓库链路已实际参与构建。
4. 标准 Java 项目执行 clean package
在真机用户目录 /storage/Users/currentUser/maven-smoke-codex 中执行 mvn -B clean package,Maven 读取标准 pom.xml,解析 Clean、Compiler、JAR 等插件,完成 Java 17 示例源码编译。

这一阶段主要验证 Maven 生命周期是否能在鸿蒙 PC 的用户目录中稳定写入。构建工具必须能创建 target/、写本地仓库、下载插件和生成 class 文件;这些都依赖终端权限、文件系统路径和 JDK 子进程协同。
5. JAR 产物生成并运行编译结果
构建结束后,终端显示 Building jar: /storage/Users/currentUser/maven-smoke-codex/target/harmony-smoke-1.0.jar,随后运行编译后的 Java 类,输出 MAVEN_HARMONY_OK。

这张图把"命令能启动"和"构建真的有结果"区分开来。Maven 不仅完成了插件下载和生命周期执行,还在设备用户目录生成了可运行产物,并由同一套 JDK 执行编译结果。
五、适配过程中遇到的关键难点
难点一:Maven 的"跨平台"依赖一整套运行契约
Maven 是 Java 程序,但它不是把 JAR 放到设备上就自然可用。启动脚本、ClassWorlds、Maven Home、用户本地仓库、证书、代理、插件仓库、项目目录权限都要同时成立。适配初期最容易误判的是:mvn --version 能跑,不代表 mvn clean package 能跑。
因此验收没有停在版本输出,而是加入 help:evaluate 和真实 Java 项目 clean package。这两步会逼出仓库访问、插件解析和文件写入问题,也能更快暴露 HNP 目录结构是否破坏了 Maven 原始发行布局。
难点二:HNP 不能只生成,还必须进入最终 HAP
maven.hnp 生成成功只是中间结果。最终安装包必须在 module.json5 中声明 public HNP,并且在签名前把 HNP 载荷真实注入 HAP。否则用户能打开 HAP 页面,却无法在 HiShell 中找到 mvn 命令。
当前 build_hap.sh 在 Hvigor 生成模块产物后,使用 SDK 的 app_packing_tool.jar --hnp-path 重新打包 HAP,并检查包内是否存在 hnp/arm64-v8a/maven.hnp。这个检查很重要,它避免了"页面安装成功、命令没有落地"的假通过。
难点三:是否内置 JDK 需要取舍
Maven 依赖 JDK 17 或更高版本。本次适配选择复用鸿蒙 PC 上已有的 BiSheng OpenJDK 17,而不是把 JDK 打进 Maven HNP。这样安装包更轻,Maven HNP 约 15 MiB,也避免多个应用各自携带重复 JDK。
代价是验收必须明确设备 JDK 是前置条件,并在文章和 HAP 页面中提示。真机验证里同时执行 java -version 和 mvn --version,就是为了把 Maven 与 JDK 的关系放在同一个证据链里。
难点四:终端环境不完全等同于调试 shell
鸿蒙 PC 上的用户 HiShell、HDC 调试 shell 和其他第三方终端可能处在不同的路径与权限环境中。public HNP 命令是否可见、用户目录是否可写、构建产物是否落在预期位置,都要以最终用户实际使用的终端为准。
本次截图和验收选择华为 HiShell。HDC 仍然用于安装、包信息检查和设备连通性确认,但不把 HDC shell 的 PATH 结果当成用户终端结果。这个边界能减少很多后续定位成本。
难点五:原生插件和交互能力不能被 Maven Core 的通过覆盖
普通 Java 项目构建已经跑通,但 Maven 生态中仍有一些插件会调用平台原生命令或携带 native 二进制。linux-aarch64 也不能直接等同于 OHOS ABI 兼容。另外,mvnDebug、mvnenc、mvnup、mvnsh、JLine 交互、Ctrl+C 中断和长时间任务信号处理,都需要单独验收。
因此当前版本的定位比较明确:Maven 批处理构建主链路已经可用,增强启动器和涉及原生能力的插件仍按待验证处理。这种边界写清楚,比笼统说"完全兼容 Maven"更可靠。
六、构建、安装与使用
本项目不属于 Electron 或 Qt。开发机需要准备 JDK 17 或更高版本、Maven 3.9+、DevEco Studio、OpenHarmony SDK、ohpm、Hvigor 和 SDK 中的 hnpcli。
先构建 Maven HNP:
bash
./tools/ohos/build_maven_hnp.sh
脚本会优先复用 apache-maven/target/apache-maven-*-bin.tar.gz。如果发行包不存在,则使用 Maven 3.9+ 对当前源码树执行构建,随后保留 Maven 官方发行目录中的 bin、boot、conf 和 lib,移除 Windows .cmd 启动器,最后生成:
text
ohos/hnp/arm64-v8a/maven.hnp
如果需要指定预构建发行包,可以这样执行:
bash
MAVEN_DIST_ARCHIVE=/path/to/apache-maven-4.1.0-bin.tar.gz \
./tools/ohos/build_maven_hnp.sh
接着构建携带 HNP 的 HAP:
bash
./tools/ohos/build_hap.sh
脚本会编译 ohos/ 下的 Stage 模型应用,并重新打包生成包含 HNP 的未签名 HAP:
text
ohos/entry/build/default/outputs/default/entry-default-unsigned-hnp.hap
配置与 org.apache.maven.ohos 和目标设备匹配的签名材料后,安装到鸿蒙 PC:
bash
hdc install -r ohos/entry/build/default/outputs/default/entry-default-signed-hnp.hap
hdc shell aa start -a EntryAbility -b org.apache.maven.ohos -m entry
安装完成后,在 HiShell 中验证:
bash
java -version
mvn --version
mvn -B help:evaluate -Dexpression=maven.version -DforceStdout
最后进入一个真实 Java 项目执行:
bash
mvn -B clean package
java -cp target/classes demo.App
七、当前功能边界
当前版本已在 HarmonyOS PC 真机上验证以下能力:
- 签名 HAP 安装与 EntryAbility 启动;
- public
maven.hnp被安装包声明并进入设备; - HiShell 中可以直接调用
mvn; - BiSheng OpenJDK 17 与 Maven 4.1.0-SNAPSHOT 协同运行;
- Maven Home 指向 HNP 安装目录;
- Maven Central HTTPS 依赖和插件下载;
help:evaluate插件目标执行;- 标准
pom.xml项目解析; clean、compile、jar生命周期主流程;- Java 17 示例代码编译;
target/harmony-smoke-1.0.jar生成;- 编译结果在真机 JDK 中运行并输出
MAVEN_HARMONY_OK。
当前没有把以下能力声明为已完成:
mvnDebug远程调试入口;mvnenc、mvnup、mvnsh的完整交互流程;- Surefire 分叉 JVM 中包含真实测试用例的完整验收;
install、deploy到本地/远端仓库的发布链路;- JLine 交互、彩色输出、Ctrl+C 中断和长任务信号处理;
- 带 Linux 原生二进制的特殊 Maven 插件;
- 第三方终端沙箱中的 public HNP 命令发现。
因此,当前成果更适合表述为"Apache Maven 在鸿蒙 PC 上的批处理构建主链路可用"。对普通 Java 项目来说,依赖下载、插件执行、编译和 JAR 打包已经形成闭环;对调试、交互式 shell、发布和原生插件,还需要按场景补充验收。
八、总结
Apache Maven 的鸿蒙 PC 适配证明,JVM 工具迁移的关键不在于改写核心代码,而在于把运行契约放到目标系统上重新闭合。Maven Core 可以保持上游实现,但 Maven Home、JDK、HNP 命令注册、HAP 注入、用户终端、远端仓库和本地构建目录都必须经过真机验证。
本项目通过 public HNP 保留 Maven 原始发行结构,通过 2in1 HAP 完成安装和说明入口,通过 HiShell 验证真实用户终端中的 mvn 命令。真机上的版本输出、Maven Central 下载、help:evaluate、clean package、JAR 生成和 Java 程序运行结果表明,当前链路已经越过"能启动 Maven"的阶段,进入可执行日常 Java 构建的状态。
后续工作应集中在调试入口、交互式能力、测试分叉 JVM、发布流程、第三方终端和原生插件兼容上。对于其他 JVM 命令行工具,这次适配也提供了一条可复用路线:尊重上游发行结构,把平台差异收敛到 HNP/HAP 交付、运行时依赖和终端验收中,最后用真实项目构建结果来证明适配质量。