Dipendenze transitive non risolte per la libreria aar utilizzando gradle


93

Ho studiato un po 'e probabilmente ho visto le risposte più popolari qui relative a dipendenze aar e transitive, ma in qualche modo non è ancora chiaro per me come farlo funzionare.

Così:

Ho una libreria Android con una configurazione gradle data:

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

Quindi lo sto distribuendo in un repository esperto locale con gradle install. Il file POM della libreria distribuita ha questo aspetto:

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

E infine gradle la configurazione della mia applicazione Android utilizzando la libreria sopra come dipendenza:

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

E dopo aver distribuito l'applicazione sul telefono, ottengo NoClassDefFoundErrorclassi appartenenti alla compilazione delle dipendenze della mia libreria Android.

Ispezionare le dipendenze delle mie applicazioni Android utilizzando 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

Secondo l'albero sopra, tutte le dipendenze transitive non vengono rilevate. Dov'è il problema e come dovrebbe essere fatto correttamente?


1
Hai esaminato l'output della corsa gradle dependenciesper la tua app?
CommonsWare

E sei davvero sicuro di volere la providedparola chiave lì? Secondo Xav, tali dipendenze non sono impacchettate nell'APK e penso che vorresti che fossero impacchettate nell'APK.
CommonsWare

@CommonsWare gradle dependenciesper la mia libreria Android: default - Configurazione per artefatti predefiniti. + --- com.google.code.gson: gson: 2.2.4 + --- com.bugsense.trace: bugsense: 3.6 \ --- commons-net: commons-net: 3.3
mkorszun

Non sono a conoscenza del fatto che i file AAR locali come questo funzionino: penso che debbano entrare in un repository Maven locale ed essere referenziati in questo modo. Ma mi riferivo davvero alla corsa gradle dependenciesper l' app , non per una libreria che qualcuno ha deciso di chiamare "app".
CommonsWare

@CommonsWare, vedere la domanda aggiornata. Ho installato la libreria nel repository Maven locale, ma questo non aiuta.
mkorszun

Risposte:


87

Ho risolto il mio problema impostando l' transitiveattributo per la mia dipendenza aar:

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

3
@PeterNiederwieser Omettendo le @aarcause Gradle tenterà di afferrare l'artefatto come file .jar. Questo uccide la build.
cwc

4
Non ha funzionato per me. Ho il problema esatto. Ho 2 biblioteche e una di loro sta usando l'altra. compile project(':LeafPeripheralsContract') { transitive=true }non ha funzionato. Si lamentava della transitiva. E ho creato un aare ho provato ad aggiungere transitivo ad esso. Non si lamentava ma non lo includeva anche nell'altro pacchetto aar.
tasomaniac

1
Non ha funzionato neanche per me. Ho anche un classificatore nella dipendenza. Chiedendosi se questo è il problema. Utilizzo di Android Studio RC1 con gli strumenti di build gradle 0.14.4.
persa

1
Sì, se stai usando classificatori, non sembra che i deps transitivi funzionino. Guarda qui: code.google.com/p/android/issues/…
lostintranslation

2
se hai artefatti sia .jar che .aar, questa è l'unica soluzione per usare @aar e includere transitivi.
Jeffrey Blattman

18

non dovresti usare "@aar", se usare "@" è diventato " notazione solo artefatto ", se vuoi usare "@" e vuoi avere una dipendenza transitiva, devi aggiungere "transitive = true"


2
Questa risposta è utile. C'era un errore di battitura nel mio commento precedente e l'ho cancellato. Grazie per la tua risposta, buona giornata :).
srain

14

Prova questo se stai usando aar localmente:

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

6
Ciao, non funziona per me. Ho creato un progetto di biblioteca che utilizza internamente la biblioteca di volley. Ho incluso il file aar creato utilizzando il progetto di libreria nella mia applicazione. Ricevo l'errore "Errore: (8, 26): il pacchetto com.android.volley non esiste". Nel mio progetto di libreria, ho incluso volley usando compile (project (': volley')) {transitive = true}
Manish

2
Ehi Manish, affrontando lo stesso problema, hai trovato una soluzione?
Jalpesh

Sono bloccato con lo stesso problema
Alex

1
Stai includendo l'aar as flatDir? Se è così, vorrei fare riferimento alla seguente commento: stackoverflow.com/questions/25698160/...
flog

5

Avevo un problema simile e sentivo di poter condividere i passaggi per risolvere il problema.

L'idea di base di non essere in grado di utilizzare le dipendenze transitive mentre si pubblica la propria aarè in realtà di non avere il .pomfile generato con le dipendenze transitive previste.

Stavo usando il 'maven-publish'plugin per la mia aardipendenza Android per pubblicarlo nel mio repository privato di Maven. Le dipendenze transitive non sono state risolte quando i miei altri progetti stavano aggiungendo la mia aardipendenza nei loro file build.gradle. Ecco quindi cosa ho fatto per modificare il .pomfile durante la pubblicazione del mio aar.

Una cosa importante da notare qui che, le dipendenze per le quali si desidera avere il comportamento transitivo dovrebbero essere importate utilizzando apinel build.gradlefile del progetto della libreria come segue.

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

Ora, come ho detto prima, stavo usando il maven-publishplugin per pubblicare la aardipendenza e quindi il mio compito di pubblicazione nel gradle è simile al seguente.

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

Quindi, ho usato un'altra mavenJavaattività per pubblicare il .pomfile nel mio repository privato Maven in modo che quando il aarfile viene aggiunto come dipendenza a qualche altro modulo, ottiene il.pom informazioni e scarica la dipendenza transitiva.

Per completare la risposta, ecco come dovresti aggiungere la dipendenza nel build.gradlefile aarimportato per il tuo pubblicato .

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

2

transitivesignifica che il consumatore (es. app) include un produttore e tutte le dipendenze del produttore (es. librerie). Aumenta il tempo di compilazione e può creare alcuni problemi con le versioni delle dipendenze

Per impostazione predefinita, la dipendenza Gradle ha transitive = true

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

Quando lo usi @artifact notationlo hatransitive = false

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

0

Per me la soluzione di pubblicazione completa è simile a questa:


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

Anche il transitive = trueblocco è obbligatorio ...


-1

La semplice aggiunta di @aar alla fine della dipendenza è ciò che ha funzionato per me.

dependencies {
    implementation 'org.videolan.vlc:libvlc:3.0.13@aar'
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.