How to pass JVM options from bootRun - java

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!

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

bootRun {
// support passing -Dsystem.property=value to bootRun task
systemProperties = System.properties
}
This should pass all JVM options to the app started via bootRun.

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

#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.

bootRun {
args = ['myProgramArgument1', 'myProgramArgument2']
}
Using jvmArgs may cause JVM start issues. Using args allows you to pass your custom program arguments

It seems to work:
bootRun {
systemProperties "property1": "value1", "property2": "value2"
}

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

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

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"

Related

Swagger UI - OAuth 2.0 configuration with Micronaut 2.5.1 client ID and client secret in seperate configuration

Trying to do the swagger OAuth configuration in the latest version of Micronaut, as per the micronuat documentation
https://micronaut-projects.github.io/micronaut-openapi/latest/guide/index.html#enableendpoints
swagger-ui.oauth2RedirectUrl
swagger-ui.oauth2.clientId
swagger-ui.oauth2.clientSecret
swagger-ui.oauth2.realm
swagger-ui.oauth2.appName
swagger-ui.oauth2.scopeSeparator
swagger-ui.oauth2.scopes
swagger-ui.oauth2.additionalQueryStringParams
swagger-ui.oauth2.useBasicAuthenticationWithAccessCodeGrant
swagger-ui.oauth2.usePkceWithAuthorizationCodeGrant
When setting any of those properties, Micronaut will generate not only a swagger-ui/index.html file, but also a swagger-ui/oauth2-redirect.html one
I can see it has created the file oauth2-redirect.html with below code
tasks.withType(JavaCompile).all {
options.forkOptions.jvmArgs << '-Dmicronaut.openapi.views.spec=swagger-ui.enabled=true,swagger-ui.theme=flattop,swagger-ui.oauth2RedirectUrl=http://localhost:8080/swagger-ui/oauth2-redirect.html,swagger-ui.oauth2.clientId=myClientId,swagger-ui.oauth2.scopes=openid,swagger-ui.oauth2.usePkceWithAuthorizationCodeGrant=true'
}
For the oauth2.clientId, oauth2RedirectUrl and oauth2.clientSecret these values differs for each environment PROD, TEST, DEV, UAT. By setting the value like above code it is hard to configure for each enviroment. Is there any better way to do this?
In my project it was solved by creating different property files for each env and steering the compilation with parameters
tasks.withType(JavaCompile) {
String openapiPropertyFile = 'openapi/openapi-dev.properties'
if(project.hasProperty("openapiPropertyFile")){
openapiPropertyFile = project.property('openapiPropertyFile')
}
options.fork = true
options.forkOptions.jvmArgs << "-Dmicronaut.openapi.config.file=$openapiPropertyFile"
}
and then you build it like this
$ sh ./gradlew clean jib -PopenapiPropertyFile=openapi/openapi-uat.properties -PimageSuffix=-uat
Although I'd like to know how to do this post compilation because in my case it forces creation of separate docker images where I'd like to have one and mount those properties afterwards.

Intellij fails to set System property in run configuration within Run Configuration

I am passing in System variables using IntelliJ's Run/Debug Configuration tool as follows:
Tasks: clean headlessTest
VM options: -Denv=test -DstoreCode=189 -Ddept=apparel
Arguments: -PdepartmentJourney=department_journey
Environment variables: UI_USERNAME=test;UI_PASSWORD=12345...//These are passed in the pipeline script in CI
This issues the local Gradle command of:
./gradlew clean headlessTest -Denv=test -DstoreCode=189 -Ddept=apparel -PdepartmentJourney=department_journey --no-daemon
And in my CI pipeline:
def setEnvironmentVariables(){
env.UI_USERNAME = getFromSecrets....
env.UI_PASSWORD = getFromSecrets....
}
./gradlew clean headlessTest -Denv=${env.ENVIRONMENT} - DstoreCode=${env.storeCode} -Ddept=${env.dept} -PdepartmentJourney=department_journey --no-daemon
I assume this calls the System.setProperty(String key, String value) method at runtime.
When I debug the code using getProperty only the storeCode value is set, with dept being set to null.
I am using the same getProperty(String key) method for each.
Running from the Terminal and in a pipeline also sees the apparel == null.
Is there an obvious reason?

