Як передати параметри 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власності.
геоі

7
Я спробував сьогодні, і єдиний спосіб, яким це працює, - це обернути список рядків квадратними дужками, наприклад bootRun {jvmArgs = ["-Dhttp.proxyHost = xxxxxx", "-Dhttp.proxyPort = xxxxxx"]}
Валентино Делл ' Aica

Яку версію gradle ви використовуєте?
геоі

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

Це має передати всі параметри JVM додатку, запущеному через bootRun.


2
Це, безумовно, найкращий спосіб передати параметри командного рядка JVM
anubhava

@Marvin Frommhold, дякую за вашу відповідь. Підхід неймовірно прямий. Таким людям, як я, було б корисно, якщо ви додасте трохи детальніше. Пропозиції: (1) показати виклик командного рядка gradle з аргументами; (2) показати, як посилатися на аргументи у Spring Boot, наприклад, @Value ("$ {властивість: за замовчуванням}"); (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

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 build, показана тут,

gradle build -Ddeep.test.run=true

справді було передано на випробування.

Сподіваюся, це допомагає іншим випробувати цей підхід для запуску тестів умовно.


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

Використання jvmArgs може спричинити проблеми із запуском JVM. Використання аргументів дозволяє передавати власні аргументи програми


Чи можете ви показати мені, як використовувати ці аргументи у Application.class або в Bootstrap.class? (Я використовую граалі 3.xx)
Стефано Скарпанті

2

Здається, це працює:

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

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.