Como passar opções JVM de bootRun

99

Estou desenvolvendo um aplicativo da web Spring simples que se comunica com o host remoto e gostaria de testá-lo localmente por meio do proxy corporativo. Eu uso o plugin gradle "Spring Boot" e a questão é como posso especificar as configurações de proxy para JVM?

Eu tentei várias maneiras de fazer isso:

  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"

Mas parece que nenhum deles funciona - "NoRouteToHostException" coloca o código de "rede". Além disso, adicionei algum código extra para depurar argumentos de início JVM:

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

E apenas um argumento foi impresso: "-Dfile.encoding = UTF-8".

Se eu definir a propriedade do sistema no código:

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

Tudo funciona muito bem!

Evgeny
fonte

Respostas:

107

Resposta original (usando Gradle 1.12 e Spring Boot 1.0.x):

A bootRuntarefa do plugin Spring Boot gradle estende a tarefa gradle JavaExec. Veja isso .

Isso significa que você pode configurar o plug-in para usar o proxy adicionando:

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

ao seu arquivo de compilação.

Claro que você pode usar o em systemPropertiesvez dejvmArgs

Se quiser adicionar jvmArgs condicionalmente a partir da linha de comando, você pode fazer o seguinte:

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

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

Resposta atualizada:

Depois de experimentar minha solução acima usando Spring Boot 1.2.6.RELEASE e Gradle 2.7 , observei que não estava funcionando como alguns dos comentários mencionam. No entanto, alguns pequenos ajustes podem ser feitos para recuperar o estado de funcionamento.

O novo código é:

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

para argumentos embutidos em código, e

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

    }
}

para argumentos fornecidos na linha de comando

geoand
fonte
4
Eu gostaria de não ter essas opções "codificadas" no arquivo de compilação. Seria ótimo ter a possibilidade de especificar as configurações de proxy. Ou seja, usando argumentos de linha de comando.
Evgeny
Não funciona: "> Não foi possível encontrar a propriedade 'args' no projeto raiz".
Evgeny
Você copiou corretamente o código? Eu fiz uma atualização. Não há argspropriedade.
geoand 01 de
7
Tentei hoje e a única maneira de funcionar, é superar a lista de string por colchetes, como bootRun {jvmArgs = ["-Dhttp.proxyHost = xxxxxx", "-Dhttp.proxyPort = xxxxxx"]}
Valentino Dell ' Aica
Qual versão do Gradle você está usando?
geoand
72
bootRun {
  // support passing -Dsystem.property=value to bootRun task
  systemProperties = System.properties
}

Isso deve passar todas as opções JVM para o aplicativo iniciado via bootRun.

Marvin Frommhold
fonte
2
Esta é de longe a melhor maneira de passar opções de linha de comando para JVM
anubhava
@Marvin Frommhold, obrigado por sua resposta. A abordagem é incrivelmente direta. Para iniciantes como eu, seria útil adicionar mais detalhes. Sugestões: (1) mostre a chamada de linha de comando do gradle com os argumentos; (2) mostrar como fazer referência aos argumentos no Spring Boot, por exemplo, @Value ("$ {property: default}"); (3) Uma captura de tela da caixa de diálogo do IntelliJ passando os parâmetros também seria útil.
Brett
1
Infelizmente, para mim, apenas adicionar isso faz com que gradle bootRun falhe terrivelmente com "org.apache.catalina.LifecycleException: Um contêiner filho falhou durante a inicialização" mesmo quando não passou nenhum parâmetro -D
tkruse
Resolvido selecionando as propriedades que desejo em uma resposta a stackoverflow.com/questions/23689054
tkruse
7

No script de compilação gradle, defina systemProperties para a tarefa de execução.

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

e gradle rundeve aceitar esse valor.

Ou defina uma propriedade de nível de projeto conforme mencionado em http://forums.gradle.org/gradle/topics/how_can_i_provide_command_line_args_to_application_started_with_gradle_run

suman j
fonte
1
Sim, esta solução funciona. Mas eu gostaria de não ter esse código sob controle de origem. Eu acredito que a solução "mais certa" é passar essas opções diretamente na linha de comando. É algum jeito para isso?
Evgeny
1
O link mencionado na postagem tem uma maneira de passá-los da linha de comando
suman j
5

@marvin, obrigado pelo seu post foi muito útil.

Compartilhando como eu usei:

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

Tenho testes JUnit que gostaria de ignorar, a menos que uma propriedade fosse usada para incluir esses testes. Usando JUnit Assume para incluir os testes condicionalmente:

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

Fazer isso com o gradle exigia que a propriedade do sistema fornecida no momento da execução do gradle build, mostrado aqui,

gradle build -Ddeep.test.run=true

foi de fato passado para os testes.

Espero que isso ajude outras pessoas a experimentar esta abordagem para executar testes condicionalmente.

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

O uso de jvmArgs pode causar problemas de inicialização da JVM. Usar args permite que você passe os argumentos do seu programa personalizado

Cristian botiza
fonte
Você pode me mostrar como usar esses argumentos em Application.class ou em Bootstrap.class? (Estou usando grails 3.xx)
Stefano Scarpanti
2

Parece funcionar:

bootRun {
    systemProperties "property1": "value1", "property2": "value2"
}
Levsa
fonte
1

Eu tive um problema semelhante, o bootRun precisava de alguns parâmetros, mas não gostaria de modificar o bootRun, pois quero manter alguma flexibilidade e manter o comportamento bootRun padrão. Minha sugestão é adicionar algumas tarefas personalizadas (digamos bootRunDev, bootRunProxy) que estende bootRun, conforme descrito no seguinte trecho de código

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

Não tenho um ambiente para exercitar o script, mas usei essa abordagem para passar profile to spring usando a propriedade spring.profiles.active. Os créditos devem ir para Karol Kaliński

Evelino Bomitali
fonte