Transitive Abhängigkeiten wurden für eine Bibliothek mit Gradle nicht aufgelöst


93

Ich habe eine Weile nachgeforscht und hier wahrscheinlich die beliebtesten Antworten in Bezug auf aar und transitive Abhängigkeiten gesehen, aber irgendwie ist mir immer noch nicht klar, wie ich das zum Laufen bringen soll.

So:

Ich habe eine Android-Bibliothek mit der angegebenen Gradle-Konfiguration:

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'
}

Dann stelle ich es für ein lokales Maven-Repo bereit gradle install. Die POM-Datei der bereitgestellten Bibliothek sieht folgendermaßen aus:

<?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>

Und schließlich gradle Konfiguration meiner Android-Anwendung unter Verwendung der obigen Bibliothek als Abhängigkeit:

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'
}

Und nachdem ich die Anwendung auf dem Telefon NoClassDefFoundErrorbereitgestellt habe, erhalte ich Klassen, die zum Kompilieren von Abhängigkeiten meiner Android-Bibliothek gehören.

Überprüfen meiner Android-Anwendungsabhängigkeiten mit gradle dependencies:

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

Gemäß dem obigen Baum werden nicht alle transitiven Abhängigkeiten erkannt. Wo liegt das Problem und wie soll es richtig gemacht werden?


1
Haben Sie die Ausgabe des Laufens gradle dependenciesfür Ihre App untersucht?
CommonsWare

Und sind Sie wirklich sicher, dass Sie das providedSchlüsselwort dort haben möchten ? Laut Xav sind solche Abhängigkeiten nicht in der APK gepackt, und ich würde denken, dass Sie möchten, dass diese in der APK gepackt werden.
CommonsWare

@CommonsWare gradle dependenciesfür meine Android- Bibliothek : Standard - Konfiguration für Standardartefakte. + --- com.google.code.gson: gson: 2.2.4 + --- com.bugsense.trace: bugsense: 3.6 \ --- commons-net: commons-net: 3.3
mkorszun

Mir ist nicht bewusst, dass solche lokalen AAR-Dateien funktionieren - ich denke, sie müssen in ein lokales Maven-Repository gehen und auf diese Weise referenziert werden. Aber ich bezog mich wirklich darauf, gradle dependenciesfür die App zu laufen , nicht für eine Bibliothek, die jemand als "App" bezeichnete.
CommonsWare

@ CommonsWare siehe aktualisierte Frage. Ich habe die Bibliothek auf dem lokalen Maven Repo installiert, aber das hilft nicht.
mkorszun

Antworten:


87

Ich habe mein Problem gelöst, indem ich ein transitiveAttribut für meine aar-Abhängigkeit festgelegt habe:

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

3
@PeterNiederwieser Wenn die @aarUrsachen weggelassen werden, versucht Gradle, das Artefakt als JAR-Datei abzurufen. Dies tötet den Build.
CWC

4
Bei mir hat es nicht funktioniert. Ich habe das genaue Problem. Ich habe 2 Bibliotheken und eine davon benutzt die andere. compile project(':LeafPeripheralsContract') { transitive=true }funktioniert nicht. Es beschwerte sich über transitiv. Und ich habe ein erstellt aarund versucht, es transitiv hinzuzufügen. Es hat sich nicht beschwert, aber es hat es auch nicht in das andere aar-Paket aufgenommen.
Tasomaniac

1
Hat auch bei mir nicht funktioniert. Ich habe auch einen Klassifikator in der Abhängigkeit. Ich frage mich, ob das das Problem ist. Verwenden von Android Studio RC1 mit Gradle Build Tools 0.14.4.
Lostintranslation

1
Ja, wenn Sie Klassifikatoren verwenden, scheint es nicht so, als ob transitive Deps funktionieren. Schauen Sie hier: code.google.com/p/android/issues/…
lostintranslation

2
Wenn Sie sowohl .jar- als auch .aar-Artefakte haben, ist dies die einzige Lösung, die @aar verwendet und Transitive einschließt.
Jeffrey Blattman

18

