用途
该技能面向使用配置驱动打包器(读取单一 HOCON 方言声明式配置)为 JVM 桌面应用生成按操作系统安装包的场景。打包器读取一份描述应用的配置,为列出的每台机器生成对应安装包;构建工具插件会生成一份伴随配置文件,包含 classpath、版本、入口点和 JDK,手写文件通过 include 引入它并补充插件无法得知的内容。
主要能力与配置要点
配置格式“失败开放”:未知键不是错误、不是警告、也不是提示。因此写在错误嵌套层级的键与生效的键无法区分,直到打开构建产物才会发现。
- 嵌套层级是键的一部分,按操作系统分区并非任意可放。URL scheme 注册绑定在应用级配置对象上,按操作系统对象不暴露该键。写
mac.url-schemes/windows.url-schemes/linux.url-schemes能正常解析,但在任何平台都不会注册任何 scheme,且是静默的。按操作系统分区确实拥有真正按操作系统的键(如 plist 条目、开始菜单组、desktop-file 组),这正是错误放置看起来合理的原因。区分方法是构建一台机器并读取生成的元数据,而不是凭直觉。 - 嵌套组的字段必须位于组内。把 desktop-entry 键写成
desktop-file.Categories会落在"Desktop Entry"组旁边而不是组内,因此永远不会进入生成的文件。含空格或方括号的键要加引号:"Desktop Entry"、"Comment[en]"。 - 命令行覆盖使用
-K<dotted.key>=<value>,列表值需要方括号加 shell 引号。示例:
conveyor -Kapp.machines=linux.amd64.glibc make linux-app
conveyor '-Kapp.machines=[mac.amd64,mac.aarch64,windows.amd64]' make site
限制机器列表也是避免某个刻意不发布的目标被作为中间步骤重新进入并导致整个运行失败的方法。
- 生成插件配置文件应作为独立步骤,在调用打包器之前完成。部分打包器支持通过 include 形式执行构建工具并将其 stdout 解析为配置;构建中任何在配置阶段打印一行的插件都会破坏解析,报错会把你的日志文本当作配置键。先运行写配置任务,固定到静态文件:
./gradlew :<desktop-module>:writeConveyorConfig --no-configuration-cache
conveyor ... make ...
- 打包 JDK 来自构建的 Java 工具链,而不是打包器。生成的配置包含一个与插件观察到的工具链匹配的 JDK 定义。应在桌面模块中显式设置工具链,并把 CI runner 的 JDK 设为相同主版本,否则会打包一个从未测试过的运行时。
限制与陷阱
- 生成的启动器把自身参数打包进固定大小的缓冲区,缓冲区满会导致构建失败,且是响亮失败而非静默失败。每个 jvm.options 条目加上 classpath 及其他“常量应用参数”被打包进生成启动器内的一个缓冲区;该项目自身配置注释记录为 16384 字节,该数字应视为版本相关,以自己构建打印的为准。失败消息不给出字节数也不给出缓冲区名称,原文为:Your JVM arguments and constant app arguments together are too large。一个发布多个按平台 jar 的依赖可能仅 classpath 就接近上限,任何新增选项都可能成为压垮的最后一根稻草——选项本身很少是真正的增长来源。应优先削减没有功能行为依赖的选项:例如三个仅用于把空闲堆归还操作系统的标志,应用中没有依赖它们,不同于几行之上运行时反射真正需要的
--add-opens模块开放;-Xmx512m本身只是占用上限。移除的行应保留在注释中并写明原因。 - 在 macOS 上声明环境块会把 PATH 固定为裸系统目录(/usr/bin:/bin:/usr/sbin:/sbin),因为启动服务层会应用它而不是继承用户环境。在添加用于分配器或区域设置的块之前,应审计应用所有生成子进程的位置:任何仅靠名称解析且不在那四个目录中的东西都会找不到,且只在从桌面启动时发生——同一个块从不适用于直接 shell 启动,因此看起来是间歇性的,且恰好在你调试的配置中不存在。
- 这里声明的每个 scheme、关联和类别还必须经受打包器之后的各层。如果重新包装打包器输出(例如把目录树变成单文件便携包),到达用户的是包装器自己生成的元数据。
- 去掉某个架构是原生依赖决策,不是配置决策。列出的机器必须拥有依赖图加载的每个原生库——数据库驱动和媒体后端是常见缺口。添加机器前应按架构审计原生库;缺失一个切片会在首次使用时失败,而不是在打包时。
验证方式
永远不要相信配置对产物的声明:
conveyor -Kapp.machines=mac.aarch64 make mac-app # 或你最小的机器
# 然后在产出的树中 grep 该功能的指纹,例如
grep -R 'CFBundleURLSchemes' -A4 output/*.app/Contents/Info.plist
grep -R 'MimeType\|Categories' output/*.desktop
对每个没有其他可观察效果的配置键做一次,并在移动键时再做一次。把同样的 grep 接入 CI,作为你无法承受丢失的键的硬断言。