57

I'm using Gradle spring-boot plugin and I need to select a spring active profile for the test run.

How do I pass spring.profiles.active system property to the bootRun plugin's task?

What has already failed:

task bootRunLocal {
    systemProperty "spring.profiles.active", "local"
    System.setProperty("spring.profiles.active", "local")
    tasks.bootRun.execute() // I suspect that this task is executed in a separate JVM
}

and some command line magic also fails:

./gradle -Dspring.profiles.active=local bootRun

Could someone kindly help me solve my troubles?

Update from the answers and comments:

I'm able to set the systemProperty and pass it to the spring container by doing :

run {
    systemProperty "spring.profiles.active", "local"
}

However, when I do this, the local profile is being set for both bootRun task and bootRunLocal task. I need a way to set this property for bootRunLocal task and call booRun task from bootRunLocal.

That might sound very simple, but I come with peace from the structured world of Maven.

Omid Nikrah
  • 2,444
  • 3
  • 15
  • 30
WeMakeSoftware
  • 9,039
  • 5
  • 34
  • 52
  • According to Pieter (below) you shouldn't call execute() on a task. I think we need to fix that before we can tackle the real question. – Dave Syer Apr 30 '14 at 12:26
  • I totally agree with Peter, but do we have any alternatives? Smth like dependsOn, doFirst, doLast? – WeMakeSoftware Apr 30 '14 at 12:37
  • @Funtik please see the simple solution I posted below. I've used this now on many projects with bootRun. – Erich Oct 02 '15 at 16:26
  • 1
    Since gradle 4.9 you can use ./gradlew bootRun --args='--spring.profiles.active=dev'. Posted my answer below. – Domo Oct 23 '18 at 11:38
  • I tried this [answer][1]. But , not worked. How to set Native library location in gradle ? [1]: https://stackoverflow.com/a/23389443/16522525 – Pradeep Simba Aug 13 '21 at 02:48

14 Answers14

96

I know I'm late here... but I recently faced this exact issue. I was trying to launch bootRun with spring.profiles.active and spring.config.location set as system properties on the command line.

So, to get your command line "magic" to work, simply add this to your build.gradle

bootRun {
    systemProperties System.properties
}

Then running from the command line...

gradle -Dspring.profiles.active=local bootRun

Will set local as the active profile, without needing to define a separate task simply to add the env variable.

Erich
  • 1,573
  • 1
  • 13
  • 21
  • most awesome!! Thank you :) – Redfox Jun 29 '17 at 12:24
  • Thank you so much ! :) but after I did this I am getting jacoco class not found error while running any Tests locally but things working fine on CI server. – pannu Mar 07 '19 at 11:49
20

There is no generic way to pass system properties to a task. In a nutshell, it's only supported for tasks that fork a separate JVM.

The bootRunLocal task (as defined above) will not execute in a separate JVM, and calling execute() on a task isn't supported (and would have to happen in the execution phase in any case). Tests, on the other hand, are always executed in a separate JVM (if executed by a Test task). To set system properties for test execution, you need to configure the corresponding Test task(s). For example:

test {
    systemProperty "spring.profiles.active", "local"
}

For more information, see Test in the Gradle Build Language Reference.

Peter Niederwieser
  • 121,412
  • 21
  • 324
  • 259
  • Thanks for prompt reply. Is there a way to explicitly fork a task to be run in a separate JVM? – WeMakeSoftware Apr 29 '14 at 14:55
  • The flow is smth similar to this: gradle -> spring-boot plugin -> bootRun task -> launch of spring container. Is there a way to somehow pass SystemProperty to the spring container? – WeMakeSoftware Apr 29 '14 at 14:58
  • There is no generic way to fork a task. It depends on if and how the task (type) supports it. Same for system properties. – Peter Niederwieser Apr 29 '14 at 16:16
  • 2
    Spring Boot piggy backs on the "run" task. So `run { systemProperty "spring.profiles.active", "local" }` should work. – Dave Syer Apr 29 '14 at 17:12
  • @DaveSyer, thanks. That seems to work. Is there a way I can add this systemProperty conditionally, so it is only set when the bootRunLocal is executed? – WeMakeSoftware Apr 30 '14 at 11:49
  • This is a very helpful, if obscure, feature of Gradle and Spring that fixed a toxic combination bug for me with Swagger (I made a separate gradle profile for Swagger). It would really help to have this in the Gradle and/or Spring documents, thanks a million Peter. – Jason D Oct 06 '14 at 21:15
20
task local {
    run { systemProperty "spring.profiles.active", "local" }
}

bootRun.mustRunAfter local

Then run gradle command as:

gradle bootRun local
Vlad
  • 475
  • 3
  • 6
  • Your answer seems very close but doesn't quite work for me. Peter's answer below seems to make the property "take" and that works for the bootRun task. I don't understand why that is, but I think it has something to do with the run bit not working as Peter describes below. Would you consider editing your answer to remove the run {} part? When I make that change it does work. – Jason D Oct 06 '14 at 21:11
  • I tried this answer. But , not worked. How to set Native library location in gradle? – Pradeep Simba Aug 13 '21 at 02:49
