使用Nexus的Android Gradle库依赖项与库依赖项

29

我正在将项目转换为使用Gradle和内部SonaType Nexus来托管我的依赖关系。我的核心项目依赖于库项目A,而库项目A又依赖于库项目B。

我的问题是,一旦我将LibA添加到我的主项目中,就会出现以下错误: “模块版本com.example:LibA:1.1依赖于库,但它本身不是库”

使用相同的构建脚本,我添加具有jar依赖项的库项目没有任何问题。我看过人们在LOCAL(项目中)android库中成功地执行此操作,但没有人在maven存储库中这样做。

这是Gradle的一个bug还是我错误配置了库构建?

核心项目构建

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.6.+'
    }
}
apply plugin: 'android'

repositories {
    maven {
        url "http://localhost:8081/nexus/content/repositories/releases/"
    }

    maven {
        url "http://localhost:8081/nexus/content/repositories/central/"
    }
}

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.0"

    defaultConfig {
        minSdkVersion 14
        targetSdkVersion 19
    }
}

dependencies {
    compile 'com.android.support:support-v4:+'
    compile('com.example:LibA:1.+')
}

LibA 构建

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:0.6.+'
    }
}

apply plugin: 'android-library'

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.0"

    defaultConfig {
        minSdkVersion 9
        targetSdkVersion 17

        versionCode = "3"
        versionName = "1.2"
    }

    android {
        sourceSets {
            main {
                manifest.srcFile 'AndroidManifest.xml'
                java.srcDirs = ['src']
                resources.srcDirs = ['src']
                aild.srcDirs = ['src']
                renderscript.srcDirs = ['src']
                res.srcDirs = ['res']
                assets.srcDirs = ['assets']
            }

        }
    }

    repositories {
        mavenCentral()
    }

    dependencies {
        compile ('com.example:LibB:1.+')
    } ...

LibB构建

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:0.6.+'
    }
}

apply plugin: 'android-library'

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.0"

    defaultConfig {
        minSdkVersion 9
        targetSdkVersion 17

        versionCode = "1"
        versionName = "1.0"
    }

    android {
        sourceSets {
            main {
                manifest.srcFile 'AndroidManifest.xml'
                java.srcDirs = ['src']
                resources.srcDirs = ['src']
                aild.srcDirs = ['src']
                renderscript.srcDirs = ['src']
                res.srcDirs = ['res']
                assets.srcDirs = ['assets']
            }

        }
    }

    repositories {
        mavenCentral()
    }

    dependencies {
    } ...

编辑:添加错误信息的 -info 输出。

* What went wrong:
A problem occurred configuring project ':GradleTest'.
> Failed to notify project evaluation listener.
   > Module version com.example:LibA:1.+ depends on libraries but is not a library itself

编辑2:添加我的本地Maven上传脚本以供LibA使用

apply plugin: 'maven'
apply plugin: 'signing'

group = "com.example"
version = defaultConfig.versionName

configurations {
    archives {
        extendsFrom configurations.default
    }
}

signing {
    required { has("release") && gradle.taskGraph.hasTask("uploadArchives") }
    sign configurations.archives
}


uploadArchives {
    configuration = configurations.archives
    repositories.mavenDeployer {
        beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
        repository(url: sonatypeRepo) {
            authentication(userName: sonatypeUsername,
                    password: sonatypePassword)
        }

        pom.project {
            name 'com-example'
            packaging 'aar'
            description 'none'
            url 'https://internal github link'

            scm {
                url 'scm:git@https://internal github link'
                connection 'git@https://internal github link'
                developerConnection 'git@https://internal github link'
            }

            licenses {
                license {
                    name 'example'
                    url 'example'
                    distribution 'example'
                }
            }

            developers {
                developer {
                    id 'example'
                    name 'example'
                    email 'example'
                }
            }

            groupId "com.example"
            artifactId rootProject.name //LibA
            version defaultConfig.versionName
        }
    }
}

Maven在网络连接不稳定的情况下会表现得相当苛刻。你可以尝试删除m2缓存目录,然后再试一次吗? - Paul Lammertsma
1
顺便说一句,Xav正在研究它:https://groups.google.com/forum/#!topic/adt-dev/frugpmBwQt0 - CommonsWare
1
顺便说一句,由于我的悬赏并没有得到明确的解决方案,我已经发布了另一个相关的SO问题,试图看看是否有一个可行的配置可以作为确定我们的问题所在的基础:https://dev59.com/L2Ij5IYBdhLWcg3wKyS0 - CommonsWare
8个回答

2
也许问题在于您将mavenCentral作为库项目的仓库。
repositories {
    mavenCentral()
}

而不是您的Nexus存储库,那里才存在实际的依赖关系

