Comment transmettre les options JVM à partir de bootRun

99

Je développe une application Web Spring simple qui communique avec un hôte distant et j'aimerais la tester localement derrière un proxy d'entreprise. J'utilise le plugin gradle "Spring Boot" et la question est de savoir comment spécifier les paramètres de proxy pour JVM?

J'ai essayé plusieurs façons de le faire:

  1. gradle -Dhttp.proxyHost=X.X.X.X -Dhttp.proxyPort=8080 bootRun
  2. export JAVA_OPTS="-Dhttp.proxyHost=X.X.X.X -Dhttp.proxyPort=8080"
  3. export GRADLE_OPTS="-Dhttp.proxyHost=X.X.X.X -Dhttp.proxyPort=8080"

Mais il semble qu'aucun d'eux ne fonctionne - "NoRouteToHostException" jette du code "réseau". De plus, j'ai ajouté du code supplémentaire pour déboguer les arguments de démarrage JVM:

    RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
    List<String> arguments = runtimeMxBean.getInputArguments();
    for (String arg: arguments) System.out.println(arg);

Et un seul argument a été affiché: "-Dfile.encoding = UTF-8".

Si je définis la propriété système dans le code:

    System.setProperty("http.proxyHost", "X.X.X.X");
    System.setProperty("http.proxyPort", "8080");

Tout fonctionne très bien!

Evgeny
la source

Réponses:

107

Réponse originale (en utilisant Gradle 1.12 et Spring Boot 1.0.x):

La bootRuntâche du plugin Gradle Spring Boot étend la tâche Gradle JavaExec. Regarde ça .

Cela signifie que vous pouvez configurer le plugin pour utiliser le proxy en ajoutant:

bootRun {
   jvmArgs = "-Dhttp.proxyHost=xxxxxx", "-Dhttp.proxyPort=xxxxxx"
}

à votre fichier de construction.

Bien sûr, vous pouvez utiliser le à la systemPropertiesplace dejvmArgs

Si vous souhaitez ajouter conditionnellement jvmArgs à partir de la ligne de commande, vous pouvez effectuer les opérations suivantes:

bootRun {
    if ( project.hasProperty('jvmArgs') ) {
        jvmArgs project.jvmArgs.split('\\s+')
    }
}

gradle bootRun -PjvmArgs="-Dwhatever1=value1 -Dwhatever2=value2"

Réponse mise à jour:

Après avoir essayé ma solution ci-dessus en utilisant Spring Boot 1.2.6.RELEASE et Gradle 2.7, j'ai remarqué que cela ne fonctionnait pas, comme le mentionnent certains commentaires. Cependant, quelques modifications mineures peuvent être apportées pour récupérer l'état de fonctionnement.

Le nouveau code est:

bootRun {
   jvmArgs = ["-Dhttp.proxyHost=xxxxxx", "-Dhttp.proxyPort=xxxxxx"]
}

pour les arguments codés en dur, et

bootRun {
    if ( project.hasProperty('jvmArgs') ) {
        jvmArgs = (project.jvmArgs.split("\\s+") as List)

    }
}

pour les arguments fournis depuis la ligne de commande

geoand
la source
4
Je voudrais ne pas avoir ces options "codées en dur" dans le fichier de construction. Ce serait formidable d'avoir la possibilité de spécifier les paramètres du proxy. Ie - en utilisant des arguments de ligne de commande.
Evgeny
Ne fonctionne pas: "> Impossible de trouver la propriété 'args' sur le projet racine".
Evgeny
Avez-vous correctement copié le code? J'ai fait une mise à jour. Il n'y a pas de argspropriété.
geo et
7
J'ai essayé aujourd'hui et la seule façon de faire ce travail, est de délimiter la liste de chaînes par des crochets, comme bootRun {jvmArgs = ["-Dhttp.proxyHost = xxxxxx", "-Dhttp.proxyPort = xxxxxx"]}
Valentino Dell ' Aica
Quelle version de gradle utilisez-vous?
geoand
72
bootRun {
  // support passing -Dsystem.property=value to bootRun task
  systemProperties = System.properties
}

Cela devrait transmettre toutes les options JVM à l'application démarrée via bootRun.

