Dependencias transitivas no resueltas para la biblioteca aar usando gradle

93

He investigado un tiempo y probablemente vi las respuestas más populares aquí relacionadas con las dependencias aar y transitivas, pero de alguna manera todavía no me queda claro cómo hacer que esto funcione.

Entonces:

Tengo una biblioteca de Android con la configuración gradle dada:

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

Luego lo estoy implementando en el repositorio local de maven con gradle install. El archivo POM de la biblioteca implementada tiene este aspecto:

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

Y finalmente gradle config de mi aplicación de Android usando la biblioteca anterior como dependencia:

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

Y después de implementar la aplicación en el teléfono, obtengo NoClassDefFoundErrorclases que pertenecen a compilar dependencias de mi biblioteca de Android.

Inspeccionando las dependencias de mi aplicación de Android usando 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

Según el árbol anterior, no se detectan todas las dependencias transitivas. ¿Dónde está el problema y cómo se debe hacer correctamente?

mkorszun
fuente
1
¿Ha examinado el resultado de la ejecución gradle dependenciesde su aplicación?
CommonsWare
¿Está realmente seguro de que quiere la providedpalabra clave allí? Según Xav, tales dependencias no están empaquetadas en el APK , y creo que querría que estuvieran empaquetadas en el APK.
CommonsWare
@CommonsWare gradle dependenciespara mi lib de Android: predeterminado: configuración para artefactos predeterminados. + --- com.google.code.gson: gson: 2.2.4 + --- com.bugsense.trace: bugsense: 3.6 \ --- commons-net: commons-net: 3.3
mkorszun
No soy consciente de que los archivos AAR locales como ese funcionen; creo que deben ir a un repositorio local de Maven y ser referenciados de esa manera. Pero realmente me refería a ejecutar gradle dependenciespara la aplicación , no para una biblioteca que alguien decidió llamar "aplicación".
CommonsWare
@CommonsWare, consulte la pregunta actualizada. He instalado la biblioteca en el repositorio local de maven, pero esto no ayuda.
mkorszun

Respuestas:

87

He resuelto mi problema estableciendo un transitiveatributo para mi dependencia de aar:

compile ('com.somepackage:LIBRARY_NAME:1.0.0@aar'){
    transitive=true
}
mkorszun
fuente
3
@PeterNiederwieser Omitir las @aarcausas hace que Gradle intente tomar el artefacto como un archivo .jar. Esto mata la construcción.
cwc
4
No funcionó para mí. Tengo el mismo problema. Tengo 2 bibliotecas y una de ellas usa la otra. compile project(':LeafPeripheralsContract') { transitive=true }no funcionó. Se quejó de transitivo. Y creé un aary traté de agregarle transitivo. No se quejó, pero tampoco lo incluyó en el otro paquete aar.
tasomaniac
1
Tampoco funcionó para mí. También tengo un clasificador en la dependencia. Preguntándose si ese es el problema. Usando Android Studio RC1 con herramientas de compilación gradle 0.14.4.
lostintranslation
1
Sí, si está utilizando clasificadores, no parece que funcione el deps transitivo. Mira aquí: code.google.com/p/android/issues/…
lostintranslation
2
si tiene artefactos .jar y .aar, esta es la única solución para usar @aar e incluir transitorios.
Jeffrey Blattman
18

no debe usar "@aar", si el uso de "@" se convierte en " Notación de solo artefacto ", si desea usar "@" y desea tener dependencia transitiva, debe agregar "transitive = true"

user3070402
fuente
2
Esta respuesta es útil. Hubo un error tipográfico en mi comentario anterior y lo eliminé. Gracias por tu respuesta, que tengas un buen día :).
sábado
14

Pruebe esto si está usando aar localmente:

compile(project(:your-library-name)) {
    transitive=true
}
suhas_sm
fuente
6
Hola, no me está funcionando. He creado un proyecto de biblioteca que utiliza internamente la biblioteca de volley. He incluido un archivo aar creado con un proyecto de biblioteca en mi aplicación. Recibo el error "Error: (8, 26) error: el paquete com.android.volley no existe". En mi proyecto de biblioteca, he incluido volley usando compile (project (': volley')) {transitive = true}
Manish
2
Hola Manish, Enfrentando el mismo problema, ¿encontraste alguna solución?
Jalpesh
Estoy atrapado con el mismo problema
Alex
1
¿Estás incluyendo el aar como flatDir? Si es así, le
recomendaría
5

Tenía un problema similar y sentí que podía compartir los pasos para resolverlo.

La idea básica de no poder usar las dependencias transitivas mientras publica las suyas aares en realidad no tener el .pomarchivo generado con las dependencias transitivas esperadas.

Estaba usando un 'maven-publish'complemento para mi aardependencia de Android para publicarlo en mi propio repositorio privado de maven. Las dependencias transitivas no se resolvieron cuando mis otros proyectos agregaban mi aardependencia en su build.gradle. De ahí lo que hice para modificar el .pomarchivo mientras publicaba mi aar.

Una cosa importante a tener en cuenta aquí es que las dependencias que desea que tengan el comportamiento transitivo deben importarse usando el archivo apidel proyecto de su biblioteca build.gradlecomo se muestra a continuación.

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

Ahora, como dije antes, estaba usando un maven-publishcomplemento para publicar la aardependencia y, por lo tanto, mi tarea de publicación en el gradle se ve así.

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

Por lo tanto, utilicé otra mavenJavatarea para publicar el .pomarchivo en mi repositorio de maven privado para que cuando el aararchivo se agregue como una dependencia a algún otro módulo, obtenga la .pominformación y descargue la dependencia transitiva.

Para completar la respuesta, así es como debe agregar la dependencia en el build.gradlearchivo para su propia publicación aarque me importó.

api('com.example.masudias:my_lib:1.0.0@aar') {
    transitive = true
}
Reaz Murió
fuente
2

transitivesignifica que el consumidor (por ejemplo, la aplicación) incluye un productor y todas las dependencias del productor (por ejemplo, bibliotecas). Aumenta el tiempo de compilación y puede crear algunos problemas con las versiones de dependencia.

De forma predeterminada, la dependencia de Gradle tiene transitive = true

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

Cuando lo usas @artifact notationtienetransitive = false

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

Para mí, la solución de publicación completa se ve así:


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

El transitive = truebloque también es necesario ...

Sergey Dryganets
fuente
-1

Simplemente agregando @aar al final de la dependencia es lo que funcionó para mí.

dependencies {
    implementation 'org.videolan.vlc:libvlc:3.0.13@aar'
}
Merc
fuente