Tâche Gradle - transmettre des arguments à l'application Java

127

J'ai une application Java qui s'exécute avec une tâche gradle personnalisée et l'application nécessite certains arguments lorsqu'elle est appelée. Ceux-ci sont:

programName ( string | -f filename | -d key | -h)
Options:
    string         Message to be used.
    -d key         Use default messages, key must be s[hort], m[edium] or l[ong].
    -f filename    Use specified file as input.
    -h             Help dialog.

La tâche Gradle ressemble à:

task run (type: JavaExec){
    description = "Secure algorythm testing"
    main = 'main.Test'
    classpath = sourceSets.main.runtimeClasspath
}

J'ai essayé de courir gradle run -het cela ne fonctionne pas.

RecuencoJones
la source
Les réponses répondaient-elles à vos besoins? Si tel est le cas, vous devez en marquer une comme solution.
Francisco J.Lopez-Pellicer
1
Pas vraiment ... un ami et moi avons découvert un moyen de le faire mais nous ne l'avons pas encore clair pour publier une solution, les deux solutions proposées ont été essayées, nous avons compris ce qu'il fallait faire, mais nous ne l'avons pas fait '' Ça a vraiment l'air de marcher ...
RecuencoJones
@ 6uitar6reat6od Comment l'avez-vous résolu à la fin? Aussi quelle version de gradle?
xlm

Réponses:

80

Depuis Gradle 4.9, les arguments de la ligne de commande peuvent être passés avec --args. Par exemple, si vous souhaitez lancer l'application avec des arguments de ligne de commande foo --bar, vous pouvez utiliser

gradle run --args = 'foo --bar'

Voir aussi Gradle Application Plugin

Comment mettre à niveau le wrapper Gradle

AMing
la source
1
Est-ce que le 'attendu ou une faute de frappe? Tous les arguments doivent-ils être passés sous forme de chaîne délimitée par des guillemets simples?
RecuencoJones
@RecuencoJones Fixé par docs.gradle.org/current/userguide/…
Drew Stephens
1
gradle run --args = 'foo --bar'
Jim Flood
3
'foo --bar'est déroutant, pourquoi ne pas simplement utiliser 'foo bar'.
Eric Wang
4
@EricWang Ce sont des arguments de ligne de commande arbitraires dont un programme peut avoir besoin. C'est bien de montrer que gradle prend en charge tous les types d'arguments, puisque la chaîne brute est transmise à l'application construite.
Joffrey
100

Gradle 4.9+

gradle run --args='arg1 arg2'

Cela suppose que vous êtes build.gradleconfiguré avec le plugin Application . Votre build.gradledevrait ressembler à ceci:

plugins {
  // Implicitly applies Java plugin
  id: 'application'
}

application {
  // URI of your main class/application's entry point (required)
  mainClassName = 'org.gradle.sample.Main'
}

Pré-Gradle 4.9

Incluez les éléments suivants dans votre build.gradle:

run {
    if (project.hasProperty("appArgs")) {
        args Eval.me(appArgs)
    }
}

Puis pour courir: gradle run -PappArgs="['arg1', 'args2']"

xlm
la source
7
Cette réponse n'était pas seulement utile, c'était la plus simple.
Jossie Calderon
Mise à jour pour votre mise à jour: gradle run --args 'arg1 arg2'n'a pas fonctionné pour moi. Je devais faire:gradle run --args='arg1 arg2'
cmyers
@cmyers merci d'avoir attrapé ça! J'ai mis à jour ma mise à jour
xlm
28

Désolé d'avoir répondu si tard.

J'ai trouvé une réponse similaire à celle de @xlm:

task run (type: JavaExec, dependsOn: classes){
    if(project.hasProperty('myargs')){
        args(myargs.split(','))
    }
    description = "Secure algorythm testing"
    main = "main.Test"
    classpath = sourceSets.main.runtimeClasspath
}

Et invoquez comme:

gradle run -Pmyargs=-d,s
RecuencoJones
la source
28

Si vous souhaitez utiliser le même ensemble d'arguments tout le temps, voici tout ce dont vous avez besoin.

