Passing jvm arguments to Gradle test task - java

I would like to pass JVM parameters to my Gradle test task. I use the parameters in a Cucumber feature file: ${app.url}. In the build.gradle file, I put those lines:
test {
testLogging.showStandardStreams = true
systemProperties System.getProperties()
}
When I execute gradle test -Dapp.url=http://....., I don't see the parameter was passed to the application. I also tried the below, but the result is the same:
test {
testLogging.showStandardStreams = true
systemProperty "app.url", System.getProperty("app.url")
}
When I use Maven and pass the same parameters as Jvm arguments, it works fine. Now I would like to switch to the Gradle, but I am stuck with passing parameters.

gradle is having -P or --project-prop option. Try this one and see.
-P, --project-prop Set project property for the build script

Related

Gradle systemProperty in custom task not setting Spring Profile

I'm trying to selectively deactive tests if there is a spring profile called "unit", which is working:
#DisabledIfEnvironmentVariable(named = "SPRING_PROFILES_ACTIVE", matches = "unit")
If I run SPRING_PROFILES_ACTIVE=unit ./gradlew clean test this works fine. The issue I'm having is that I don't want to have to write all that out, and instead I want a custom gradle task, also called "unit". It currently looks like this:
task unit(type: Test) {
useJUnitPlatform()
systemProperty "SPRING_PROFILES_ACTIVE", "unit"
}
This runs all tests, even if they are supposed to be disabled. I tried useJUnitPlatform { sysProp... }, I tried adding options { sysProp... }, I tried using doFirst, I tried switching "SPRING_PROFILES_ACTIVE" to "spring.profiles.active" in both the build.gradle and in the annotation, I tried systemProperties "SPRING_PROFILES_ACTIVE": "unit" but that doesn't work.
I found lots of StackOverflow questions where people just put systemProperties into the default test task, but I couldn't find anything with a custom task.
What do I need to call where to get the task to pass a spring profile system property?
#DisabledIfEnvironmentVariable annotation requires environment variable to be set. Try to set environment variable instead of system property in Your task:
task unit(type: Test) {
useJUnitPlatform()
environment "SPRING_PROFILES_ACTIVE", "unit"
}

How to pass environment variables to the gradle wrapper build using only command line?

I am trying to pass env variables locally with strictly a command line command. At deploy, these variables get passed into the docker container, but when running locally, they are not present and need to be set locally.
They need to be removed before committing though because they are access keys so i dont want them exposed in the repo. That is why running tests locally (without an IDE) would require a command that passes these variables.
I have already tried this:
./gradlew clean build -Dspring.profiles.active=local -DMY_ENV_VAR1=xxxxxx -DMY_ENV_VAR2=xxxxxx
and it doesnt seem to be working. i cant find the docs for the build command's options, but i thought this was how you pass them. what am i doing wrong here? or is it not possible?
Another reason for environment variables not working is the gradle daemon.
Run this to kill any old daemons:
./gradlew --stop
Then try again. Lost far too much time on that.
For passing env variables
MY_ENV_VAR1=xxxxxx MY_ENV_VAR2=xxxxxx ./gradlew bootRun
For arguments/overriding properties values
./gradlew bootRun --args='--spring.profiles.active=local --db.url=something --anotherprop=fafdf'
For both passing env variable and overriding properties values.
MY_ENV_VAR1=xxxxxx MY_ENV_VAR2=xxxxxx ./gradlew bootRun --args='--spring.profiles.active=local --db.url=something --anotherprop=fafdf'
This related post worked for me: https://stackoverflow.com/a/57890208/1441210
The solution was to use the --args option of gradlew to get the environment variable to be passed to the spring boot app:
./gradlew bootRun --args='--spring.profiles.active=local'
I just put the env variable setting before calling command as the way a regular Unix shell does. Work with my Zsh.
MY_ENV_VAR1=xxxxxx MY_ENV_VAR2=xxxxxx gradlew clean test
If you want to pass values to the JVM that runs the gradle you can use the '-D' switch. I suppose you have to pass values to the gradle build file from the command line. If that's the case there are two options for that:
You can use the -P switch and specify the value there. For example:
gradle -PmySecretKey="This key is so secret" yourTask
If you are using linux or variants you can set environment variable as follows:
export ORG_GRADLE_PROJECT_mySecretKey="This key is so secret"
After this you can access the value in the gradle build file as follows (I am using kotlin dsl)
val mySecretKey: String by project
println(mySecretKey)
To answer your question, as far as I know, there's no way to set environment variables manually through Gradle. What your doing right now is just passing in regular CLI arguments/parameters to your tests.
when running locally, they are not present and need to be set locally.
running tests locally (without an IDE) would require a command that passes these variables.
I see from your snippet, you are using Spring, likely Spring Boot. And since you're already specifying the profile as local, why not define these variables in a profile specific configuration? Example:
application.yml -- base configuration
my-config-value: ${MY_ENV_VAR}
application-local.yml -- local profile configuration that overrides the base
my-config-value: some-dummy-value-for-local-development