9
SPRING_PROFILES_ACTIVE=local gradle clean bootRun

This is according to this and this and it works.

Soumya
  • 1,833
  • 5
  • 34
  • 45
8

According to the spring-boot-gradle-plugin documentation you should be able to pass arguments like this

./gradlew bootRun --args='--spring.profiles.active=dev'

Seems like this is a new gradle feature since 4.9. I used it in my project and it worked out of the box.

Domo
  • 560
  • 5
  • 18
7

For gradle 2.14 below example works. I have added as below.
When System.properties['spring.profiles.active'] is null then default profile is set.

  bootRun {
       systemProperty 'spring.profiles.active', System.properties['spring.profiles.active']
    }

command line example

gradle bootRun -Dspring.profiles.active=dev
Mikołaj Mitura
  • 121
  • 1
  • 3
6

Just for reference if anyone will have this issue:

Vlad answer didn't quite worked for me but this one works great with 2.4,

task local <<{
    bootRun { systemProperty "spring.profiles.active", "local" }
}
local.finalizedBy bootRun

then gradle local

norbertas.gaulia
  • 2,033
  • 3
  • 18
  • 19
4

Responding to OP's exact request here ...

How do I pass spring.profiles.active system property to the bootRun plugin's task?

And assuming by "pass" the OP meant "pass from commandline" or "pass from IDE invocation" ... This is how I like to do it.

Add this to build.gradle:

/**
 * Task from spring-boot-gradle-plugin, configured for easier development
 */
bootRun {
    /* Lets you pick Spring Boot profile by system properties, e.g. gradle bootRun -Dspring.profiles.active=dev */
    systemProperties = System.properties
}

Then when you invoke it, use the familiar Java flag for setting a system property

gradle bootRun -Dspring.profiles.active=local

There is one main advantage of sticking to system properties, over the environment variables option (SPRING_PROFILES_ACTIVE=local gradle bootRun) ... and that's easy portability between Linux/OS X (bash, etc.) and Windows (cmd.exe anyway).

I learned this way from this blog post.

(UPDATE: Ah somehow I had missed @Erich's response with same recommendation. Oops! I'm leaving my answer, because of the additional details about portability, etc.)

floer32
  • 2,190
  • 4
  • 29
  • 50
3

You can create a new task (in discussed case with name bootRunLocal), that would extend org.springframework.boot.gradle.run.BootRunTask and setup properties before task execution. You can create such a task with following code:

task bootRunLocal(type: org.springframework.boot.gradle.run.BootRunTask) {
    doFirst() {
        main = project.mainClassName
        classpath = sourceSets.main.runtimeClasspath
        systemProperty "spring.profiles.active", "local"
    }
}

More details can be found here: https://karolkalinski.github.io/gradle-task-that-runs-spring-boot-aplication-with-profile-activated/

2

Starting from SpringBoot 2.0.0-M5 setSystemProperties() is no longer a method of the task bootRun. The build.gradle needs to be updated to

bootRun {
    execSpec {
        // System.properties["spring.profiles.active"]
       systemProperties System.properties
    }
}

This is as springBoot's run task uses org.gradle.process.JavaExecSpec

This works for me using Gradle 4.2

CyclingSir
  • 143
  • 1
  • 9
  • won't work https://stackoverflow.com/questions/46924150/using-gradle-to-load-command-line-properties-but-cannot-find-method-execspec – NanoNova Jul 28 '19 at 06:42
1

This works:

SPRING_PROFILES_ACTIVE=production ./gradlew app-service:bootRun

user2266870
  • 81
  • 1
  • 5
  • 1
    This question has already been answered and your answer doesn't contain a reason why this works. – Alexander May 20 '15 at 22:18
  • 2
    The reason this works is that while Gradle won’t pass along system properties to Spring Boot, it does pass along environment variables. Spring Boot is able to pick up the environment variable when it resolves the property and the last ten months of changing property files by hand makes me look like a total and absolute moron https://fbflex.wordpress.com/2014/10/16/spring-boot-shannanigan-overriding-properties-via-the-command-line-when-using-gradle/ – david May 08 '17 at 14:59
0

with run command you can add to build file run { systemProperties = System.properties } and start with gradle run -Dspring.profiles.active=local

z0mb1ek
  • 899
  • 9
  • 16
0

Another way which doesn't require any support from the gradle task: Set the JAVA_TOOL_OPTIONS environment variable:

JAVA_TOOL_OPTIONS='-Dfoo=bar' gradle ...

Or if the variable might already contain anything useful:

JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS -Dfoo=bar" gradle ...
EndlosSchleife
  • 515
  • 7
  • 19
0
// defualt value
def profiles = 'dev'

bootRun {
    args = ["--spring.profiles.active=" + profiles]
}

Then you can simply pick a specific version when starting a gradle task, like

./gradlew bootRun -P dev

"dev" is gonna to take place "prod"

Simon
  • 41
  • 8