Gradle project properties best practices

Gradle project properties best practices

Last Updated on September 8, 2021

Gradle project properties provide an easy way to customise builds which may need to run differently in certain situations. In this article you’ll learn the most effective ways to use and set properties, along with some common scenarios you might come across in your Gradle project.

UPDATED in July 2021 to reflect recent versions of Gradle.

Why do we need project properties in a Gradle build?

A Gradle project property is a property that can be accessed in your project’s build.gradle and gets passed in from an external source when your build is executed.

Just like you might externalise configuration properties for an application so it can execute differently in different scenarios, the same applies to your Gradle build.

Let’s look at some reasons you might use project properties.

Avoid storing credentials or other sensitive information in version control

The following build.gradle configures the Gradle maven-publish plugin to publish a jar file built by the java plugin:

plugins {
    id 'java'
    id 'maven-publish'
}

publishing {
    publications {
        maven(MavenPublication) {
            from components.java
        }
    }
    repositories {
        maven {
            url 'https://maven.tomgregory.com/repository/snapshots'
            credentials {
                username 'tom'
                password 'buttons123'
            }
        }
    }
}

group 'org.example'
version '1.0-SNAPSHOT'

The above code will publish a jar file to a Maven repository when ./gradlew publish is run.

But, you can see the username and password for the Maven repository are hard-coded. Assuming we’re committing our code into version control, then this represents bad practice since anyone who checks out our code would immediately have access to the credentials.

Much better would be to pass the credentials in externally, using Gradle project properties. The build.gradle just needs to be modified slightly:

            ...
            credentials {
                username mavenUsername
                password mavenPassword
            }
            ...

Now when we call the publish task we can pass the properties in using the Gradle -P flag, like this:

./gradlew publish -PmavenUsername=tom -PmavenPassword=buttons123

The build may need to be run differently depending on the situation

Sometimes rather than hard-coding parts of our build, we need to be more flexible and run it differently in different situations. For example, in the previous section the Maven repository URL was hard coded, like this:

        maven {
            url 'https://maven.tomgregory.com/repository/snapshots'
            credentials {
                username mavenUsername
                password mavenPassword
            }
        }

There may be a requirement to sometimes push to a different repository, in which case we’d also want to externalise this property using a project property.

Some other scenarios like this include:

  • deployment – if your Gradle build is responsible for deploying then you may need to pass in extra information such as the environment and region to which to deploy
  • test memory allocation – the Gradle test task allows you to configure it’s maxHeapSize property. By using a project property, you can externalise this configuration and easily tweak the memory allocation for different environments.
  • database connection string – if your build needs to connect to a database to run tests, you could use a project property to provide the option to connect to a different database.

What ways are there to configure project properties?

Gradle provides several ways to pass properties into a build, some of which have higher priority than others. Or in other words, the same property key can be passed into the build in multiple ways, but the one with highest priority wins.

Here’s a quick overview of how that hierarchy works:

We’ll run through the ways to configure project properties from highest to lowest priority.

1) On the command line when calling Gradle using -P

When you run a Gradle command you can pass as many -PpropertyName=propertyValue flags as you like. For example:

./gradlew <task-name> -PmyPropName1=myPropValue1 -PmyPropName2=myPropValue2

2) As Java system properties using -D

You can pass Java system properties using the following syntax:

./gradlew <task-name> -Dorg.gradle.project.myPropName1=myPropValue1 -Dorg.gradle.project.myPropName2=myPropValue2

3) As environment variables

You can pass project properties as environment variables using the following syntax:

ORG_GRADLE_PROJECT_myPropName1=myPropValue1 ORG_GRADLE_PROJECT_myPropName2=myPropValue2 ./gradlew publish

4) In a gradle.properties file (Gradle user home directory)

A gradle.properties file is a list of key values pairs, each of which represents a property name and value. For example:

myPropName1=myPropValue1
myPropName2=myPropValue2

This gradle.properties is located in the GRADLE_USER_HOME directory, which is usually ~/.gradle/gradle.properties

5) In a gradle.properties file (project root directory)

Similar to above, a gradle.properties file can also be placed in the project root directory, i.e. my-awesome-project/gradle.properties

10 Common Mistakes To Avoid In Your Gradle Project

Get your FREE PDF guide!

✅ Easy fixes you can apply today
✅ Build your project consistently every time
✅ Improve performance and maintainability

How can we access project properties in builds?

Once a property has been passed into our Gradle build, there are three ways to access it:

1) Directly as a variable

You can treat a project property as a variable, and just reference it by its name.

For example, if we passed in a project property with ./gradlew <task-name> -PmyPropName1=myPropValue1 then it could be accessed in build.gradle like this:

println myPropName1

If the property is not found, then a MissingPropertyException is thrown.

Also note, that with this method IDEs may have a problem understanding and show a syntax error. Here’s the output from IntelliJ IDEA:

Cannot infer argument type error

2) Using the property method

Gradle provides the following method to access a property:

Object property(String var1) throws MissingPropertyException

For example, if we called ./gradlew <task-name> -PmyPropName1=myPropValue1 then the property could be accessed like this:

println property('myPropName1')

Like before, if the property is not found, then a MissingPropertyException is thrown.

3) Using the findProperty method

When we need to access a property but don’t want an exception to be thrown if it’s not provided, use the findProperty method:

Object findProperty(String var1)

If we called ./gradlew <task-name> -PmyPropName1=myPropValue1 then the property could be accessed like this:

println findProperty('myPropName1')

This time, if the property is not found null is returned. This can be very useful if we want to return a default value, which we can do using Groovy’s Elvis operator:

println findProperty('myPropName1') ?: 'defaultValue'

Checking if a property exists with hasProperty

Lastly, we can check for the presence of the property using the hasProperty method:

boolean hasProperty(String var1)

This could be used where we have some build logic that’s only enabled if a specific property is set, for example:

if (hasProperty('myPropName1')) {
    println 'Doing some conditional build logic'
}

Summary

Here’s a summary of the 3 ways to access a property value:

Throws MissingPropertyException?IDE understands?
As a variableYesNo
property methodYesYes
findProperty methodNoYes

Resources

Documentation

See this Gradle Build Environment documentation which covers project properties, as well as Gradle and system properties.

Video

If you prefer to learn in video format, check out the accompanying video on the Tom Gregory Tech YouTube channel.

Get going with Gradle course
Gradle icon

Want to learn more about Gradle?
Check out the full selection of Gradle tutorials.

Gradle project properties best practices

4 thoughts on “Gradle project properties best practices

    1. Hi Felix. Do you mean the gradle.properties file? I’m not aware of any way to auto-generate this file.

      Just create it when you need to add properties.

  1. Is there we can call the AWS access key and secret key from jenkins envornment variable to gradle.properties.

    1. Yes, if you’re using a Jenkins pipeline you can access credentials within the pipeline definition. e.g.

      stage('Example Username/Password') {
          environment {
              SERVICE_CREDS = credentials('my-predefined-username-password')
          }
          steps {
              sh 'echo "Service user is $SERVICE_CREDS_USR"'
              sh 'echo "Service password is $SERVICE_CREDS_PSW"'
              sh 'curl -u $SERVICE_CREDS https://myservice.example.com'
          }
      }

      (example taken from Jenkins docs)

      You can then pass those environment variables directly to your Gradle build using the techniques from this article.

Leave a Reply to Felix rith Cancel reply

Your email address will not be published. Required fields are marked *

Scroll to top

Get the newsletter

Found this article helpful? Subscribe for monthly updates.

✅ All of my latest articles for the month
✅ Access to video tutorials
✅ Exclusive tips not found on my website