Spring cloud pass arguments

I have application already configured with spring cloud config , I want to pass jvm agrument to run this application :
bootsrap.yml config
spring.application.name: app
spring.cloud.config:
enabled: ${SPRING_CONFIG_ENABLED:false}
uri: ${SPRING_CONFIG_URI:http://ip:9097/}
I want to pass argument like this but not work :
gradle bootRunLocal -DSPRING_CONFIG_ENABLED=true -DSPRING_CONFIG_URI=http://localhost:9097/
Try to configure bootrun task in build.gradle file as bellow:
bootRun {
systemProperties System.properties
}
I fix problem by adding this code in bootRun:
bootRun {
if (project.hasProperty('args')) {
args project.args.split(',')
}
}
to run task :
gradle bootRun -Pargs=--spring.profiles.active=local,--SPRING_CONFIG_ENABLED=true,--SPRING_CONFIG_URI=http://localhost:9097/

How can I run WSDLToJava from a build.gradle file?

I am successfully able to run the WSDLToJava class from the command line to generate JaxB classes from a WSDL.
java -Xmx128M
-cp "C:\cxf\apache-cxf-3.1.6\lib\cxf-manifest.jar;
C:\java\jdk1.7.0_80\lib\tools.jar"
-Djava.util.logging.config.file="C:\cxf\apache-cxf-3.1.6
\etc\logging.properties"
org.apache.cxf.tools.wsdlto.WSDLToJava
-d generated -frontend jaxws21 -b C:\Project\jaxb-bindings.xml
C:\Project\Service.wsdl
How can I run the same command line from a "build.gradle" file? I am completely new to Gradle.
Thank you in advance for your help.
Pete
While there are some Gradle plugins that implement this, I think it's just as easy to make the call directly via a JavaExec task. Add the following to your build.gradle:
ext.cxfVersion = "3.1.6"
configurations {
wsdl2java
}
dependencies {
wsdl2java("org.apache.cxf:cxf-tools-wsdlto-core:${cxfVersion}")
wsdl2java("org.apache.cxf:cxf-tools-wsdlto-frontend-jaxws:${cxfVersion}")
wsdl2java("org.apache.cxf:cxf-tools-wsdlto-databinding-jaxb:${cxfVersion}")
}
task wsdl2java(type: JavaExec) {
main = "org.apache.cxf.tools.wsdlto.WSDLToJava"
classpath = configurations.wsdl2java
// Uncomment to add JVM arguments if necessary (e.g. for cert-based security)
//jvmArgs = [
// "-Djavax.net.ssl.keyStore=${keystorePath}",
// "-Djavax.net.ssl.keyStorePassword=${keystorePassword}"
//]
args = [
"-d", "src/gen/java",
"example.wsdl"
// Uncomment and remove the previous line to run for multiple WSDL files
//"-wsdlList, "wsdls.txt"
]
}
// If you want to be able to debug the wsdl2java task from Eclipse, add the following
//eclipse {
// classpath {
// plusConfiguration += [configurations.wsdl2java]
// }
//}
Execute the task by running gradlew wsdl2java.

how to pass dynamic input pararm to gradle java exec task?

I have this Gradle task:
task resources_cleaner_bl(type: JavaExec) {
classpath sourceSets.main.runtimeClasspath
systemProperties['cleanTarget'] = 'bl'
main = "com.m.ResourcesCleanerRunner"
}
How can I edit this such that 'bl' will be entered dynamically when I run this gradle task.
You can simply eliminate the configuration systemProperties['cleanTarget'] = 'bl' by setting the system property from the command line using the -D flag, i.e. running gradlew resources_cleaner_bl -DcleanTarget=bl.
You can read more about project and system properties in Gradle user guide here.

Categories