113

I'm trying to set up gradle to launch the bootRun process with various spring profiles enabled.

My current bootRun configuration looks like:

bootRun {
    // pass command line options from gradle to bootRun
    // usage: gradlew bootRun "-Dspring.profiles.active=local,protractor"
    if (System.properties.containsKey('spring.profiles.active')) {
        systemProperty "spring.profiles.active", System.properties['spring.profiles.active']
    }
}

I'd like to set system properties with a gradle task, and then execute bootRun.

My attempt looked like this:

task bootRunDev

bootRunDev  {
    System.setProperty("spring.profiles.active", "Dev")
}

A few questions:

  1. is systemProperty a part of the spring boot bootRun configuration?
  2. is it possible to set a system property in another task?
  3. What should my next step be? I need to get bootRunDev configuration to happen before bootRun
  4. Is there another approach I should look into

-Eric

Eric Francis
  • 23,039
  • 31
  • 88
  • 122

17 Answers17

163

Spring Boot v2 Gradle plugin docs provide an answer:

6.1. Passing arguments to your application

Like all JavaExec tasks, arguments can be passed into bootRun from the command line using --args='<arguments>' when using Gradle 4.9 or later.

To run server with active profile set to dev:

$ ./gradlew bootRun --args='--spring.profiles.active=dev'
Community
  • 1
  • 1
Ivar
  • 4,350
  • 2
  • 27
  • 29
80

Environment variables can be used to set spring properties as described in the documentation. So, to set the active profiles (spring.profiles.active) you can use the following code on Unix systems:

SPRING_PROFILES_ACTIVE=test gradle clean bootRun

And on Windows you can use:

SET SPRING_PROFILES_ACTIVE=test
gradle clean bootRun
Paulo Merson
  • 13,270
  • 8
  • 79
  • 72
