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

  1. 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.
  2. If the sibling is meant to be consumed remotely, configure remotePath so addDependency() writes the wrapped remote coordinates instead of throwing.
  3. 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

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


AI-assisted analysis of Blankj/AndroidUtilCode@7b4caf9e54 (2026-08-14). Data as JSON: /api/errors/097a999cbda49333. Report an issue: GitHub.