如何从bootRun传递JVM选项

时间:2014-08-01 11:27:30

标签: java gradle spring-boot

我正在开发与远程主机通信的简单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"
  4. 但似乎没有一个能起作用 - " NoRouteToHostException"投入"网络"码。 另外,我添加了一些额外的代码来调试JVM启动参数:

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

    只打印了一个参数:&#34; -Dfile.encoding = UTF-8&#34;。

    如果我在代码中设置系统属性:

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

    一切正常!

8 个答案:

答案 0 :(得分:94)

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

Spring Boot gradle插件的bootRun任务扩展了gradle JavaExec任务。请参阅this

这意味着您可以通过添加以下内容来配置插件以使用代理:

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)

    }
}

用于从命令行提供的参数

答案 1 :(得分:60)

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

这应该将所有JVM选项传递给通过bootRun启动的应用程序。

答案 2 :(得分:6)

在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

答案 3 :(得分:4)

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

分享我如何使用它:

Field,Type,Null,Key,Default
APP_UID,varchar(32),NO,PRI,null
APP_NUMBER,int(11),NO,,null
APP_STATUS,varchar(10),NO,,null
ROW,int(11),NO,PRI,null
GRID_EQUIPMENT_ID,int(11),YES,,null
GRID_EQUIPMENT_ID_LABEL,varchar(64),YES,,null

除非使用属性包含此类测试,否则我要跳过JUnit测试。使用JUnit Assume有条件地包含测试:

SELECT *
  FROM (SELECT * FROM PMT_RPT_OLD
    UNION
  SELECT * FROM PMT_RPT_X
    ) AS A
ORDER BY A.APP_NUMBER

使用gradle执行此操作需要在运行gradle build时提供的系统属性,如此处所示

Field,Type,Null,Key,Default
APP_UID,varchar(32),NO,PRI,null
APP_NUMBER,int(11),NO,,null
APP_STATUS,varchar(10),NO,,null
PROJECT_TITLE,varchar(255),YES,,null
PROJECT_CHARTER_NUMBER,varchar(32),YES,,null
COMPANY_CITY,varchar(32),YES,,null
COMPANY_COUNTRY,varchar(32),YES,,null
COMPANY_NAME,varchar(255),YES,,null
PROJECT_CHARTER_CLIENT_TYPE_LABEL,varchar(32),YES,,null
PROJECT_CHARTER_CLIENT_SECTOR_OTHER,varchar(255),YES,,null
PROJECT_CHARTER_CLIENT_SECTOR_LABEL,varchar(32),YES,,null
PROJECT_CHARTER_START_DATE,varchar(10),YES,,null
REQUEST_DATE,varchar(10),YES,,null
INQUIRY_DIV,varchar(32),YES,,null
CLIENT_CALLBACK_EXPLAIN,varchar(255),YES,,null
CLIENT_CALLBACK_LABEL,varchar(32),YES,,null
CLIENT_SURVEY_LABEL,varchar(32),YES,,null
PROJECT_CLOSEOUT_FEEDBACK_LABEL,varchar(32),YES,,null
PROJECT_CLOSEOUT_SURVEY_COMMENTS,varchar(255),YES,,null
PROJECT_COMPLETION_SIGNOFF_COMMENTS_PM,varchar(255),YES,,null
PROJECT_LOST_SIGNOFF_COMMENTS_PM,varchar(255),YES,,null

确实通过了测试。

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

答案 4 :(得分:2)

似乎有效:

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

答案 5 :(得分:2)

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

使用jvmArgs可能会导致JVM启动问题。使用args可以传递自定义程序参数

答案 6 :(得分: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。 积分应转至Karol Kaliński

答案 7 :(得分:0)

这里值得一提的是,一些使用 Gradle 和 Spring Boot 的系统正在 build.gradle 之外启动 JVM,例如在 Dockerfile 中。

在专门关于 bootRun 的帖子中提及这一点并非毫无意义!我在这里结束是因为这篇特别的文章是一个磁铁,可以在 gradle 下编译/运行的 Spring Boot 应用程序的上下文中搜索有关 jvm 选项的信息。 (我找到的关于添加 java.net.http.httpclient 日志记录的所有建议都说“将其添加到 bootRunjvmArgs”。不过什么也没发生。

因此,如果您碰巧从 Docker 容器运行 gradle 构建的 Spring Boot 应用程序,您需要将 JVM 参数添加到项目的 Dockerfile 中的环境变量中,例如-

...
ENV JAVA_OPTS "${JAVA_OPTS} \
-server \
-Duser.timezone=UTC \
-XX:InitialRAMPercentage=50 \
-XX:MaxRAMPercentage=50 \
-Djavax.net.ssl.trustStorePassword=elvislives \
-Djavax.net.ssl.trustStoreProvider=BCFIPS \
-Djavax.net.ssl.trustStoreType=BCFKS \
-Djdk.internal.httpclient.debug=true \
-Djava.util.logging.manager=org.apache.logging.log4j2.jul.LogManager \
-Djdk.httpclient.HttpClient.log=errors,requests,headers,frames[:control:data:window:all..],content,ssl,trace,channel \
"
...

ENTRYPOINT java ${JAVA_OPTS} -cp app:app/lib/* com.mygreatcompany.theapp