Marvin Frommhold
la source
2
C'est de loin le meilleur moyen de passer des options de ligne de commande à JVM
anubhava
@Marvin Frommhold, merci pour votre réponse. L'approche est incroyablement simple. Pour les noobs comme moi, il serait utile que vous ajoutiez un peu plus de détails. Suggestions: (1) afficher l'appel de ligne de commande gradle avec les arguments; (2) montrer comment référencer les arguments dans Spring Boot, par exemple @Value ("$ {property: default}"); (3) Une capture d'écran de la boîte de dialogue IntelliJ passant les paramètres serait également utile.
Brett
1
Malheureusement, pour moi, le simple fait d'ajouter cela provoque un échec horrible du bootRun de gradle avec "org.apache.catalina.LifecycleException: Un conteneur enfant a échoué au démarrage" même en ne passant aucun paramètre -D
tkruse
Résolu en sélectionnant les propriétés que je veux comme dans une réponse à stackoverflow.com/questions/23689054
tkruse
7

Dans le script de construction gradle, définissez systemProperties pour la tâche d'exécution.

//to provide the properties while running the application using spring-boot's run task
    run {
        systemProperties['property name'] = 'value'
    }

et gradle rundevrait accepter cette valeur.

Ou définissez une propriété au niveau du projet comme mentionné dans http://forums.gradle.org/gradle/topics/how_can_i_provide_command_line_args_to_application_started_with_gradle_run

suman j
la source
1
Oui, cette solution fonctionne. Mais j'aimerais ne pas avoir ce code sous contrôle de code source. Je crois que la solution "la plus juste" est de passer ces options directement en ligne de commande. Est-ce possible?
Evgeny
1
Le lien mentionné dans l'article permet de les transmettre à partir de la ligne de commande
suman j
5

@marvin, merci pour votre message, il a été très utile.

Partageant comment je l'ai utilisé:

test {
  // support passing -Dsystem.property=value to bootRun task
  systemProperties = System.properties
}

J'ai des tests JUnit que je voulais ignorer à moins qu'une propriété ne soit utilisée pour inclure de tels tests. Utilisation de JUnit Assume pour inclure les tests de manière conditionnelle:

//first line of test
assumeThat(Boolean.parseBoolean(System.getProperty("deep.test.run","false"),true)

Pour ce faire avec gradle, il fallait que la propriété système fournie au moment de l'exécution de la génération de gradle, illustrée ici,

gradle build -Ddeep.test.run=true

a bien été passé aux tests.

J'espère que cela aidera les autres à essayer cette approche pour exécuter des tests de manière conditionnelle.

Rishik Dhar
la source
3
bootRun {
  args = ['myProgramArgument1', 'myProgramArgument2']
}

L'utilisation de jvmArgs peut entraîner des problèmes de démarrage de la JVM. L'utilisation d'arguments vous permet de transmettre vos arguments de programme personnalisés

Cristian Botiza
la source
Pouvez-vous me montrer comment utiliser ces arguments dans Application.class ou Bootstrap.class? (J'utilise grails 3.xx)
Stefano Scarpanti
2

Cela semble fonctionner:

bootRun {
    systemProperties "property1": "value1", "property2": "value2"
}
levsa
la source
1

J'ai eu un problème similaire, bootRun avait besoin de certains paramètres mais je n'aurais pas envie de modifier bootRun car je veux garder une certaine flexibilité et m'en tenir au comportement standard de bootRun. Ma suggestion est d'ajouter des tâches personnalisées (disons bootRunDev, bootRunProxy) qui étend bootRun, comme décrit dans l'extrait de code suivant

task bootRunPxy(type: org.springframework.boot.gradle.run.BootRunTask, dependsOn: 'build') {
    group = 'Application'
    doFirst() {
        main = project.mainClassName
        classpath = sourceSets.main.runtimeClasspath
        systemProperty 'http.proxyHost', 'xxxxx'
        systemProperty 'http.proxyPort', 'yyyyy'
    }
}

Je n'ai pas d'environnement pour exercer le script mais j'ai utilisé cette approche pour passer le profil au ressort en utilisant la propriété spring.profiles.active. Les crédits doivent aller à Karol Kaliński

Evelino Bomitali
la source