web-dev-qa-db-fra.com

Comment définir un chemin de classe de compilation * uniquement * dans Gradle?

Quelqu'un peut-il me donner un exemple simple de build.gradle de la façon dont je peux spécifier des classes de compilation uniquement qui ne sont pas incluses dans le déploiement à l'exécution (war).

Gradle semble avoir mal compris cela car "runtime" hérite de "compile". Je ne peux pas imaginer une situation où je voudrais des classes au moment de l'exécution que je ne voudrais pas au moment de la compilation. Cependant, il y a de nombreuses circonstances où j'ai besoin de classes pour générer du code au moment de la compilation que je ne souhaite pas déployer au moment de l'exécution!

J'ai parcouru la documentation de Gradle gonflée mais je ne trouve aucune instruction ou exemple clair. Je soupçonne que cela pourrait être réalisé en définissant une "configuration" et en la définissant comme chemin de classe du plugin CompileJava - mais la documentation ne parvient pas à expliquer comment y parvenir.

62
Alex Worden

Il y a eu beaucoup de discussions sur ce sujet, principalement ici , mais pas de conclusion claire.

Vous êtes sur la bonne voie: actuellement, la meilleure solution consiste à déclarer votre propre configuration provided, qui inclura les dépendances de compilation uniquement et à ajouter à votre chemin de classe de compilation:

configurations{
  provided
}

dependencies{
  //Add libraries like lombok, findbugs etc
  provided '...'
}

//Include provided for compilation
sourceSets.main.compileClasspath += [configurations.provided]

// optional: if using 'idea' plugin
idea {
  module{
    scopes.PROVIDED.plus += [configurations.provided]
  }
}

// optional: if using 'Eclipse' plugin
Eclipse {
  classpath {
    plusConfigurations += [configurations.provided]
  }
}

Cela fonctionne généralement bien.

56
rodion

Si vous utilisez le plugin war, providedCompile devrait faire l'affaire. Cependant, si vous devez exclure des dépendances d'être incluses dans un pot , vous devrez étendre la tâche jar. Vous trouverez ci-dessous un exemple de construction d'un "gros pot" ou "uber jar" (un seul pot qui inclut toutes les classes de ses dépendances) à l'exclusion des dépendances marquées provided:

configurations {
    provided
    compile.extendsFrom provided
}

dependencies {
    provided "group.artifact:version"
    compile "group.artifact:version"
}

jar {
    dependsOn configurations.runtime
    from {
        (configurations.runtime - configurations.provided).collect {
            it.isDirectory() ? it : zipTree(it)
        }
    } 
}

Crédit: http://kennethjorgensen.com/blog/2014/fat-jars-with-excluded-dependencies-in-gradle/

Mise à jour:

Depuis Gradle 2.12 le problème de la définition des dépendances de compilation uniquement est finalement résolu de manière simple et naturelle par la nouvelle configuration "copmpileOnly":

dependencies {
    compileOnly 'javax.servlet:servlet-api:2.5'
}
12
Doron Gold

Je l'ai compris pour la configuration de mon projet. J'utilise Android Studio fonctionnant avec le plugin gradle 0.9. + Avec gradle 1.11 Le projet principal utilise des publicités Amazon et des achats inapp Amazon. Cela dépend d'un projet de bibliothèque utilisant la messagerie d'appareil Amazon (ADM).

Mon problème principal était avec l'ADM, où j'ai eu le "RuntimeException: Stub!" Erreur.

1.) Projet de bibliothèque: La "configuration fournie" proposée par Lukas ne fonctionne pas, comme il l'a déclaré, j'ai donc utilisé l'approche de Richards, qui n'a cependant pas fonctionné aussi bien hors de la boîte. J'ai dû le changer un peu car je n'ai pas pu trouver la lib dans le dossier ext_libs du fichier aar. Gradle semble emballer toutes les bibliothèques dans le dossier libs dans le fichier aar final.

Android.libraryVariants.all { variant ->
variant.packageLibrary.exclude( 'libs/Amazon-device-messaging-1.0.1.jar' )
}

2.) Projet d'application: Ici, l'approche avec la "configuration fournie" a fonctionné.

configurations{
    provided
} 
dependencies {
    compile 'fr.avianey:facebook-Android-api:+@aar'
    compile files('ext_libs/Amazon-ads-5.3.22.jar')
    compile files('ext_libs/in-app-purchasing-1.0.3.jar' )
    provided files('ext_libs/Amazon-device-messaging-1.0.1.jar')
}

Android.applicationVariants.all {
    variant -> variant.javaCompile.classpath += configurations.provided
}
9
Mike T

Il est assez courant d'avoir des dépendances d'exécution qui ne sont pas des dépendances de temps de compilation. L'inverse est un cas assez spécial et nécessite donc quelques lignes de configuration dans Gradle. Je suggère de rechercher le forum Gradle pour provided.

