Document cross-platform JAR path design

This commit is contained in:
张家训
2026-08-03 14:47:04 +08:00
parent b604fb5006
commit d2ffedfa53
@@ -0,0 +1,84 @@
# WorkUtils 跨平台 JAR 与路径设计
## 背景
WorkUtils 当前可以在 Windows 上运行,但构建和运行路径仍包含 Windows 假设:POM 将编译器固定到 `C:\Program Files\Java\jdk-17`,Launch4j 在所有平台参与 `package`,运行目录依赖散落的 `user.dir`,部分路径通过带 `/` 的字符串拼接,Git Review 默认只查找 Windows IDEA 命令。
这会造成两类问题:Maven 与编译器可能使用不同 JDK(当前基线中 Maven 由 Java 8 启动、源码由 JDK 17 编译,测试 JVM因此无法加载 class),以及同一 JAR 在 macOS/Linux 上启动时无法稳定找到数据、导出和配置目录。
## 目标与范围
- 使用标准 JDK 17 在 Windows、macOS、Linux 构建并运行 Spring Boot JAR。
- 统一应用运行目录,数据、导出、历史记录和插件配置使用同一解析规则。
- 将业务路径组合改为 `Path` 分段解析,支持空格、中文和平台分隔符。
- Git Review 在三个桌面平台上提供合理的 IntelliJ IDEA 默认启动方式。
- Windows 现有默认数据位置保持不变,不自动迁移用户数据。
明确不包含:手机 UI 自动化插件的兼容性修改、`.app`/`.dmg` 等原生安装包、数据迁移、Git 项目内容路径的语义变更。
## 运行目录
新增单一的运行目录解析组件 `ApplicationPaths`。应用根目录按以下优先级确定:
1. JVM 参数 `-Dworkutils.home=<path>`;
2. 环境变量 `WORKUTILS_HOME=<path>`;
3. JVM `user.dir`。
空白值视为未设置。最终路径转换为绝对、规范化的 `Path`,但不要求目录预先存在,也不展开 `~`。`ApplicationPaths` 提供根目录及分段 `resolve(...)` 能力,使调用方不再自行读取系统属性或拼接分隔符。
`WorkUtilsProperties` 仍接受配置文件中的绝对路径;相对路径统一相对于应用根目录解析。未配置导出目录时使用 `<home>/export`。`WorkUtilsApplication` 的启动诊断、Git Review 数据目录、历史记录和插件配置也从该入口获取路径。
默认回退仍是 `user.dir`,因此 Windows 用户未设置新参数时不会改变原有数据位置。实现不扫描或移动旧目录。
## 构建与启动
默认 Maven 构建要求运行 Maven 的 JVM 为 JDK 17,并使用 `maven-compiler-plugin` 的 `release=17`。删除硬编码 JDK 路径、外部 `javac`、编译器 fork 和冗余 compilerVersion,确保编译与测试使用同一 JDK。
Launch4j 和 `start.bat` 复制仅放入 Windows 自动激活 profile。普通 `mvn package` 在 macOS/Linux 上只生成可执行 Spring Boot JAR及通用启动脚本,不尝试生成 `.exe`。
新增 `scripts/start.sh`,脚本:
- 从脚本自身位置定位发布根目录,而不是依赖调用者当前目录;
- 检查 `java` 可用且主版本至少为 17;
- 查找对应的 WorkUtils JAR并以参数数组启动,正确处理空格和中文路径;
- 显式传递 `-Dworkutils.home=<发布根目录>`,让脚本启动结果稳定;
- 将用户追加参数原样交给 Java 进程。
直接执行 `java -jar` 时仍按统一优先级解析根目录。
## 路径组合
运行路径不再使用 `String.format("%s/%s", ...)`、字符串 `+ "/..."` 或在一个 `resolve` 参数中嵌入平台分隔符。源码目录等固定层级使用 `Path.of("src", "main", "java")` 或连续 `resolve`。
仅修改实际文件系统操作。URL、正则表达式、展示文本以及手机 UI 自动化插件中的平台逻辑不在本次批量替换范围,避免改变业务语义。
## IntelliJ IDEA 启动
Git Review 将命令解析与进程执行分离,便于模拟操作系统测试。用户显式配置的 IDEA 命令始终优先,且通过 `ProcessBuilder` 参数列表执行,不拼 shell 字符串。
- Windows 默认依次尝试 `idea64.exe`、`idea.bat`、`idea`;批处理命令继续通过 `cmd.exe /c` 执行。
- macOS 默认尝试 `idea`,不可用时回退 `open -a "IntelliJ IDEA" <project>`。
- Linux 默认尝试 `idea`。
界面默认文案不再固定显示 `idea64.exe`,改为平台中性的“自动检测”;现有已保存的自定义命令保持有效。
## 测试策略
先增加失败测试,再实施最小改动:
- `ApplicationPaths` 覆盖 JVM 参数、环境变量、`user.dir` 的优先级、空白值、相对路径、空格和中文路径。
- `WorkUtilsProperties` 验证所有相对数据/导出路径都基于统一根目录,绝对路径不被改写。
- IDEA 命令解析测试模拟 Windows、macOS、Linux,验证自定义命令、默认候选和 macOS fallback。
- 路径生成与固定源码目录测试验证使用平台 `Path` 后的结果。
- 构建测试/检查验证默认 POM 不含 Windows JDK 路径,Launch4j 只属于 Windows profile,`start.sh` 被纳入发布产物。
最终运行聚焦测试、JDK 17 Maven 全量 `clean test`、`package`、`git diff --check`。当前环境只能实际执行 Windows 构建;macOS/Linux 行为由无平台副作用的命令解析和路径测试覆盖。
## 验收标准
- JDK 17 执行 `mvn clean package` 可生成并运行 Spring Boot JAR。
- 非 Windows 默认构建不执行 Launch4j。
- 应用根目录优先级明确,所有纳入范围的相对运行路径保持一致。
- 路径包含空格、中文时不因字符串分隔符或 shell 拼接失败。
- Git Review 在 macOS/Linux 不再默认依赖 `.exe`。
- Mobile UI Automation 源码无改动,无 `.app`/`.dmg` 产物,无自动数据迁移。