david
  • 997
  • 7
  • 5
  • 2
    While this code snippet may solve the question, [including an explanation](http://meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – DimaSan Jun 21 '17 at 07:17
  • On *nix, you will probably need to export the variable for it to be visible to gradle: `export SPRING_PROFILES_ACTIVE=dev; gradle bootRun` – Steve Tarver Apr 03 '18 at 14:59
  • 5
    No, on a per-call basis setting environment variables works as shown by david. – Patrick Bergner Jul 27 '18 at 13:10
  • It does work on Windows! In my case, I was not even running bootRun, but executing `SpringBootTest` tests that require the active profiles for retrieving properties via spring-cloud-config. – Paulo Merson Apr 24 '19 at 18:35
67

Simplest way would be to define default and allow it to be overridden. I am not sure what is the use of systemProperty in this case. Simple arguments will do the job.

def profiles = 'prod'

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

To run dev:

./gradlew bootRun -Pdev

To add dependencies on your task you can do something like this:

task setDevProperties(dependsOn: bootRun) << {
  doFirst {
    System.setProperty('spring.profiles.active', profiles)
  }
}

There are lots of ways achieving this in Gradle.

Edit:

Configure separate configuration files per environment.

if (project.hasProperty('prod')) {
  apply from: 'gradle/profile_prod.gradle'
} else {
  apply from: 'gradle/profile_dev.gradle'
}

Each configuration can override tasks for example:

def profiles = 'prod'
bootRun {
  systemProperty "spring.profiles.active", profiles
}

Run by providing prod flag in this case just like that:

./gradlew <task> -Pprod
GreenGiant
  • 4,930
  • 1
  • 46
  • 76
Vaelyr
  • 2,841
  • 2
  • 21
  • 34
  • I get `Could not find method dev() for arguments [org.springframework.boot:spring-boot-devtools] on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.` when I try this approach. http://stackoverflow.com/a/31328621/1134197 works fine – aycanadal Nov 18 '16 at 12:21
  • 3
    While first code snippet shows how to configure `bootRun` task, other examples simply do not work. – Ivar Feb 26 '18 at 17:34
  • 6
    Can you update how `-Pdev` will set `profiles` to `dev`? It seems it does not work at all. – lowatt Nov 08 '18 at 21:49
  • 1
    You obviously need to have 'org.springframework.boot' plugin applied to your project as well. – Vaelyr Jan 20 '19 at 17:04
  • For anyone confused about `-P` see [Passing System properties to your application](https://docs.spring.io/spring-boot/docs/current/gradle-plugin/reference/htmlsingle/#running-your-application-passing-system-properties) on the Spring website. It allows properties to be passed to the JVM. – Zach Jan 15 '21 at 15:29
16

Using this shell command it will work:

SPRING_PROFILES_ACTIVE=test gradle clean bootRun

Sadly this is the simplest way I have found. It sets environment property for that call and then runs the app.

Rafael
  • 2,521
  • 2
  • 33
  • 59
15

For those folks using Spring Boot 2.0+, you can use the following to setup a task that will run the app with a given set of profiles.

task bootRunDev(type: org.springframework.boot.gradle.tasks.run.BootRun, dependsOn: 'build') {
    group = 'Application'

    doFirst() {
        main = bootJar.mainClassName
        classpath = sourceSets.main.runtimeClasspath
        systemProperty 'spring.profiles.active', 'dev'
    }
}

Then you can simply run ./gradlew bootRunDev or similar from your IDE.

Mikezx6r
  • 16,829
  • 7
  • 33
  • 31
Yona Appletree
  • 8,801
  • 6
  • 35
  • 52
8

Kotlin edition: Define the following task in you build.gradle.kts file:

tasks.named<BootRun>("bootRun") {
  args("--spring.profiles.active=dev")
}

This will pass the parameter --spring.profiles.active=dev to bootRun, where the profile name is dev in this case.

Every time you run gradle bootRun the profile dev is used.

deamon
  • 89,107
  • 111
  • 320
  • 448
7

In your build.gradle file simply use the following snippet

bootRun {
  args = ["--spring.profiles.active=${project.properties['profile'] ?: 'prod'}"]
}

And then run following command to use dev profile:

./gradlew bootRun -Pprofile=dev
Akter Hossain
  • 81
  • 1
  • 2
7

For the command line as of Gradle 7.5 and Spring Boot 2.7.3, I do this (if it helps anyone):

gradle bootRun --args=--spring.profiles.active=myprofile
Patrice Gagnon
  • 1,276
  • 14
  • 14
6

I wanted it simple just to be able to call gradle bootRunDev like you without having to do any extra typing..

This worked for me - by first configuring it the bootRun in my task and then right after it running bootRun which worked fine for me :)

task bootRunDev {
    bootRun.configure {
        systemProperty "spring.profiles.active", 'Dev'
    }
}

bootRunDev.finalizedBy bootRun
Mohamed Omar
  • 158
  • 1
  • 7
6

For anyone looking how to do this in Kotlin DSL, here's a working example for build.gradle.kts:

tasks.register("bootRunDev") {
    group = "application"
    description = "Runs this project as a Spring Boot application with the dev profile"
    doFirst {
        tasks.bootRun.configure {
            systemProperty("spring.profiles.active", "dev")
        }
    }
    finalizedBy("bootRun")
}
Jakub Zalas
  • 35,761
  • 9
  • 93
  • 125
3

For someone from internet, there was a similar question https://stackoverflow.com/a/35848666/906265 I do provide the modified answer from it here as well:

// build.gradle
<...>

bootRun {}

// make sure bootRun is executed when this task runs
task runDev(dependsOn:bootRun) {
    // TaskExecutionGraph is populated only after 
    // all the projects in the build have been evaulated https://docs.gradle.org/current/javadoc/org/gradle/api/execution/TaskExecutionGraph.html#whenReady-groovy.lang.Closure-
    gradle.taskGraph.whenReady { graph ->
        logger.lifecycle('>>> Setting spring.profiles.active to dev')
        if (graph.hasTask(runDev)) {
            // configure task before it is executed
            bootRun {
                args = ["--spring.profiles.active=dev"]
            }
        }
    }
}

<...>

then in terminal:

gradle runDev

Have used gradle 3.4.1 and spring boot 1.5.10.RELEASE

Ivar
  • 4,350
  • 2
  • 27
  • 29
3

Configuration for 4 different task with different profiles and gradle tasks dependencies:

  • bootRunLocal and bootRunDev - run with specific profile
  • bootPostgresRunLocal and bootPostgresRunDev same as prev, but executing custom task runPostgresDocker and killPostgresDocker before/after bootRun

build.gradle:

final LOCAL='local'
final DEV='dev'

void configBootTask(Task bootTask, String profile) {
    bootTask.main = bootJar.mainClassName
    bootTask.classpath = sourceSets.main.runtimeClasspath

    bootTask.args = [ "--spring.profiles.active=$profile" ]
//    systemProperty 'spring.profiles.active', profile // this approach also may be used
    bootTask.environment = postgresLocalEnvironment
}

bootRun {
    description "Run Spring boot application with \"$LOCAL\" profile"
    doFirst() {
        configBootTask(it, LOCAL)
    }
}

task bootRunLocal(type: BootRun, dependsOn: 'classes') {
    description "Alias to \":${bootRun.name}\" task: ${bootRun.description}"
    doFirst() {
        configBootTask(it, LOCAL)
    }
}

task bootRunDev(type: BootRun, dependsOn: 'classes') {
    description "Run Spring boot application with \"$DEV\" profile"
    doFirst() {
        configBootTask(it, DEV)
    }
}

task bootPostgresRunLocal(type: BootRun) {
    description "Run Spring boot application with \"$LOCAL\" profile and re-creating DB Postgres container"
    dependsOn runPostgresDocker
    finalizedBy killPostgresDocker
    doFirst() {
        configBootTask(it, LOCAL)
    }
}

task bootPostgresRunDev(type: BootRun) {
    description "Run Spring boot application with \"$DEV\" profile and re-creating DB Postgres container"
    dependsOn runPostgresDocker
    finalizedBy killPostgresDocker
    doFirst() {
        configBootTask(it, DEV)
    }
}
radistao
  • 14,889
  • 11
  • 66
  • 92
1

Add to VM options: -Dspring.profiles.active=dev

Or you can add it to the build.gradle file to make it work: bootRun.systemProperties = System.properties.

meiskalt7
  • 606
  • 7
  • 13
  • 6
    This needs to be added to the `build.gradle` file to make it work: `bootRun.systemProperties = System.properties`. See https://github.com/spring-projects/spring-boot/issues/832#issuecomment-272780482 – Janux Jan 19 '19 at 15:58
1

my way:

in gradle.properties:

profile=profile-dev

in build.gradle add VM options -Dspring.profiles.active:

bootRun {
   jvmArgs = ["-Dspring.output.ansi.enabled=ALWAYS","-Dspring.profiles.active="+profile]
}

this will override application spring.profiles.active option

Dmitriy
  • 234
  • 2
  • 7
1

Working solution for Spring Boot 2.5+

tasks.register('runDev') {
   dependsOn 'bootRun'
   bootRun.systemProperty('spring.profiles.active', 'dev')
}

and to run:

./gradlew runDev
DevTomek
  • 501
  • 4
  • 6
1

For Gragle Kotlin, following works for me

tasks.bootRun {
    args("--spring.profiles.active=dev")
}
maruf571
  • 1,836
  • 2
  • 21
  • 18
0

If you are using jib for containerisation then, Add these two line of codes in your build.gradle and application.properties files respectively.

jib.container.jvmFlags = ['-Dspring.profiles.active=test']
spring.profiles.active=test

that's it.

Shubham K.
  • 93
  • 1
  • 2
  • 13