Dependências transitivas não resolvidas para a biblioteca aar usando gradle

93

Eu investiguei um pouco e provavelmente vi as respostas mais populares aqui relacionadas a aar e dependências transitivas, mas de alguma forma ainda não está claro para mim como fazer isso funcionar.

Assim:

Tenho uma biblioteca Android com a configuração do Gradle fornecida:

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

Em seguida, estou implantando no repositório maven local com gradle install. O arquivo POM da biblioteca implantada tem a seguinte aparência:

<?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, finalmente, a configuração do gradle do meu aplicativo Android usando a biblioteca acima como uma dependência:

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 depois de implantar o aplicativo no telefone estou recebendo NoClassDefFoundErrorpara classes pertencentes a dependências de compilação da minha biblioteca android.

Inspecionando minhas dependências de aplicativos 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

De acordo com a árvore acima, todas as dependências transitivas não são detectadas. Onde está o problema e como deve ser feito corretamente?

Mkorszun
fonte
1
Você examinou o resultado da execução gradle dependenciesdo seu aplicativo?
CommonsWare 01 de
E você tem certeza de que deseja a providedpalavra-chave lá? De acordo com o Xav, essas dependências não são empacotadas no APK , e eu acho que você gostaria que elas fossem empacotadas no APK.
CommonsWare
@CommonsWare gradle dependenciesfor my android lib: default - Configuração para artefatos padrão. + --- com.google.code.gson: gson: 2.2.4 + --- com.bugsense.trace: bugsense: 3.6 \ --- commons-net: commons-net: 3.3
mkorszun de
Não estou ciente de que os arquivos AAR locais como esse funcionam - acho que eles precisam ir para um repositório Maven local e ser referenciados dessa forma. Mas eu realmente estava me referindo a correr gradle dependenciespara o aplicativo , não para uma biblioteca que alguém decidiu chamar de "aplicativo".
CommonsWare
@CommonsWare, consulte a pergunta atualizada. Instalei a biblioteca no repositório maven local, mas isso não ajuda.
mkorszun 01 de

Respostas:

87

Resolvi meu problema configurando o transitiveatributo para minha dependência aar:

compile ('com.somepackage:LIBRARY_NAME:1.0.0@aar'){
    transitive=true
}
Mkorszun
fonte
3
@PeterNiederwieser Omitir as @aarcausas do Gradle para tentar obter o artefato como um arquivo .jar. Isso mata a construção.
cwc
4
Não funcionou para mim. Eu tenho o problema exato. Tenho 2 bibliotecas e uma delas está usando a outra. compile project(':LeafPeripheralsContract') { transitive=true }não funcionou. Ele reclamou sobre transitivo. E eu criei um aare tentei adicionar transitivo a ele. Não reclamou, mas também não o incluiu no outro pacote aar.
tasomaníaco
1
Não funcionou para mim também. Também tenho um classificador na dependência. Querendo saber se esse é o problema. Usando o Android Studio RC1 com ferramentas de compilação gradle 0.14.4.
perdeu a tradução em
1
Sim, se você estiver usando classificadores, não parece que as dependências transitivas funcionem. Olhe aqui: code.google.com/p/android/issues/…
lostintranslation
2
se você tiver artefatos .jar e .aar, esta é a única solução para usar o @aar e incluir transitivos.
Jeffrey Blattman,
18

você não deve usar "@aar", se usar "@" se tornar " notação apenas de artefato ", se quiser usar "@" e quiser ter dependência transitiva, você deve adicionar "transitivo = verdadeiro"

user3070402
fonte
2
Essa resposta é útil. Houve um erro de digitação em meu comentário anterior e eu o excluí. Obrigado pela sua resposta, tenha um bom dia :).
srain
14

Tente fazer isso se estiver usando aar localmente:

compile(project(:your-library-name)) {
    transitive=true
}
suhas_sm
fonte
6
Oi, não está funcionando para mim. Eu criei um projeto de biblioteca que usa internamente a biblioteca de vôlei. Eu incluí o arquivo aar criado usando o projeto de biblioteca em meu aplicativo. Estou recebendo o erro "Erro: (8, 26) erro: o pacote com.android.volley não existe". No meu projeto de biblioteca, incluí o voleibol usando compilar (project (': volley')) {transitivo = verdadeiro}
Manish
2
Ei Manish, Enfrentando o mesmo problema, você encontrou alguma solução?
Jalpesh
Estou preso com o mesmo problema
Alex
1
Você está incluindo o aar como flatDir?
Nesse
5

Eu estava tendo um problema semelhante e senti que poderia compartilhar as etapas para resolver o problema.

A ideia básica de não ser capaz de usar as dependências transitivas enquanto você está publicando as suas próprias aaré não ter o .pomarquivo gerado com as dependências transitivas esperadas.

Eu estava usando o 'maven-publish'plugin para minha aardependência do Android para publicá-lo em meu próprio repositório maven privado. As dependências transitivas não foram resolvidas quando meus outros projetos adicionaram minha aardependência a eles build.gradle. Daí o que fiz para modificar o .pomarquivo durante a publicação do meu aar.

Uma coisa importante a notar aqui que, as dependências que você deseja que tenham o comportamento transitivo devem ser importadas usando o apino build.gradlearquivo do seu projeto de biblioteca como a seguir.

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

Agora, como eu disse antes, eu estava usando o maven-publishplugin para publicar a aardependência e, portanto, minha tarefa de publicação no gradle se parece com o seguinte.

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

Portanto, usei outra mavenJavatarefa para publicar o .pomarquivo em meu repositório maven privado para que, quando o aararquivo for adicionado como uma dependência a algum outro módulo, ele obtenha as .pominformações e baixe a dependência transitiva.

Para completar a resposta, deve adicionar no build.gradlearquivo a dependência do seu próprio publicado aarpara mim importado.

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

transitivesignifica que o consumidor (por exemplo, aplicativo) inclui um produtor e todas as dependências do produtor (por exemplo, bibliotecas). Isso aumenta o tempo de construção e pode criar alguns problemas com versões de dependência

Por padrão, a dependência do Gradle tem transitive = true

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

Quando você usa @artifact notationtemtransitive = false

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

Para mim, a solução de publicação completa se parece com isto:


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

O transitive = truebloqueio também é necessário ...

Sergey Dryganets
fonte
-1

Simplesmente adicionar @aar no final da dependência é o que funcionou para mim.

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