Как передать параметры JVM из bootRun


99

Я разрабатываю простое веб-приложение Spring, которое взаимодействует с удаленным хостом, и я хотел бы протестировать его локально за корпоративным прокси. Я использую плагин Gradle "Spring Boot", и вопрос в том, как я могу указать настройки прокси для JVM?

Я пробовал несколько способов сделать это:

  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"

Но похоже, что ни один из них не работает - «NoRouteToHostException» подбрасывает «сетевой» код. Кроме того, я добавил дополнительный код для отладки аргументов запуска JVM:

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

И был напечатан только один аргумент: «-Dfile.encoding = UTF-8».

Если я установил системное свойство в коде:

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

Все отлично работает!

Ответы:


107

Исходный ответ (с использованием Gradle 1.12 и Spring Boot 1.0.x):

bootRunЗадача Gradle плагин Spring Загрузочный расширяет Gradle задачу JavaExec. Смотрите это .

Это означает, что вы можете настроить плагин для использования прокси, добавив:

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

в ваш файл сборки.

Конечно, вы можете использовать systemPropertiesвместоjvmArgs

Если вы хотите условно добавить jvmArgs из командной строки, вы можете сделать следующее:

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

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

Обновленный ответ:

Опробовав мое решение выше с использованием Spring Boot 1.2.6.RELEASE и Gradle 2.7, я заметил, что оно не работает, как упоминается в некоторых комментариях. Тем не менее, можно внести несколько незначительных изменений, чтобы восстановить рабочее состояние.

Новый код:

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

для жестко запрограммированных аргументов и

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

    }
}

для аргументов, предоставленных из командной строки


4
Я бы не хотел, чтобы эти параметры были жестко запрограммированы в файле сборки. Было бы здорово иметь возможность указать настройки прокси. Т.е. - с использованием аргументов командной строки.
Евгений

Не работает: «> Не удалось найти свойство 'args' в корневом проекте».
Евгений

Вы правильно скопировали код? Я сделал обновление. Нет argsсобственности.
geoand 01

7
Я попробовал сегодня, и единственный способ, которым это работает, - это окружить список строк квадратными скобками, например bootRun {jvmArgs = ["-Dhttp.proxyHost = xxxxxx", "-Dhttp.proxyPort = xxxxxx"]}
Valentino Dell ' Aica 08

Какую версию Gradle вы используете?
geoand

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

Это должно передать все параметры JVM приложению, запущенному через bootRun.


2
Это, безусловно, лучший способ передать параметры командной строки в JVM
анубхава

@Marvin Frommhold, спасибо за ответ. Подход невероятно прост. Для таких новичков, как я, было бы полезно, если бы вы добавили немного больше деталей. Предложения: (1) показать вызов командной строки gradle с аргументами; (2) показать, как ссылаться на аргументы в Spring Boot, например, @Value ("$ {property: default}"); (3) Также будет полезен снимок экрана диалога IntelliJ, в котором передаются параметры.
Бретт

1
К сожалению, для меня простое добавление этого приводит к ужасному сбою gradle bootRun с "org.apache.catalina.LifecycleException: сбой дочернего контейнера во время запуска", даже если не передать какие-либо параметры -D
tkruse

Решено путем выбора свойств, которые я хочу, как в ответе на stackoverflow.com/questions/23689054
tkruse

7

В скрипте сборки gradle определите systemProperties для выполнения задачи.

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

и gradle runдолжен принять это значение.

Или определите свойство уровня проекта, как указано в http://forums.gradle.org/gradle/topics/how_can_i_provide_command_line_args_to_application_started_with_gradle_run


1
Да, это решение работает. Но я бы не хотел, чтобы этот код находился под контролем источника. Я полагаю, что «наиболее правильное» решение - передать эти параметры непосредственно в командной строке. Есть ли способ для этого?
Евгений

1
Ссылка, упомянутая в сообщении, позволяет передавать их из командной строки
suman j 01

5

@marvin, спасибо за ваш пост, это было очень полезно.

Рассказывая, как я его использовал:

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

У меня есть тесты JUnit, которые я хотел бы пропустить, если для включения таких тестов не использовалось свойство. Использование JUnit Assume для условного включения тестов:

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

Для этого с помощью gradle требовалось, чтобы системное свойство предоставлялось во время выполнения сборки gradle, как показано здесь,

gradle build -Ddeep.test.run=true

действительно прошел испытания.

Надеюсь, это поможет другим опробовать этот подход для условного выполнения тестов.


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

Использование jvmArgs может вызвать проблемы с запуском JVM. Использование args позволяет передавать аргументы пользовательской программы


Вы можете показать мне, как использовать эти аргументы в Application.class или Bootstrap.class? (Я использую grails 3.xx)
Стефано Скарпанти


1

У меня возникла аналогичная проблема, bootRun требовал некоторых параметров, но мне не хотелось бы изменять bootRun, поскольку я хочу сохранить некоторую гибкость и придерживаться стандартного поведения bootRun. Я предлагаю добавить несколько пользовательских задач (скажем, bootRunDev, bootRunProxy), расширяющих bootRun, как описано в следующем фрагменте кода.

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

У меня нет среды для выполнения сценария, но я использовал этот подход для передачи профиля в Spring с помощью свойства spring.profiles.active. Кредиты должны перейти к Каролю Калински

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.