Outils pour utilisateurs

Outils du site


prog:gradle

Compatibilité

  • Java
JavaMinimum Gradle
82.0
94.3
104.7
115.0
125.4
136.0
146.3
156.7
167.0
177.3
187.5
197.6
208.3

Compatibility Matrix Archive du 2023 le 18/08/2023

Options en ligne de commande

Pour améliorer la vitesse de compilation, essayer d'activer les options --parallel --daemon --configuration-cache --build-cache

build.gradle

Android

Debug / Release

  • Pour du Debug :
shrinkResources false
minifyEnabled false
debuggable true
jniDebuggable true
ndk {
  debugSymbolLevel 'FULL'
}
packagingOptions {
  doNotStrip '**/*.so'
}
  • Pour du Release :

minifyEnabled se met à false pour les librairies sinon le fichier classes.jar sera vide et il ne sera pas possible de utiliser la librairie externe sous Android Studio.

shrinkResources se met à false pour une librairie.

shrinkResources se met à false si minifyEnabled est déjà à false.

minifyEnabled se met à false si on souhaite utilise jni, y compris dans l'application principale en Android avec JNI qui utilise une librairie avec NDK.

shrinkResources true
minifyEnabled true
debuggable false
jniDebuggable false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'

Attention, il existe les fichiers proguard-android-optimize.txt et proguard-android.txt. Les deux sont destinés au release. Le fichier optimize ajoute des optimisations qui peuvent être incompatibles avec certains programmes. Shrink, obfuscate, and optimize your app, Archive du 19/09/2022 le 22/09/2022

  • Non compatible

Le champ testBuildType est commun entre debug et release. Il faut donc trouver un moyen de savoir si on veut en release ou debug.

android {
  testBuildType 'debug'
  gradle.startParameter.taskNames.each{value ->
    if (value.indexOf('ebug') != -1)
      testBuildType 'debug'
    else if (value.indexOf('elease') != -1)
      testBuildType 'release'
  }
 
  ...

API

NDK

  • CMake

Il n'est pas possible de voir les logs de CMake pour la configuration et la compilation. Il faut aller voir directement les fichiers :

build/intermediates/cxx/*/*/logs/*/configure_stdout.txt
build/intermediates/cxx/*/*/logs/*/configure_stderr.txt
build/intermediates/cxx/*/*/logs/*/build_stdout_project.txt
build/intermediates/cxx/*/*/logs/*/build_stderr_project.txt

Java

  • Ajouter des options de compilation
android {
  gradle.projectsEvaluated {
    tasks.withType(JavaCompile) {
      options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
    }
  }
  ...

Task

  • Ajout d'une tâche

Cette tâche exécute un script generate_assets.py qui génère des fichiers draw1.xml à draw10.xml.

Renseigner inputs et outputs va servir uniquement à relancer la task si l'un de ces fichiers est modifié. Authoring Tasks ou Authoring Tasks Github Archive du 24/05/2023 le 08/06/2023

task generateAssets(type: Exec) {
  int startDelay = 100;
  int endDelay = 10000;
  int stepDelay = 100;
 
  inputs.files("${project.projectDir}/../tools/generate_assets.py")
  for (int i = 1; i <= 10; i = i + 1) {
    outputs.files file("${project.projectDir}/src/main/res/drawable/draw" + i.toString() + ".xml")
  }
  workingDir "${project.projectDir}/../tools"
  commandLine 'python', 'generate_assets.py'
}

Code ne fonctionnant pas avec configuration cache :

outputs.upToDateWhen {
  def result = exec {
    workingDir '../tools'
    commandLine 'python', 'generate_assets.py', '100', '10000', '100', 'dry-run'
    ignoreExitValue = true
  }
  return result.exitValue == 0
}

Code ne fonctionnant pas car la modification des fichiers n'est pas détectée :

outputs.files  fileTree("${project.buildDir}/many").matching { include '*.txt' }

Ajout d'une dépendance entre deux tâches :

tasks.whenTaskAdded { task ->
  if (task.name.startsWith('compile')) {
    task.dependsOn generateAssets
  }
}

Ligne de commandes

Les paramètres des lignes de commande sont accessibles depuis un fichier build.gradle.

  • project.gradle.startParameter.logLevel.name() == 'DEBUG' permet de savoir si l'option --debug a été appliquée.

Debug

Afficher des messages dans la console pour afficher la valeur des variables.

project.logger.lifecycle('my message visible by default')

plugins

pmd

  • Quand tout va bien

Il suffit de rajouter en plus d'un plugin java ou un de ses dérivés (java-library, com.android.library, com.android.application) :

plugins {
    id 'pmd'
}

et une configuration :

pmd {
    consoleOutput = true
    toolVersion = "6.55.0"
    ignoreFailures = true
    threads = 2
    ruleSets = [
            "category/java/bestpractices.xml",
            "category/java/codestyle.xml",
            "category/java/design.xml",
            "category/java/documentation.xml",
            "category/java/errorprone.xml",
            "category/java/multithreading.xml",
            "category/java/performance.xml",
            "category/java/security.xml"]
}

Pour vérifier qu'il y a bien la bonne tâche d'ajoutée, il faut exécuter gradlew tasks et voir un ou plusieurs tâches

lib:pmdMain - Run PMD analysis for main classes
lib:pmdTest - Run PMD analysis for test classes
  • Tâches manquantes

Dans le cas d'un projet Android avec du ndk, je n'ai pas réussi à faire fonctionner pmd de façon native. Il faut alors forcer la création de la tâche.

android {
    tasks.register("pmd", Pmd) {
        consoleOutput = true
        ignoreFailures = true
        ruleSets = [
                "category/java/bestpractices.xml",
                "category/java/codestyle.xml",
                "category/java/design.xml",
                "category/java/documentation.xml",
                "category/java/errorprone.xml",
                "category/java/multithreading.xml",
                "category/java/performance.xml",
                "category/java/security.xml"]
        source 'src'
        include '**/*.java'
        exclude '**/build/**'
        threads = 2
 
        reports {
            xml.enabled = false
            html.enabled = true
            html {
                destination = file("$project.buildDir/reports/pmd/pmd.html")
            }
        }
    }
}
 