Cela ressemble à ce que vous cherchez vraiment à déclarer les dépendances pour votre build , pas pour le chemin de la classe de compilation. La façon dont cela se fait dépend de la façon dont la fonctionnalité souhaitée est invoquée (tâche Ant, tâche Gradle/plug-in, utilisation ad-hoc à partir du script de construction). Si vous fournissez des informations plus détaillées sur ce que vous essayez de faire, je peux fournir une réponse plus précise.

Voici quelques liens vers des informations pertinentes dans le guide de l'utilisateur Gradle:

6

Dans Gradle 2.12, une configuration compileOnly a été introduite. Un article de blog présentant ces fonctionnalités est disponible ici:

Gradle dernière fonctionnalité: Compiler uniquement les dépendances

Veuillez noter un effet secondaire important:

Du fait de l'ajout de la configuration "compileOnly", la configuration "compile" ne représente plus une image complète de toutes les dépendances de temps de compilation. Lorsque vous avez besoin de référencer un chemin de classe de compilation dans des scripts de génération ou des plug-ins personnalisés, la propriété compileClasspath de l'ensemble source approprié doit être utilisée à la place.

6
xsveda

Si vous utilisez le plugin WAR, vous pouvez utiliser providedCompile comme dans ce exemple

dependencies {
    compile module(":compile:1.0") {
        dependency ":compile-transitive-1.0@jar"
        dependency ":providedCompile-transitive:1.0@jar"
    }
    providedCompile "javax.servlet:servlet-api:2.5"
    providedCompile module(":providedCompile:1.0") {
        dependency ":providedCompile-transitive:1.0@jar"
    }
    runtime ":runtime:1.0"
    providedRuntime ":providedRuntime:1.0@jar"
    testCompile "junit:junit:4.11"
    moreLibs ":otherLib:1.0"
}
6
Adrian H.

Il s'avère qu'ils ont ajouté une configuration "fournie" dans le gradle Android plugin 0.8.0 mais cela ne fonctionne pas tout à fait. Il ajoute automatiquement les bibliothèques fournies au chemin de compilation, mais il les inclut également dans l'aar/apk final.

Ce qui a fonctionné pour moi, c'est la solution fournie par @ lukas-hanaceck mais en changeant le nom de "fourni" en n'importe quel autre nom personnalisé. Dans mon cas, il s'agit d'un projet de bibliothèque qui est une dépendance pour mon projet d'application final Android. Heres a Gist de ce qui a fonctionné pour moi.

configurations {
   providedlibs
}

dependencies {
   providedlibs files('provided/library.jar')
}

libraryVariants.all {
    variant -> variant.javaCompile.classpath += configurations.providedlibs
}

Il se compile parfaitement et le fichier/library.jar fourni n'est pas inclus dans l'apk final. Le seul problème que j'ai est de notifier Android studio de l'existence de library.jar. Le plugin d'idée ne semble pas fonctionner pour Android studio. Im deviner qu'ils ont un autre plugin personnalisé pour synchroniser gradle avec studio.

3
aarkay

Dans Android Studio 1.0, procédez comme suit:

Android.libraryVariants.all { variant ->
    variant.outputs.each { output ->
        output.packageLibrary.exclude('libs/someLib.jar')
    }
}
2
Thomas Hofmann

Je n'ai pas trouvé de solution pour Android Studio, mais voici ce que j'ai essayé:

Dans Android studio, j'ai dû mettre à jour vers la version 0.5. +

dans gradle/gradle-wrapper.properties replace

distributionUrl=http\://services.gradle.org/distributions/gradle-1.9-rc-3-bin.Zip

par

distributionUrl=http\://services.gradle.org/distributions/gradle-1.11-all.Zip

dans tout mon build.gradle remplacer

buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.Android.tools.build:gradle:0.7.+'
    }
}

par

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

et dans la bibliothèque que je voulais utiliser à condition

configurations {
    provided
}

//put applicationVariants in case it is apply plugin: 'Android' and not apply plugin: 'Android-library'
Android.libraryVariants.all {
    variant -> variant.javaCompile.classpath += configurations.provided
}

dependencies {
    provided files('ext_libs/Amazon-device-messaging-1.0.1.jar')
}

et à la fin cela ne fonctionne pas, il semble que cela fonctionne pour jar mais pas pour aar ou apk comme indiqué ici https://groups.google.com/forum/#!topic/adt-dev/WIjtHjgoGwA

2
Lukas Hanacek

Nous n'avons pas besoin de "fourni", essayez d'ajouter ceci:

Android.libraryVariants.all { variant ->
    variant.packageLibrary.exclude( 'ext_libs/Amazon-device-messaging-1.0.1.jar' )
}

Prendre plaisir!

0
Richard Li

L'OP n'a apparemment pas cherché de réponse Android, mais certaines réponses sont spécifiques à Android. Je vous suggère donc de regarder cette page: http://tools.Android. com/tech-docs/new-build-system

La version 0.9.0 a introduit une portée fournie. Donc, utilisez simplement

dependencies {
    provided "groupId:artifcatId:version"
}
0
Snicolas