Blankj/AndroidUtilCode · error · GradleException
The module of <" + dep.name + "> should set groupId & versio
Error message
The module of <" + dep.name + "> should set groupId & version.
What it means
config/publish.gradle's addDependency() builds the published pom. When a dependency resolves with version 'unspecified' (a local/source module rather than a published artifact) and the module being published has its own ext.groupId or ext.version set (signaling publish mode), it throws GradleException. A source dependency cannot be correctly represented in a published pom unless that dependency module itself has publish coordinates.
Source
Thrown at config/publish.gradle:132
sign publishing.publications
}
}
private void addDependency(Project project, def dependenciesNode, Dependency dep, String scope) {
if (dep.group == null || dep.version == null || dep.name == null || dep.name == "unspecified") {
return
}
final dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('scope', scope)
if (dep.version == 'unspecified') {
// 检测 module 中的 dependencies 是否有源码依赖
// 如果是源码依赖,而且没有在 config 中配置 remotePath,
// 那么发布到仓库,其他地方依赖该库时会找不到源码的那个库
println "publish -> module(unspecified) <${dep.group}:${dep.name}:${dep.version}>"
if (project.ext.groupId || project.ext.version) {
throw new GradleException("The module of <" + dep.name + "> should set groupId & version.")
}
// 源码依赖,但配置了 remotePath,让 pom 中写入 remotePath
println("publish -> module(wrapped) <${project.ext.groupId}:${name}:${project.ext.version}>")
dependencyNode.appendNode('groupId', project.ext.pomGroupID)
dependencyNode.appendNode('artifactId', dep.name)
dependencyNode.appendNode('version', project.ext.pomVersion)
} else {
dependencyNode.appendNode('groupId', dep.group)
dependencyNode.appendNode('artifactId', dep.name)
dependencyNode.appendNode('version', dep.version)
println("publish -> library <${dep.group}:${dep.name}:${dep.version}>")
}
if (!dep.transitive) {
// In case of non transitive dependency,
// all its dependencies should be force excluded from them POM file
final exclusionNode = dependencyNode.appendNode('exclusions').appendNode('exclusion')
View on GitHub (pinned to 7b4caf9e54)
Solutions
- Set ext.groupId and ext.version (plus the publish block / remotePath) on the local source dependency module that resolves to 'unspecified', so its coordinates can be written into the pom.
- If the sibling is meant to be consumed remotely, configure remotePath so addDependency() writes the wrapped remote coordinates instead of throwing.
- If the dependency should not appear in the pom, make it non-transitive or move it out of the api configuration so it is excluded from pom generation.
Example fix
// before - lib_a is published and depends on local :lib_b (version 'unspecified')
// lib_a/build.gradle
ext { groupId = 'com.example'; artifactId = 'lib-a'; version = '1.0.0' }
apply from: "${rootDir}/config/publish.gradle"
dependencies { api project(':lib_b') } // lib_b has no groupId/version -> error
// after - publish lib_b too (or point lib_a's pom at lib_b's remote coordinates)
// lib_b/build.gradle
ext { groupId = 'com.example'; artifactId = 'lib-b'; version = '1.0.0' }
apply from: "${rootDir}/config/publish.gradle" Defensive patterns
Strategy: validation
Validate before calling
tasks.named('publish2Local').configure {
doFirst {
['api', 'implementation'].each { cfg ->
configurations.findByName(cfg)?.dependencies?.each { d ->
if (d.version == 'unspecified') {
throw new GradleException(
"Source dep <${d.name}> has no groupId/version; publish it or set remotePath.")
}
}
}
}
} Prevention
- Before publishing a module, ensure every local/source dependency is itself publishable (groupId + version).
- Prefer remote coordinates (remotePath) for source deps so the pom stays resolvable by consumers.
- Keep publish metadata consistent across all modules in the composite, not just the published leaf.
When it happens
Trigger: A publishable module (sets ext.groupId/ext.version and applies publish.gradle) has an api/implementation dependency on another local Gradle module (project(':other')) whose version is 'unspecified' and which has no groupId/version/remotePath configured.
Common situations: Multi-module mono-repo where one library depends on a sibling local module but only the leaf is published; converting a remote dependency to a source dependency without setting publish metadata on the sibling; publishing a single module out of a normally-composite build.
Related errors
- <" + className + "> and <" + apiInfo.implApiClass + "> impl
- ApiExtension's apiUtilsClass is empty.
- u should impl these apis: " + noImplApis + "\n u can check i
- No ApiUtils of ${apiUtilsClass} in $mProject.
- BusExtension's busUtilsClass is empty.
AI-assisted analysis of Blankj/AndroidUtilCode@7b4caf9e54 (2026-08-14).
Data as JSON: /api/errors/097a999cbda49333.
Report an issue: GitHub.