pmd {
    toolVersion = "6.55.0"
}

build.gradle nextcloud/android Archive du 17/04/2023 le 17/04/2023

  • Désactiver des règles spécifiques

Il faut passer par un fichier de config spécifique.

rules.xml
<?xml version="1.0"?>
 
<ruleset name="Custom Rules"
    xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
 
    <description>
        My custom rules
    </description>
 
    <rule ref="category/java/bestpractices.xml">
    </rule>
    <rule ref="category/java/codestyle.xml">
    </rule>
    <rule ref="category/java/design.xml">
    </rule>
    <rule ref="category/java/documentation.xml">
        <exclude name="CommentRequired"/>
    </rule>
    <rule ref="category/java/errorprone.xml">
    </rule>
    <rule ref="category/java/multithreading.xml">
    </rule>
    <rule ref="category/java/performance.xml">
    </rule>
    <rule ref="category/java/security.xml">
    </rule>
</ruleset>

Et mettre dans build.gradle :

ruleSetFiles = files('config/pmd/rules.xml')

Making rulesets Archive du 25/11/2022 le 12/05/2023

  • Ignorer certaines erreurs

Ajouter sur la ligne indiquée par pmd le commentaire // NOPMD

Suppressing warnings Archive du 27/04/2023 le 16/05/2023

checkstyle

  • Quand tout va bien

Il suffit de rajouter en plus d'un plugin java ou un de ses dérivés (java-library, com.android.library, com.android.application) :

plugins {
    id 'checkstyle'
}

et une configuration :

checkstyle {
    toolVersion '10.9.3'
    configFile file("config/checkstyle/checkstyle.xml")
}

Pour vérifier qu'il y a bien la bonne tâche d'ajoutée, il faut exécuter gradlew tasks et voir un ou plusieurs tâches

lib:checkstyleMain - Run Checkstyle analysis for main classes
lib:checkstyleTest - Run Checkstyle analysis for test classes
  • Tâches manquantes

Dans le cas d'un projet Android avec du ndk, je n'ai pas réussi à faire fonctionner checkstyle de façon native. Il faut alors forcer la création de la tâche.

android {
    tasks.register('checkstyleMain', Checkstyle) {
        configFile = file('config/checkstyle/checkstyle.xml')
        source 'src'
        include '**/*.java'
        exclude '**/build/**'
        classpath = files()
    }
 
}
 
checkstyle {
    toolVersion '10.9.3'
}

Le fichier checkstyle peut se récupérer directement dans le code de l'application (penser à bien configurer toolVersion) : google_checks.xml

build.gradle nextcloud/android Archive du 17/04/2023 le 17/04/2023

javadoc

  • Quand tout va bien
javadoc {
  source = sourceSets.main.allJava
  classpath = configurations.compile
}
  • Tâches manquantes

Pour un projet Android et/ou avec du code généré, il peut être nécessaire d'utiliser le code généré par la compilation Java.

android {
  tasks.register("javadoc${variant.name.capitalize()}", Javadoc) {
    source = variant.sourceSets.collect { it.java.sourceFiles }.inject { m, i -> m + i }
    doFirst {
      classpath = project.files(variant.javaCompileProvider.get().classpath.files,
        project.android.getBootClasspath(),
        "${project.buildDir}/intermediates/javac/${variant.name}",
        "${project.buildDir}/generated/data_binding_base_class_source_out/${variant.name}/out")
    }
    options.addBooleanOption('Xdoclint:all', true)
    dependsOn "assemble${variant.name.capitalize()}"
    // To enable error on warning
    // options.addStringOption('Xwerror', '-quiet')
  }
}

Messages d'erreur

  • kotlin
