Come passare le opzioni JVM da bootRun


99

Sto sviluppando una semplice applicazione web Spring che comunica con l'host remoto e vorrei testarla localmente dietro proxy aziendale. Uso il plugin gradle "Spring Boot" e la domanda è: come posso specificare le impostazioni proxy per JVM?

Ho provato diversi modi per farlo:

  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"

Ma sembra che nessuno di loro funzioni - "NoRouteToHostException" genera il codice di "rete". Inoltre, ho aggiunto del codice extra per eseguire il debug degli argomenti di avvio di JVM:

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

Ed è stato stampato un solo argomento: "-Dfile.encoding = UTF-8".

Se imposto la proprietà di sistema nel codice:

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

Funziona tutto bene!

Risposte:


107

Risposta originale (utilizzando Gradle 1.12 e Spring Boot 1.0.x):

L' bootRunattività del plug-in gradle Spring Boot estende l'attività gradle JavaExec. Vedi questo .

Ciò significa che puoi configurare il plug-in per utilizzare il proxy aggiungendo:

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

al tuo file build.

Ovviamente potresti usare il systemPropertiesinvece dijvmArgs

Se vuoi aggiungere in modo condizionale jvmArgs dalla riga di comando puoi fare quanto segue:

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

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

Risposta aggiornata:

Dopo aver provato la mia soluzione sopra usando Spring Boot 1.2.6.RELEASE e Gradle 2.7 ho notato che non funzionava come menzionato da alcuni commenti. Tuttavia, è possibile apportare alcune piccole modifiche per ripristinare lo stato di funzionamento.

Il nuovo codice è:

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

per argomenti hardcoded e

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

    }
}

per gli argomenti forniti dalla riga di comando


4
Vorrei non avere queste opzioni "hardcoded" nel file di build. Sarebbe bello avere la possibilità di specificare le impostazioni del proxy. Ad esempio, utilizzando gli argomenti della riga di comando.
Evgeny

Non funziona: "> Impossibile trovare la proprietà 'args' nel progetto radice".
Evgeny

Hai copiato correttamente il codice? Ho effettuato un aggiornamento. Nessuna argsproprietà.
geoand

7
Ho provato oggi e l'unico modo in cui funziona è racchiudere l'elenco di stringhe tra parentesi quadre, come bootRun {jvmArgs = ["-Dhttp.proxyHost = xxxxxx", "-Dhttp.proxyPort = xxxxxx"]}
Valentino Dell ' Aica

Quale versione di gradle stai usando?
geoand

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

Questo dovrebbe trasferire tutte le opzioni JVM all'app avviata tramite bootRun.


2
Questo è di gran lunga il modo migliore per passare le opzioni della riga di comando a JVM
anubhava

@Marvin Frommhold, grazie per la tua risposta. L'approccio è incredibilmente semplice. Per i niubbi come me, sarebbe utile aggiungere qualche dettaglio in più. Suggerimenti: (1) mostra la chiamata alla riga di comando gradle con gli argomenti; (2) mostra come fare riferimento agli argomenti in Spring Boot, ad esempio, @Value ("$ {property: default}"); (3) Sarebbe utile anche uno screenshot della finestra di dialogo IntelliJ che passa i parametri.
Brett

1
Purtroppo, per me, la semplice aggiunta di questo fa sì che gradle bootRun fallisca orribilmente con "org.apache.catalina.LifecycleException: un contenitore figlio non riuscito durante l'avvio" anche quando non si passa alcun parametro -D
tkruse

Risolto da cherry-picking le proprietà che voglio come in una risposta ad stackoverflow.com/questions/23689054
tkruse

7

Nello script di build gradle, definire le proprietà di sistema per l'attività di esecuzione.

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

e gradle rundovrebbe accettare questo valore.

Oppure definisci una proprietà a livello di progetto come indicato in http://forums.gradle.org/gradle/topics/how_can_i_provide_command_line_args_to_application_started_with_gradle_run


1
Sì, questa soluzione funziona. Ma vorrei non avere questo codice sotto il controllo del codice sorgente. Credo che la soluzione "più giusta" sia passare queste opzioni direttamente nella riga di comando. È in qualche modo per questo?
Evgeny

1
Il collegamento menzionato nel post ha un modo per passarli dalla riga di comando
suman j

5

@marvin, grazie per il tuo post è stato molto utile.

Condividendo come l'ho usato:

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

Ho dei test JUnit che volevo saltare a meno che una proprietà non fosse utilizzata per includere tali test. Utilizzo di JUnit Assume per includere i test in modo condizionale:

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

Fare questo con gradle richiedeva che la proprietà di sistema fornita al momento dell'esecuzione di gradle build, mostrata qui,

gradle build -Ddeep.test.run=true

è stato infatti passato alle prove.

Spero che questo aiuti gli altri a provare questo approccio per eseguire i test in modo condizionale.


3
bootRun {
  args = ['myProgramArgument1', 'myProgramArgument2']
}

L'uso di jvmArgs può causare problemi di avvio di JVM. L'uso di args ti consente di passare gli argomenti del programma personalizzato


Potete mostrarmi come utilizzare questi argomenti in Application.class o in Bootstrap.class? (Sto usando grails 3.xx)
Stefano Scarpanti

2

Sembra funzionare:

bootRun {
    systemProperties "property1": "value1", "property2": "value2"
}

1

Mi sono imbattuto in un problema simile, bootRun necessitava di alcuni parametri ma non avrei voglia di modificare bootRun perché voglio mantenere una certa flessibilità e attenermi al comportamento standard di bootRun. Il mio suggerimento è di aggiungere alcune attività personalizzate (diciamo bootRunDev, bootRunProxy) che estendono bootRun, come descritto nel seguente frammento di codice

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

Non ho un ambiente per esercitare lo script, ma ho utilizzato questo approccio per passare il profilo alla molla utilizzando la proprietà spring.profiles.active. I crediti dovrebbero andare a Karol Kaliński

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.