repositories {
    maven {
        url "http://localhost:8081/nexus/content/repositories/releases/"
}

    maven {
        url "http://localhost:8081/nexus/content/repositories/central/"
    }
}

2

你在依赖项中包含LibA的代码是错误的。为了引入一个库项目,使用以下代码:

compile project(':LibA')

如果库的目录不在项目目录的根目录下,您需要指定一个以冒号分隔的路径。例如,如果您的目录结构如下:
projectFolder
  |
  +--coreProject
  |
  +--libraries
      |
      +--LibA
      |
      +--LibB
你的依赖关系将是:
compile project(':libraries:LibA')

这与您在settings.gradle文件中使用的表示法相同。

据我所知,这是您用于本地依赖项的方法,即代码实际上在项目结构中的依赖项。在我的示例中,我正在使用从mavencentral和自定义maven存储库中拉取的远程依赖项。我的目标是避免在我的项目中使用本地代码,以便我不需要子模块来更新它们。 - sgarman
好的,你能否在命令行中运行构建并添加--info命令行选项?这可能会更清楚地说明出了什么问题。可能是你的本地Maven存储库没有正确设置,Gradle找不到LibA。你如何设置本地Maven存储库? - Scott Barta
是的,本地Maven仓库对于所有常规的Android库和JAR包都可以正常工作。只有当添加一个具有另一个Android库项目依赖项的库项目时,才会出现上述错误消息。在原帖中添加了-info error。 - sgarman
我会在上面的帖子中发布代码,请告诉我是否看到错误。 - sgarman
我去了本地仓库并验证了LibA aars是否已经发布。它们在那里,但是可能LibA构建文件中仍然有一些配置错误。 - sgarman
显示剩余3条评论

2
如果您同时上传了jar和aar库文件,请尝试以下方法。
compile 'com.example:LibA:1.1.1@aar'

1
如果您不想将其作为子模块添加到第一个build.gradle文件中,可以将本地maven存储库添加到其中。
mavenLocal()
//repositories
repositories {
    mavenCentral()
    mavenLocal()
}

但是您需要先在libA上运行安装。

Luis,我相当确定使用我的自定义Maven仓库与本地Maven是完全相同的过程 - 这仍然会产生我上面所述的错误。 - sgarman

1

我在引入库时不小心造成了循环依赖,导致出现类似的错误信息:

commons-utils中的build.gradle文件

dependencies {
    ...
    instrumentTestCompile project(':test-utils')
}

test-utils 中的 build.gradle

dependencies {
    ...
    compile project(':commons-utils')
}

修复这个问题解决了该问题。错误信息不是很明确。

1

这些是Maven托管的Gradle项目,而不是本地源Gradle项目。如果您继续阅读您链接的部分,您也会看到类似的依赖声明。 - sgarman
我明白了。还有一件事可以尝试,就是列出每个库项目的依赖关系(http://www.gradle.org/docs/current/userguide/tutorial_gradle_command_line.html#para:commandline_dependency_report),然后再列出核心项目的依赖关系,并查看差异并进行调试。 - omermuhammed
我在核心项目上运行了该命令,但实际上它出现了相同的错误,当我尝试构建时也是如此,因此我无法收集任何其他信息。 - sgarman
我看到了Scott在aar文件方面的帖子,这激发了我的记忆。看一下这篇文章:http://www.flexlabs.org/2013/06/using-local-aar-android-library-packages-in-gradle-builds,它可能会有所帮助。 - omermuhammed
感谢提供链接,但我并没有遇到这个问题,因为我的AAR文件已经是“远程”的或者说是由Maven(即自定义的Nexus)提供的。问题在于当我添加具有库依赖关系的库时会发生什么情况。这只是添加了一个单一的库依赖项,而且运行良好。 - sgarman

1

不能确定,只是几个想法:

  1. 您是否尝试运行gradle assemble而不是gradle build?这将跳过测试,因为我看到错误与测试任务相关。
  2. 也许很傻,但是尝试从第一个依赖项中删除第二个依赖项,并将其放入您的主构建文件列表中,在第一个之前列出。我记得有一些相关的东西。这样,第二个库可能会被添加到类路径中,从而使第一个可以编译。
  3. 尝试手动创建.aar文件,并手动将其上传到repo。
  4. 这是一个技巧,但也许它会起作用:您考虑过排除这个:GradleTest模块吗?请参见第50.4.7节

  1. 使用assembled时也出现了同样的错误,我认为其中一个项目实际上被称为GradleTest。2) 我还没有尝试过...但这违背了依赖管理的整个目的 - 我的项目不应该知道其他项目的依赖关系。
- sgarman

0
这个问题已经在后续版本的Gradle和Android Gradle插件中得到了解决。看起来只是早期版本的一个bug。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接