非Kotlin多平台Java项目如何在Gradle中优雅声明多平台依赖
纯Java Gradle项目跨平台原生依赖发布问题
项目构建过程中使用了部分按不同原生操作系统独立分发jar包的依赖库,这类依赖如果同时引入全平台的jar包会引发运行异常。
初期实现方案为构建时判断当前运行的操作系统类型,仅引入对应平台的依赖,代码如下:
if (isWindows()) { runtimeOnly(libraries.nd4j.windows) runtimeOnly(libraries.openblas.windows) } else if (isMacOS()) { runtimeOnly(libraries.nd4j.macos) runtimeOnly(libraries.openblas.macos) } else if (isLinux()) { runtimeOnly(libraries.nd4j.linux) runtimeOnly(libraries.openblas.linux) }
上述写法可以通过将判断逻辑封装到依赖配置中隐藏实现来做代码精简,但无法解决核心缺陷:发布项目产物时,生成的POM文件只会记录执行构建操作的主机所属平台的依赖。例如在Windows系统上构建发布的产物,其POM中仅声明Windows版本的上述依赖,macOS或Linux用户依赖该产物构建时会出现依赖不匹配、无法正常运行的问题。
已评估的方案及局限
- Maven Profile适配方案:如果Gradle支持Maven Profile机制,即可在POM中声明基于构建平台选择的多套依赖配置,下游项目可自动识别匹配对应平台依赖,问题即可解决。但目前Gradle既不支持读取也不支持写入带Maven Profile的POM,该方案无法落地。
- 多模块拆分方案:曾考虑将项目拆分为公共模块、Windows模块、macOS模块、Linux模块四个子项目,业务代码和通用依赖统一放在公共模块,各平台专属子模块依赖公共模块与对应平台的专属依赖。但这种方案会将平台依赖选择的问题传递给下游使用方,并未从根本解决问题。
- Kotlin多平台能力复用方案:已知Kotlin多平台提供了成熟的多平台依赖处理能力,但当前项目为纯Java项目,仅构建脚本正在迁移至Kotlin DSL,并未引入Kotlin语言依赖,无法直接复用KMP的相关能力。
核心诉求
寻找不需要强制引入Kotlin技术栈的更优多平台依赖声明与发布解决方案。
内容的提问来源于stack exchange,提问作者Hakanai
相关产品推荐
相关产品推荐

