使用 gradle 未解决 aar 库的传递依赖关系

Posted

技术标签:

【中文标题】使用 gradle 未解决 aar 库的传递依赖关系【英文标题】:Transitive dependencies not resolved for aar library using gradle 【发布时间】:2017-07-22 23:05:17 【问题描述】:

我已经调查了一段时间,可能在这里看到了与 aar传递依赖 相关的最流行的答案,但不知何故,我仍然不清楚如何使其工作。

所以:

我有带有给定 gradle 配置的 android 库:

apply plugin: 'android-library'
apply plugin: 'android-maven'

version = "1.0.0"
group = "com.somepackage"

buildscript 
    repositories 
        mavenCentral()
        mavenLocal()
    

    dependencies 
        classpath 'com.github.dcendents:android-maven-plugin:1.0'
    


android 
    compileSdkVersion 19
    buildToolsVersion '19.0.3'

    defaultConfig 
        minSdkVersion 10
    


repositories 
    maven  url 'http://www.bugsense.com/gradle/' 


dependencies 
    provided 'com.google.android.gms:play-services:+'
    provided 'com.android.support:appcompat-v7:+'
    compile 'com.google.code.gson:gson:2.2.4'
    compile 'com.bugsense.trace:bugsense:3.6'
    compile 'commons-net:commons-net:3.3'

然后我用gradle install 将它部署到本地maven repo。已部署库的 POM 文件如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.sprezzat</groupId>
  <artifactId>app</artifactId>
  <version>1.0.0</version>
  <packaging>aar</packaging>
  <dependencies>
    <dependency>
      <groupId>com.bugsense.trace</groupId>
      <artifactId>bugsense</artifactId>
      <version>3.6</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>commons-net</groupId>
      <artifactId>commons-net</artifactId>
      <version>3.3</version>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
      <version>2.2.4</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>
</project>

最后使用上述库作为依赖项对我的 android 应用程序进行 gradle 配置:

buildscript 
    repositories 
        mavenCentral()
    
    dependencies 
        classpath 'com.android.tools.build:gradle:0.9.+'
    

apply plugin: 'android'

repositories 
    mavenCentral()
    mavenLocal()


android 
    compileSdkVersion 15
    buildToolsVersion "19.0.2"

    defaultConfig 
        minSdkVersion 10
        targetSdkVersion 18
    


dependencies 
    compile 'com.google.android.gms:play-services:+'
    compile 'com.android.support:appcompat-v7:+'
    compile 'com.somepackage:LIBRARY_NAME:1.0.0@aar'

在手机上部署应用程序后,我得到了 NoClassDefFoundError 用于属于我的 android 库的编译依赖项的类。

使用 gradle dependencies 检查我的 android 应用程序依赖项:

apk - Classpath packaged with the compiled main classes.
+--- com.google.android.gms:play-services:+ -> 4.3.23
|    \--- com.android.support:support-v4:19.0.1 -> 19.1.0
+--- com.android.support:appcompat-v7:+ -> 19.1.0
|    \--- com.android.support:support-v4:19.1.0
\--- com.somepackage:LIBRARY_NAME:1.0.0

根据上面的树,没有检测到所有传递依赖。问题出在哪里,应该如何正确解决?

【问题讨论】:

您是否检查过为您的应用运行 gradle dependencies 的输出? 您确定要在此处使用provided 关键字吗?根据 Xav,such dependencies are not packaged in the APK,我认为您会希望将这些打包在 APK 中。 @CommonsWare gradle dependencies for my android lib: default - 默认工件的配置。 +--- com.google.code.gson:gson:2.2.4 +--- com.bugsense.trace:bugsense:3.6 \--- commons-net:commons-net:3.3 我不知道像这样的本地 AAR 文件 - 我认为它们需要进入本地 Maven 存储库并以这种方式引用。但我真正指的是为 app 运行 gradle dependencies,而不是为某人决定命名为“app”的库。 我应该将 pom 文件放在 aar 添加的应用程序中的什么位置 【参考方案1】:

我通过为我的 aar 依赖项设置 transitive 属性解决了我的问题:

compile ('com.somepackage:LIBRARY_NAME:1.0.0@aar')
    transitive=true

【讨论】:

@PeterNiederwieser 省略 @aar 会导致 Gradle 尝试将工件作为 .jar 文件抓取。这会杀死构建。 它对我不起作用。我有确切的问题。我有 2 个库,其中一个正在使用另一个。 compile project(':LeafPeripheralsContract') transitive=true 没用。它抱怨传递性。我创建了一个aar 并尝试添加传递给它。它没有抱怨,但也没有将其包含在另一个 aar 包中。 对我也不起作用。我在依赖项中也有一个分类器。想知道这是否是问题所在。使用带有 gradle 构建工具 0.14.4 的 Android Studio RC1。 是的,如果您使用的是分类器,那么传递 deps 似乎不起作用。看这里:code.google.com/p/android/issues/… 如果您同时拥有 .jar 和 .aar 工件,这是使用 @aar 并包含传递的唯一解决方案。【参考方案2】:

你不应该使用“@aar”,如果使用“@”变成“Artifact only notation”,如果你想使用“@”并且想要依赖传递,你应该添加“transitive=true”

【讨论】:

这个答案很有帮助。我之前的评论中有一个错字,我删除了那个。感谢您的回答,祝您有美好的一天:)。【参考方案3】:

如果你在本地使用 aar,试试这个:

compile(project(:your-library-name)) 
    transitive=true

【讨论】:

