How to pass JVM options from bootRun
JavaGradleSpring BootJava Problem Overview
I'm developing simple Spring web application that communicates with remote host and I would like to test it locally behind corporate proxy. I use "Spring Boot" gradle plugin and the question is how can I specify proxy settings for JVM?
I have try several ways to do it:
gradle -Dhttp.proxyHost=X.X.X.X -Dhttp.proxyPort=8080 bootRun
export JAVA_OPTS="-Dhttp.proxyHost=X.X.X.X -Dhttp.proxyPort=8080"
export GRADLE_OPTS="-Dhttp.proxyHost=X.X.X.X -Dhttp.proxyPort=8080"
But it seems like none of them work - "NoRouteToHostException" throws in "network" code. Also, I have added some extra code to debug JVM start arguments:
RuntimeMXBean runtimeMxBean = ManagementFactory.getRuntimeMXBean();
List<String> arguments = runtimeMxBean.getInputArguments();
for (String arg: arguments) System.out.println(arg);
And only one argument was printed: "-Dfile.encoding=UTF-8".
If I set system property in code:
System.setProperty("http.proxyHost", "X.X.X.X");
System.setProperty("http.proxyPort", "8080");
Everything works just fine!
Java Solutions
Solution 1 - Java
Original Answer (using Gradle 1.12 and Spring Boot 1.0.x):
The bootRun
task of the Spring Boot gradle plugin extends the gradle JavaExec task. See this.
That means that you can configure the plugin to use the proxy by adding:
bootRun {
jvmArgs = "-Dhttp.proxyHost=xxxxxx", "-Dhttp.proxyPort=xxxxxx"
}
to your build file.
Of course you could use the systemProperties
instead of jvmArgs
If you want to conditionally add jvmArgs from the command line you can do the following:
bootRun {
if ( project.hasProperty('jvmArgs') ) {
jvmArgs project.jvmArgs.split('\\s+')
}
}
gradle bootRun -PjvmArgs="-Dwhatever1=value1 -Dwhatever2=value2"
Updated Answer:
After trying out my solution above using Spring Boot 1.2.6.RELEASE and Gradle 2.7 I observed that it was not working as some of the comments mention. However, a few minor tweaks can be made to recover the working state.
The new code is:
bootRun {
jvmArgs = ["-Dhttp.proxyHost=xxxxxx", "-Dhttp.proxyPort=xxxxxx"]
}
for hard-coded arguments, and
bootRun {
if ( project.hasProperty('jvmArgs') ) {
jvmArgs = (project.jvmArgs.split("\\s+") as List)
}
}
for arguments provided from the command line
Solution 2 - Java
bootRun {
// support passing -Dsystem.property=value to bootRun task
systemProperties = System.properties
}
This should pass all JVM options to the app started via bootRun
.
Solution 3 - Java
In gradle build script, define systemProperties for run task.
//to provide the properties while running the application using spring-boot's run task
run {
systemProperties['property name'] = 'value'
}
and gradle run
should accept this value.
Or define a project level property as mentioned in http://forums.gradle.org/gradle/topics/how_can_i_provide_command_line_args_to_application_started_with_gradle_run
Solution 4 - Java
@marvin, thanks for your post it was very helpful.
Sharing how I used it:
test {
// support passing -Dsystem.property=value to bootRun task
systemProperties = System.properties
}
I have JUnit tests that I wanted to skip unless a property was used to include such tests. Using JUnit Assume for including the tests conditionally:
//first line of test
assumeThat(Boolean.parseBoolean(System.getProperty("deep.test.run","false"),true)
Doing this with gradle required that the system property provided at the time of running gradle build, shown here,
gradle build -Ddeep.test.run=true
was indeed passed through to the tests.
Hope this helps others trying out this approach for running tests conditionally.
Solution 5 - Java
bootRun {
args = ['myProgramArgument1', 'myProgramArgument2']
}
Using jvmArgs may cause JVM start issues. Using args allows you to pass your custom program arguments
Solution 6 - Java
It seems to work:
bootRun {
systemProperties "property1": "value1", "property2": "value2"
}
Solution 7 - Java
I got into a similar problem, bootRun needed some parameters but I wouldn't feel like modifying bootRun as I want to keep some flexibility and stick to standard bootRun behaviour. My suggestion is to add some custom tasks (let's say bootRunDev, bootRunProxy) that extends bootRun, as described in the following code snippet
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'
}
}
I don't have an environment to exercise the script but I used this approach to pass profile to spring using the property spring.profiles.active. Credits should go to Karol Kaliński
Solution 8 - Java
It's worth mentioning, here, that some systems that use Gradle and Spring Boot are starting JVM outside of build.gradle
, e.g. in a Dockerfile.
It's not pointless to mention this on a thread specifically about bootRun
! I wound up here because this particular post is a magnet for searches about jvm options in the context of a Spring Boot app compiled / run under gradle. (All the advice I found for adding java.net.http.httpclient logging said "add it to bootRun
's jvmArgs
". Nothing happened, though.
So, if you happen to run your gradle-built Spring Boot app from a Docker container, you'll want to add your JVM params to an env var in your project's Dockerfile, like so, e.g.-
...
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
Solution 9 - Java
For development as Docker Container add to run_script.sh as JAVA_OPTS
JAVA_OPTS="-XX:+UseG1GC -Xms512m -Xmx2048m --add-opens java.base/java.util=ALL-UNNAMED -Dspring.profiles.active=$PROFILE,discovery"