Execute Groovy script from Gradle without compiling Java

I have a Java project with Gradle.
Also I use Groovy to generate some class that will be used in Java code. Gradle executes script in separate task below:
task generateClass(type: JavaExec) {
classpath = sourceSets.main.runtimeClasspath
main = 'generatorScript'
}
If I run this task, it first starts Java compilation, and only after that executes script. So if compilation failed, my generator script will not be executed. As it was mentioned, script generates one class, which my Java code is actually depends on, so, if not generated, Java will not be compiled. Vicious circle.
Script itself does not depend on some Java classes and is placed in separate sources directory:
/src
/main
/java
/...(java classes)
/groovy
generatorScript.groovy
It seems like nothing interferes me to execute script separately and independently from Java compilation.
How can I achieve that?
The problem is that you have the generator groovy script in the main sourcesets, and you try to compile this groovy script to use it as classpath for your JavaExec task. This is why compileJava task is executed, I guess.
You could do in another way, using groovy.ui.GroovyMain to execute your script, with following solution based on this link
configurations {
// a dedicated Configuration for Groovy classpath
groovyScript
}
dependencies {
// Set Groovy dependency so groovy.ui.GroovyMain can be found.
groovyScript localGroovy()
}
task generateClass(type: JavaExec) {
// Set class path used for running Groovy command line.
classpath = configurations.groovyScript
// Main class that runs the Groovy command line.
main = 'groovy.ui.GroovyMain'
// Pass your groovy script as argument of the GroovyMain main
// (can be improved)
args 'src/main/groovy/generatorScript.groovy'
}

How to enable assertions in the Gradle run task

By default, Java disables assertions. (The test I'm using here is assert false; as the first line in main().)
I'd like to have them enabled while running my program with gradle run. What's the trick for doing this?
There is a specific flag enableAssertions that you can set to enable assertions. Such flags are often more readable than working with the jvm args directly. It comes down to personal preferences I think.
Instead of working with applicationDefaultJvmArgs you can add the following to your build.gradle file:
run {
enableAssertions = true
}
This configures the run task to enable assertions.
The run task is of type JavaExec, have a look at the documentation if you are interested in other parameters that you can set (e.g., workingDir or heapMaxSize).
tasks.withType(JavaExec) {
enableAssertions = true
}

How to pass command-line arguments to main class in gradle?

I am creating simple Java class and I would like to create out-of-the-box launcher by using gradle.
So I want to be able to run Java program via gradle:
gradlew clean run These are my command line arguments where These are my command line arguments are passed directly to my public static void main(String... args) method.
I am using the apply plugin: "application" which gives me the run task. But when I am running this 'as is' I've got:
* What went wrong:
Task 'These' not found in root project 'question1'. Some candidates are: 'test'.
Gradle interprets each argument not starting with a hyphen (-) as task name to define which tasks will be executed during the build. Since a task with the name These does not exist, the build fails.
You are using the Gradle Application Plugin, which, as you already stated, provides a run task. The docs show, that the run task is of the type JavaExec. So, to apply your arguments, add them to the run task via args:
run {
args 'These are my command line arguments'
}
To modify the arguments for each build without changing the build.gradle file, simply use project properties:
run {
args findProperty('runArgs')
}
And call gradle clean run -PrunArgs='These are my command line arguments'

Categories