嗨,它不适合我。我创建了一个在内部使用 volley 库的库项目。我在我的应用程序中包含了使用库项目创建的 aar 文件。我收到“错误:(8, 26) 错误:com.android.volley 包不存在”错误。在我的库项目中,我使用 compile(project(':volley')) transitive = true 包含了 volley 嘿Manish,遇到同样的问题,你找到解决办法了吗? 我遇到了同样的问题 您是否将 aar 包括为 flatDir?如果是这样,我建议您参考以下评论:***.com/questions/25698160/…【参考方案4】:

我遇到了类似的问题,觉得我可以分享解决问题的步骤。

在发布自己的aar 时无法使用传递依赖项的基本想法实际上是没有生成具有预期传递依赖项的.pom 文件。

我正在为我的 android aar 依赖项使用 'maven-publish' 插件将其发布到我自己的私有 maven 存储库中。当我的其他项目在他们的build.gradle 中添加我的aar 依赖项时,传递依赖项没有得到解决。因此,在这里我在发布我的aar 时修改了.pom 文件。

这里需要注意的重要一点是,您希望具有传递行为的依赖项应使用库项目的build.gradle 文件中的api 导入,如下所示。

dependencies 
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    api 'com.android.volley:volley:1.0.0'
    api "com.google.code.gson:gson:$globalGsonVersion"

现在正如我之前所说,我使用 maven-publish 插件发布 aar 依赖项,因此我在 gradle 中的发布任务如下所示。

publishing 
    publications 
        mavenAar(MavenPublication) 
            from components.android
        

        mavenJava(MavenPublication) 
            pom.withXml 
                def dependenciesNode = asNode().appendNode('dependencies')
                // Iterate over the api dependencies (we don't want the test ones), adding a <dependency> node for each
                configurations.api.allDependencies.each 
                    def dependencyNode = dependenciesNode.appendNode('dependency')
                    dependencyNode.appendNode('groupId', it.group)
                    dependencyNode.appendNode('artifactId', it.name)
                    dependencyNode.appendNode('version', it.version)
                
            
        
    

    repositories 
        maven 
            // Your repository information goes here
        
    

因此,我使用另一个 mavenJava 任务在我的私有 maven 存储库中发布 .pom 文件,以便当 aar 文件作为依赖项添加到其他模块时,它会获取 .pom 信息和下载传递依赖。

要完成答案,这就是您应该如何在 build.gradle 文件中为您自己发布的 aar 添加到我导入的依赖项。

api('com.example.masudias:my_lib:1.0.0@aar') 
    transitive = true

【讨论】:

成功了,谢谢!不知道为什么将传递依赖项添加到 POM 不是默认行为。 不错的一个!只是在这里补充一点。当依赖添加为api时,pom文件中的依赖范围为compile。但是如果将依赖添加为implementation,则在pom文件中作用域变为runtime 感谢您对@NikhilKumar 的这些补充。欣赏! An important thing to note here that, the dependencies which you want to have the transitive behavior should be imported using the api in your library project's build.gradle file like the following. OMG,谢谢。【参考方案5】:

传递依赖

transitive 表示消费者(例如应用程序)包括生产者和所有生产者的依赖项(例如库)。它会增加构建时间并可能会导致依赖版本出现一些问题

Gradle 依赖默认有transitive = true

api ('com.package:library:0.0.1')
//the same
api ('com.package:library:0.0.1') 
    transitive = true

当您使用@artifact notation 时,它具有transitive = false

api ('com.package:library:0.0.1@aar')
//the same
api ('com.package:library:0.0.1@aar') 
    transitive = false

【讨论】:

【参考方案6】:

对我来说,完整的发布解决方案如下所示:


apply plugin: 'com.github.dcendents.android-maven'

group = GROUP
version = VERSION

// you could move it to env variable or property
def publishFlavorless = true
def firstTask = null

android.libraryVariants.all  variant ->

    if (variant.name.toLowerCase().contains("debug")) 
        // Workaround for https://github.com/gradle/gradle/issues/1487
        if (publishFlavorless && firstTask == null) 
            def bundleTask = tasks["bundle$variant.name.capitalize()Aar"]
            firstTask = bundleTask
            artifacts 
                archives(firstTask.archivePath) 
                    builtBy firstTask
                    name = project.name
                
            
        
        return
    

    def bundleTask = tasks["bundle$variant.name.capitalize()Aar"]

    artifacts 
        archives(bundleTask.archivePath) 
            classifier variant.flavorName
            builtBy bundleTask
            name = project.name
        
    


install 
    repositories.mavenInstaller 
        // This generates POM.xml with proper parameters
        pom.project 
            name POM_NAME
            artifactId POM_ARTIFACT_ID
            // For aar it is equal to 'aar' with jar transitive dependencies won't work
            packaging POM_PACKAGING
            description POM_DESCRIPTION
        
    

transitive = true 块也是必需的...

【讨论】:

【参考方案7】:

只需在依赖项末尾添加 @aar 对我有用。

dependencies 
    implementation 'org.videolan.vlc:libvlc:3.0.13@aar'

【讨论】:

以上是关于使用 gradle 未解决 aar 库的传递依赖关系的主要内容,如果未能解决你的问题,请参考以下文章

Gradle:下载包含的 aar 库的依赖项

本地 aar 库的传递依赖

项目集成aar以及gradle依赖冲突解决方式

当它具有也是 aar 库的依赖项时,如何为 android 库生成 javadoc?

怎么改变android studio中库的aar文件的输出目录

AndroidStudio引入AAR依赖