如何从bootRun传递JVM选项


99

我正在开发与远程主机通信的简单Spring Web应用程序,我想在公司代理之后在本地对其进行测试。我使用“ Spring Boot” gradle插件,问题是如何为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");

一切正常!

Answers:


107

原始答案(使用Gradle 1.12和Spring Boot 1.0.x):

bootRun春季启动gradle这个插件的任务延长了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.RELEASEGradle 2.7尝试上述解决方案后,我发现它无法正常工作,因为其中有一些评论提到。但是,可以进行一些小的调整以恢复工作状态。

新的代码是:

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

对于硬编码的参数,以及

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

    }
}

用于从命令行提供的参数


4
我不想在构建文件中将此选项“硬编码”。能够指定代理设置非常好。即-使用命令行参数。
伊夫根尼(Evgeny)2014年

不起作用:“>在根项目上找不到属性'args'”。
叶夫根尼(Evgeny)

您是否正确复制了代码?我做了更新。没有args财产。
geoand 2014年

7
我今天尝试过,这项工作的唯一方法是用方括号代替字符串列表,例如bootRun {jvmArgs = [“ -Dhttp.proxyHost = xxxxxx”,“ -Dhttp.proxyPort = xxxxxx”]}
Valentino Dell' Aica

您正在使用哪个版本的gradle?
geoand 2014年

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

这应将所有JVM选项传递给通过以下方式启动的应用 bootRun


2
到目前为止,这是将命令行选项传递给JVM的最佳方法
anubhava 2016-02-17

@Marvin Frommhold,感谢您的回答。该方法非常简单。对于像我这样的菜鸟,如果添加更多细节,将很有帮助。建议:(1)显示带有参数的gradle命令行调用;(2)显示如何在Spring Boot中引用参数,例如@Value(“ $ {property:default}”); (3)传递参数的IntelliJ对话框的屏幕快照也将很有帮助。
布雷特

1
可悲的是,对我来说,仅添加此内容将导致gradle bootRun严重失败,出现“ org.apache.catalina.LifecycleException:启动期间子容器失败”,即使未传递任何-D参数也是如此
tkruse 2016年

通过选择我想要的属性来解决问题,作为对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
是的,此解决方案有效。但是我不想在源代码控制下使用此代码。我相信“最正确的”解决方案是直接在命令行中传递此选项。有什么办法吗?
伊夫根尼(Evgeny)

1
帖子中提到的链接有一种从命令行传递它们的方法
suman j

5

@marvin,感谢您的帖子,它非常有帮助。

分享我的使用方式:

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

我有要跳过的JUnit测试,除非使用属性来包含此类测试。使用JUnit假定有条件地包括测试:

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

使用gradle进行此操作需要在运行gradle构建时提供的系统属性(如下所示),

gradle build -Ddeep.test.run=true

确实通过了测试。

希望这可以帮助其他人尝试这种方法以有条件地运行测试。



2

似乎有效:

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

1

我遇到了类似的问题,bootRun需要一些参数,但是我不想修改bootRun,因为我想保持一些灵活性并坚持标准的bootRun行为。我的建议是添加一些扩展bootRun的自定义任务(例如,bootRunDev,bootRunProxy),如以下代码片段所述

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.profiles.active将配置文件传递给spring。应归功于KarolKaliński

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.