publishtomavenlocal默认只发布执行命令所在模块,因该task不自动遍历子模块;需在各待发布子模块中显式启用maven-publish插件并配置publishing块,或通过根项目subprojects统一注入配置,同时注意过滤非发布模块、统一groupid/version、确保android库使用androidcomponents api等关键细节。

多模块项目里 publishToMavenLocal 为什么只发了主模块
默认情况下,publishToMavenLocal task 只在当前 project(即执行命令的目录所在模块)上运行,不会自动遍历子模块。你执行 ./gradlew publishToMavenLocal 时,如果在根目录运行,而根 project 没有应用 maven-publish 插件,那什么都不会发布;如果在某个子模块目录下运行,就只会发布那个模块。
真正要批量发布,得让所有需要发布的子模块都显式启用 maven-publish 插件,并统一配置 publishing block。常见错误是只在根 build.gradle 里写了插件,但没 propagate 到子项目。
- 必须在每个待发布的子模块的
build.gradle或build.gradle.kts中 applymaven-publish - 不能只在根项目 apply,除非你用
subprojects或allprojects显式委托 -
publishToMavenLocal不会自动触发依赖模块的 publish,哪怕 A 依赖 B,也得单独 publish B
如何用 subprojects 统一配置 publishing
在根项目的 build.gradle(Groovy)中,用 subprojects 块统一注入 publishing 配置,是最直接、最可控的方式。它能避免重复粘贴,也能保证 groupId、version 等基础属性一致。
注意:不要在 subprojects 里无条件 apply 插件——有些模块(比如 application 模块或脚本模块)根本不需要发布,应加判断过滤。
- 用
plugins.withId("java-library")或检查模块名前缀(如name.startsWith("lib-"))来精准控制哪些模块参与发布 - version 推荐从根
gradle.properties读取:project.version = findProperty("VERSION_NAME") ?: "1.0.0-SNAPSHOT" - groupId 必须显式设置,不能依赖默认值;否则子模块可能用自己目录名当 group,导致坐标混乱
subprojects {
plugins.withId("java-library") {
apply(plugin = "maven-publish")
publishing {
publications {
create<mavenpublication>("library") {
from(components["java"])
groupId = "com.example"
artifactId = project.name
version = project.version.toString()
}
}
}
}
}</mavenpublication>
批量执行 publish tasks 的正确姿势
Gradle 不支持像 ./gradlew :**publish 这样通配符式调用 task,但可以用 --include-build 或直接指定路径前缀。最稳妥的是用冒号拼接模块路径:
- 发布全部子模块:
./gradlew :module-a:publish :module-b:publish :module-core:publish - 更省事的是写个 alias 脚本,比如在
gradlew同级建publish-all.sh,内容为:./gradlew :module-a:publishToMavenLocal :module-b:publishToMavenLocal ... - 如果用了
maven-publish,别只跑publishToMavenLocal——它只是本地快照;正式发布到私服需用publish,且确保publishing.repositories已正确定义
另外,publish task 默认不依赖 build,所以建议加 dependsOn("build"),否则可能发布未编译产物。
发布时容易漏掉的三个关键点
很多团队卡在“包传上去了但引用失败”,问题往往不出在命令本身,而在 publishing 配置的细节缺失:
-
generatePomFileForXPublicationtask 是自动生成 pom 的,但如果子模块有 custom pom 配置(比如添加 license、scm),就得手动写pom.withXml,否则上传后 pom 缺失关键元数据 - Android 库模块(
com.android.library)必须用androidComponentsAPI 替代components["java"],否则 aar 不会被包含进 publication - 签名环节常被忽略:发布到中央仓库等公开源必须 GPG 签名,本地私服虽可跳过,但若团队规范要求校验,
signing插件和sign publish就不能少
真正麻烦的不是“怎么发”,而是“发完别人能不能正常 resolve”。每发一个组件,最好立刻在另一个空项目里试 implementation 'com.example:module-a:1.0.0',确认依赖图干净、没有 transitive 冲突、Javadoc 和 sources 也同步可用。











