A Bag of Properties
Posted on 2022-04-25

Gradle properties is one of the many ways to pass information to Gradle. It gives you type-unsafe way to define String key-value pairs similar to Java properties.

Setting properties

You can set Gradle properties in 4 places (the first one found in any of these locations wins):

  1. command-line with -Pcom.foo=bar
  2. gradle.properties in GRADLE_USER_HOME directory
  3. gradle.properties in project root directory (sometimes it works in subproject directories, but it is not supported)
  4. gradle.properties in Gradle installation directory (e.g. if your project ships a custom Gradle distribution)

You are likely going to see command-line and project root gradle.properties most often. However, GRADLE_USER_HOME (default is ~/.gradle) can be handy to set secret tokens or signing keys.

Gradle has dozens of built-in properties such as org.gradle.caching=true and org.gradle.parallel=true. I highly recommend bookmarking that page and checking out available values every once in a while, as there are some gems like org.gradle.caching.debug=true that helps you debug Gradle task caching (oh so many caches!) bugs.

Android Gradle Plugin (AGP) also has an assortment of Gradle properties, but sadly these are scattered throughout the documentation and are a bit hard to find. It is the best to look at BooleanOption.kt in AGP source code. Here you can find things like android.defaults.buildfeatures.aidl=false (to disable AIDL if you don’t use it in your build) or android.uniquePackageNames=true to enforce unique Android package names throughout your projects.

Many other plugins have their own Gradle properties, for inspiration you can take a peek at androidx project gradle.properties and see if any of them would work for you.

Reading properties

You can check if a given property is set via project.hasProperty("foo.bar") and read it through project.getProperties() or project.property(“foo.bar”). This mechanism allows your own build to have these values, which can be useful for things like -Pci=true.

One frustrating thing with this system is that it is not type safe. If you look at the methods linked above, they all return Object type and then you have to cast it to something more useful. Folks at Slack have built a version of type-safe properties that does this a bit better.

These are not the properties you are looking for

Continuing the theme of overloaded terms - properties is no exception. Gradle also has:

  • dynamic project properties - which are responsible for a lot of “magic” in your build.gradle files
  • Property class used in a configuration context.
  • Lazy properties to describe a general category of inputs that are not computed at configuration time.
  • local.properties - technically in the same category as all the gradle.properties, but used for non-versioning-system-safe properties such as a path to Android SDK