run {
    args = ["--myarg1", "--myarg2"]
}
Claudio Fahey
la source
2
Ok, pour les débutants absolus comme moi: afin de pouvoir définir la tâche d'exécution, votre build.gradle doit contenir les deux lignes suivantes: apply plugin: 'application' mainClassName = "<nom de classe complet y compris le chemin du package>" Sinon, vous ne pouvez pas définir la méthode run dans le buuild.gradle
mk ..
1
J'utilise le id 'application'plugin et c'était la réponse dont j'avais besoin (ça marche).
Big Rich
6

Vous pouvez trouver la solution dans Problèmes de transmission des propriétés système et des paramètres lors de l'exécution de la classe Java via Gradle . Les deux impliquent l'utilisation de la argspropriété

Vous devriez également lire la différence entre passer avec -Dou avec -Pqui est expliquée dans la documentation Gradle

Francisco J. Lopez-Pellicer
la source
J'ai vu ça aussi. Toujours à la recherche. Toutes ces méthodes semblent vouloir modifier / masser les propriétés actuelles et les transmettre. La ligne de commande et les propriétés Java pour exécuter une application ou un service s'apparentent au paramètre «Contexte» ou «Configuration». Il serait préférable d'avoir un plug-in qui fait des choses comme "exécuter les paramètres" en tant que profils côte à côte ou autre.
sera
5

Bien sûr, les réponses font avant tout le travail, mais j'aimerais quand même utiliser quelque chose comme

gradle run path1 path2

Eh bien, cela ne peut pas être fait, mais si nous pouvons:

gralde run --- path1 path2

Si vous pensez que c'est plus élégant, alors vous pouvez le faire, l'astuce est de traiter la ligne de commande et de la modifier avant que gradle ne le fasse, cela peut être fait en utilisant des scripts d'initialisation

Le script init ci-dessous:

  1. Traitez la ligne de commande et supprimez --- et tous les autres arguments suivant '---'
  2. Ajoutez la propriété 'appArgs' à gradle.ext

Ainsi, dans votre tâche d'exécution (ou JavaExec, Exec), vous pouvez:

if (project.gradle.hasProperty("appArgs")) {
                List<String> appArgs = project.gradle.appArgs;

                args appArgs

 }

Le script init est:

import org.gradle.api.invocation.Gradle

Gradle aGradle = gradle

StartParameter startParameter = aGradle.startParameter

List tasks = startParameter.getTaskRequests();

List<String> appArgs = new ArrayList<>()

tasks.forEach {
   List<String> args = it.getArgs();


   Iterator<String> argsI = args.iterator();

   while (argsI.hasNext()) {

      String arg = argsI.next();

      // remove '---' and all that follow
      if (arg == "---") {
         argsI.remove();

         while (argsI.hasNext()) {

            arg = argsI.next();

            // and add it to appArgs
            appArgs.add(arg);

            argsI.remove();

        }
    }
}

}


   aGradle.ext.appArgs = appArgs

Limites:

  1. J'ai été obligé d'utiliser «---» et non «-»
  2. Vous devez ajouter un script d'initialisation global

Si vous n'aimez pas le script d'initialisation global, vous pouvez le spécifier en ligne de commande

gradle -I init.gradle run --- f:/temp/x.xml

Ou mieux ajouter un alias à votre shell:

gradleapp run --- f:/temp/x.xml
Boaz Nahum
la source
2
Cela fonctionne très bien ... si aucun de mes arguments ne commence par un tiret. Cela le rend inutile pour les analyseurs de ligne de commande courants : (. Dès que cela se produit, gradle semble traiter cet argument comme un argument pour graduer (je ne pense pas que cela argsI.remove()ait l'effet souhaité). Suggestions?
Krease
3

Vous devez les transmettre argsà la tâche en utilisant les propriétés du projet, quelque chose comme:

args = [project.property('h')]

ajouté à votre définition de tâche (voir la documentation dsl )

Ensuite, vous pouvez l'exécuter comme:

gradle -Ph run
cjstehno
la source