Cómo pasar las opciones de JVM desde bootRun

99

Estoy desarrollando una aplicación web Spring simple que se comunica con un host remoto y me gustaría probarla localmente detrás del proxy corporativo. Utilizo el complemento de gradle "Spring Boot" y la pregunta es ¿cómo puedo especificar la configuración del proxy para JVM?

He probado varias formas de hacerlo:

  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"

Pero parece que ninguno de ellos funciona: "NoRouteToHostException" incluye código de "red". Además, he agregado un código adicional para depurar los argumentos de inicio de JVM:

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

Y solo se imprimió un argumento: "-Dfile.encoding = UTF-8".

Si configuro la propiedad del sistema en el código:

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

¡Todo funciona bien!

Evgeny
fuente

Respuestas:

107

Respuesta original (usando Gradle 1.12 y Spring Boot 1.0.x):

La bootRuntarea del complemento gradle de Spring Boot extiende la tarea gradle JavaExec. Mira esto .

Eso significa que puede configurar el complemento para usar el proxy agregando:

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

a su archivo de compilación.

Por supuesto, podría usar el en systemPropertieslugar dejvmArgs

Si desea agregar jvmArgs de forma condicional desde la línea de comando, puede hacer lo siguiente:

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

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

Respuesta actualizada:

Después de probar mi solución anterior usando Spring Boot 1.2.6.RELEASE y Gradle 2.7 , observé que no estaba funcionando como mencionan algunos de los comentarios. Sin embargo, se pueden realizar algunos ajustes menores para recuperar el estado de funcionamiento.

El nuevo código es:

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

para argumentos codificados, y

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

    }
}

para argumentos proporcionados desde la línea de comando

geo y
fuente
4
Me gustaría no tener estas opciones "codificadas" en el archivo de compilación. Sería genial tener la posibilidad de especificar la configuración del proxy. Es decir, usando argumentos de línea de comandos.
Evgeny
No funciona: "> No se pudo encontrar la propiedad 'args' en el proyecto raíz".
Evgeny
¿Copiaste correctamente el código? He hecho una actualización. No hay argspropiedad.
geo y
7
Lo intenté hoy y la única forma en que esto funciona es rodear la lista de cadenas entre corchetes, como bootRun {jvmArgs = ["-Dhttp.proxyHost = xxxxxx", "-Dhttp.proxyPort = xxxxxx"]}
Valentino Dell ' Aica 8/10/2014
¿Qué versión de gradle estás usando?
geo y
72
bootRun {
  // support passing -Dsystem.property=value to bootRun task
  systemProperties = System.properties
}

Esto debería pasar todas las opciones de JVM a la aplicación iniciada a través de bootRun.

Marvin Frommhold
fuente
2
Esto es, con mucho, la mejor manera de pasar las opciones de línea de comandos para JVM
anubhava
@Marvin Frommhold, gracias por tu respuesta. El enfoque es increíblemente sencillo. Para novatos como yo, sería útil si agregaras un poco más de detalle. Sugerencias: (1) muestre la llamada de línea de comandos de Gradle con los argumentos; (2) muestre cómo hacer referencia a los argumentos en Spring Boot, por ejemplo, @Value ("$ {propiedad: predeterminado}"); (3) También sería útil una captura de pantalla del diálogo de IntelliJ pasando los parámetros.
Brett
1
Lamentablemente, para mí, solo agregar esto hace que gradle bootRun falle horriblemente con "org.apache.catalina.LifecycleException: un contenedor secundario falló durante el inicio" incluso cuando no pasa ningún parámetro -D
tkruse
Resuelto seleccionando las propiedades que quiero como en una respuesta a stackoverflow.com/questions/23689054
tkruse
7

En el script de compilación de Gradle, defina systemProperties para ejecutar la tarea.

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

y gradle rundebería aceptar este valor.

O defina una propiedad de nivel de proyecto como se menciona en http://forums.gradle.org/gradle/topics/how_can_i_provide_command_line_args_to_application_started_with_gradle_run

suman j
fuente
1
Sí, esta solución funciona. Pero me gustaría no tener este código bajo control de fuente. Creo que la solución "más correcta" es pasar estas opciones directamente en la línea de comandos. ¿Es de alguna manera?
Evgeny
1
El enlace mencionado en la publicación tiene una forma de pasarlos desde la línea de comando
suman j
5

@marvin, gracias por tu publicación fue muy útil.

Compartiendo cómo lo usé:

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

Tengo pruebas de JUnit que quería omitir a menos que se usara una propiedad para incluir dichas pruebas. Usando JUnit Assume para incluir las pruebas condicionalmente:

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

Hacer esto con gradle requería que la propiedad del sistema proporcionada en el momento de ejecutar la compilación de gradle, que se muestra aquí,

gradle build -Ddeep.test.run=true

de hecho pasó a las pruebas.

Espero que esto ayude a otros a probar este enfoque para ejecutar pruebas de forma condicional.

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

El uso de jvmArgs puede causar problemas de inicio de JVM. El uso de args le permite pasar sus argumentos de programa personalizados

Cristian Botiza
fuente
¿Puede mostrarme cómo usar estos argumentos en Application.class o en Bootstrap.class? (Estoy usando Grails 3.xx)
Stefano Scarpanti
2

Parece funcionar:

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

Me metí en un problema similar, bootRun necesitaba algunos parámetros, pero no me gustaría modificar bootRun porque quiero mantener algo de flexibilidad y ceñirme al comportamiento estándar de bootRun. Mi sugerencia es agregar algunas tareas personalizadas (digamos bootRunDev, bootRunProxy) que amplíen bootRun, como se describe en el siguiente fragmento 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'
    }
}

No tengo un entorno para ejercitar el script, pero utilicé este enfoque para pasar el perfil a Spring usando la propiedad spring.profiles.active. Los créditos deben ir a manos de Karol Kaliński

Evelino Bomitali
fuente