Execution failed for task ':app:checkDuplicateClasses'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.CheckDuplicatesRunnable
   > Duplicate class kotlin.collections.jdk8.CollectionsJDK8Kt found in modules jetified-kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and jetified-kotlin-stdlib-jdk8-1.6.21 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21)
     Duplicate class kotlin.internal.jdk7.JDK7PlatformImplementations found in modules jetified-kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and jetified-kotlin-stdlib-jdk7-1.6.21 (org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.21)
     Duplicate class kotlin.internal.jdk7.JDK7PlatformImplementations$ReflectSdkVersion found in modules jetified-kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and jetified-kotlin-stdlib-jdk7-1.6.21 (org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.21)
     Duplicate class kotlin.internal.jdk8.JDK8PlatformImplementations found in modules jetified-kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and jetified-kotlin-stdlib-jdk8-1.6.21 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21)
     Duplicate class kotlin.internal.jdk8.JDK8PlatformImplementations$ReflectSdkVersion found in modules jetified-kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and jetified-kotlin-stdlib-jdk8-1.6.21 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21)
     Duplicate class kotlin.io.path.ExperimentalPathApi found in modules jetified-kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and jetified-kotlin-stdlib-jdk7-1.6.21 (org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.21)
     Duplicate class kotlin.io.path.PathRelativizer found in modules jetified-kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and jetified-kotlin-stdlib-jdk7-1.6.21 (org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.21)
     Duplicate class kotlin.io.path.PathsKt found in modules jetified-kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and jetified-kotlin-stdlib-jdk7-1.6.21 (org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.21)
     Duplicate class kotlin.io.path.PathsKt__PathReadWriteKt found in modules jetified-kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and jetified-kotlin-stdlib-jdk7-1.6.21 (org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.21)
     Duplicate class kotlin.io.path.PathsKt__PathUtilsKt found in modules jetified-kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and jetified-kotlin-stdlib-jdk7-1.6.21 (org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.21)
     Duplicate class kotlin.jdk7.AutoCloseableKt found in modules jetified-kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and jetified-kotlin-stdlib-jdk7-1.6.21 (org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.6.21)
     Duplicate class kotlin.jvm.jdk8.JvmRepeatableKt found in modules jetified-kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and jetified-kotlin-stdlib-jdk8-1.6.21 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21)
     Duplicate class kotlin.random.jdk8.PlatformThreadLocalRandom found in modules jetified-kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and jetified-kotlin-stdlib-jdk8-1.6.21 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21)
     Duplicate class kotlin.streams.jdk8.StreamsKt found in modules jetified-kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and jetified-kotlin-stdlib-jdk8-1.6.21 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21)
     Duplicate class kotlin.streams.jdk8.StreamsKt$asSequence$$inlined$Sequence$1 found in modules jetified-kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and jetified-kotlin-stdlib-jdk8-1.6.21 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21)
     Duplicate class kotlin.streams.jdk8.StreamsKt$asSequence$$inlined$Sequence$2 found in modules jetified-kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and jetified-kotlin-stdlib-jdk8-1.6.21 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21)
     Duplicate class kotlin.streams.jdk8.StreamsKt$asSequence$$inlined$Sequence$3 found in modules jetified-kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and jetified-kotlin-stdlib-jdk8-1.6.21 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21)
     Duplicate class kotlin.streams.jdk8.StreamsKt$asSequence$$inlined$Sequence$4 found in modules jetified-kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and jetified-kotlin-stdlib-jdk8-1.6.21 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21)
     Duplicate class kotlin.text.jdk8.RegexExtensionsJDK8Kt found in modules jetified-kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and jetified-kotlin-stdlib-jdk8-1.6.21 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21)
     Duplicate class kotlin.time.jdk8.DurationConversionsJDK8Kt found in modules jetified-kotlin-stdlib-1.8.10 (org.jetbrains.kotlin:kotlin-stdlib:1.8.10) and jetified-kotlin-stdlib-jdk8-1.6.21 (org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.6.21)
     
     Go to the documentation to learn how to <a href="d.android.com/r/tools/classpath-sync-errors">Fix dependency resolution errors</a>.

Il manque le plugin kotlin. Même si vous n'utilisez pas de kotlin, les dépendances le peuvent.

plugins {
  id 'org.jetbrains.kotlin.android' version '1.8.10'
}

Duplicate class in Kotlin Android Archive du 27/01/2023 le 22/06/2023

Erreurs

Certificats

  • Unable to find valid certification path to requested target
  • Connection refused: connect

C'est évidemment un problème de certificat à cause d'un serveur faisant du DPI (Deep Packet Inspection).

Il faut l'installer dans la machine virtuelle Java. Faire également la même chose pour Android Studio.

Regarder le contenu de la variable JAVA_HOME (C:\jdk-11.0.15+10 par exemple).

Aller dans le dossier C:\jdk-11.0.15+10\lib\security en ligne de commande.

Et lancer la commande ../../bin/keytool -importcert -file /path/to/your/certificate/my-root-ca-cert.cer -keystore cacerts -storepass changeit -noprompt

Avec changeit le mot de passe par défaut et my-root-ca-cert.cer le certificat du serveur DPI.

Il est nécessaire de redémarrer la session car l'application gradle tourne peut-être en arrière plan.

Android Studio - Unable to find valid certification path to requested target Archive du 02/11/2014 le 21/02/2023

prog/gradle.txt · Dernière modification : 2023/08/18 14:32 de root