Sie sollten "@aar" nicht verwenden. Wenn "@" zu " Nur Artefakt-Notation " wird. Wenn Sie "@" verwenden und eine Abhängigkeit transitiv haben möchten, sollten Sie "transitiv = wahr" hinzufügen.


2
Diese Antwort ist hilfreich. In meinem vorherigen Kommentar war ein Tippfehler und ich habe diesen gelöscht. Danke für deine Antwort, einen schönen Tag noch :).
Srain

14

Versuchen Sie dies, wenn Sie aar lokal verwenden:

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

6
Hallo, es funktioniert nicht bei mir. Ich habe ein Bibliotheksprojekt erstellt, das intern die Volleybibliothek verwendet. Ich habe eine mit einem Bibliotheksprojekt erstellte AAR-Datei in meine Anwendung aufgenommen. Ich erhalte die Fehlermeldung "Fehler: (8, 26) Fehler: Paket com.android.volley existiert nicht". In mein Bibliotheksprojekt habe ich Volley mit Compile (Projekt (': Volley')) {transitive = true}
Manish

2
Hey Manish, haben Sie angesichts des gleichen Problems eine Lösung gefunden?
Jalpesh

Ich stecke mit dem gleichen Problem fest
Alex

1
Schließen Sie das aar als flatDir ein? Wenn ja, würde ich Sie auf den folgenden Kommentar verweisen: stackoverflow.com/questions/25698160/…
FloG

5

Ich hatte ein ähnliches Problem und hatte das Gefühl, die Schritte zur Lösung des Problems teilen zu können.

Die Grundidee, die transitiven Abhängigkeiten nicht verwenden zu können, während Sie Ihre eigenen veröffentlichen, aarbesteht darin, dass die .pomDatei nicht mit den erwarteten transitiven Abhängigkeiten generiert wird.

Ich habe das 'maven-publish'Plugin für meine Android- aarAbhängigkeit verwendet, um es in meinem eigenen privaten Maven-Repository zu veröffentlichen. Die transitiven Abhängigkeiten wurden nicht aufgelöst, als meine anderen Projekte meine aarAbhängigkeit in ihre hinzufügten build.gradle. Daher hier, was ich getan habe, um die .pomDatei beim Veröffentlichen meiner zu ändern aar.

Hierbei ist zu beachten, dass die Abhängigkeiten, für die Sie das transitive Verhalten wünschen, wie folgt apiin die build.gradleDatei Ihres Bibliotheksprojekts importiert werden sollten .

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

Wie ich bereits sagte, habe ich das maven-publishPlugin verwendet, um die aarAbhängigkeit zu veröffentlichen, und daher sieht meine Veröffentlichungsaufgabe im Gradle wie folgt aus.

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
        }
    }
}

Daher habe ich eine andere mavenJavaAufgabe verwendet, um die .pomDatei in meinem privaten Maven-Repo zu veröffentlichen, sodass beim Hinzufügen der aarDatei als Abhängigkeit zu einem anderen Modul die .pomInformationen abgerufen und die transitive Abhängigkeit heruntergeladen werden.

Um die Antwort zu vervollständigen, sollten Sie auf diese Weise die Abhängigkeit in der build.gradleDatei für Ihre eigene aar, mir importierte Datei hinzufügen .

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

1

transitivebedeutet, dass der Verbraucher (z. B. App) einen Produzenten und alle Abhängigkeiten des Produzenten (z. B. Bibliotheken) enthält. Dies verlängert die Erstellungszeit und kann zu Problemen mit Abhängigkeitsversionen führen

Standardmäßig hat Gradle-Abhängigkeit transitive = true

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

Wenn Sie es verwenden @artifact notation, hattransitive = false

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

0

Für mich sieht die komplette Publishing-Lösung folgendermaßen aus:


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
        }
    }
}

Der transitive = trueBlock wird auch benötigt ...


-1

Das einfache Hinzufügen von @aar am Ende der Abhängigkeit hat bei mir funktioniert.

dependencies {
    implementation 'org.videolan.vlc:libvlc:3.0.13@aar'
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.