As of this writing there are 1,396 public types with 6,275 public methods available in Gradle’s public API to compile Java code against. Kotlin DSL and Groovy DSL each add some syntactic sugar on top of these. Some inconsistencies are bound to manifest over the years in such a large API.
One of the most significant inconsistencies is about our redundant configuration model. Historically, Gradle’s build model was configured using the JavaBeans model, i.e. properties defined via getters and setters. In 2017 we introduced the provider API as an alternative configuration model with a number of benefits, like lazy configuration, tracking build dependencies and lifecycle management on a fine-grained level.
The plan was to eventually convert the entirety of the Gradle API to the provider API, but it was never fully implemented. At present about 12% of public properties use provider API semantics. The rest is mostly exposed as JavaBean properties, but there is also a significant number of methods that conform to neither standard.
The inconsistency of our configuration model is the cause for some of the most reported problems, and the largest culprit for accidental complexity in Gradle builds. Full conversion would mean a lazy-only configuration model that would make some mistakes impossible to make that currently cause performance issues like cache misses, but can even result in incorrect builds. A lazy-only API also means we could track the origin of the value of a property, e.g. we can tell if a JavaCompile task is configured for Java 8 source compatibility because of a convention plugin, dictated by the JDK being used, or set from a build script. Some future features like coarse-grained execution, sandboxing and remote execution depend on a fully lazy API, or would be significantly simpler to implement with.
In Gradle 9.0 we are planning to migrate a large part of the remaining public API to use providers.
A demo of the upgrade experience can be tried here: https://github.com/gradle/provider-api-migration-testbed
As of this writing there are 1,396 public types with 6,275 public methods available in Gradle’s public API to compile Java code against. Kotlin DSL and Groovy DSL each add some syntactic sugar on top of these. Some inconsistencies are bound to manifest over the years in such a large API.
One of the most significant inconsistencies is about our redundant configuration model. Historically, Gradle’s build model was configured using the JavaBeans model, i.e. properties defined via getters and setters. In 2017 we introduced the provider API as an alternative configuration model with a number of benefits, like lazy configuration, tracking build dependencies and lifecycle management on a fine-grained level.
The plan was to eventually convert the entirety of the Gradle API to the provider API, but it was never fully implemented. At present about 12% of public properties use provider API semantics. The rest is mostly exposed as JavaBean properties, but there is also a significant number of methods that conform to neither standard.
The inconsistency of our configuration model is the cause for some of the most reported problems, and the largest culprit for accidental complexity in Gradle builds. Full conversion would mean a lazy-only configuration model that would make some mistakes impossible to make that currently cause performance issues like cache misses, but can even result in incorrect builds. A lazy-only API also means we could track the origin of the value of a property, e.g. we can tell if a
JavaCompiletask is configured for Java 8 source compatibility because of a convention plugin, dictated by the JDK being used, or set from a build script. Some future features like coarse-grained execution, sandboxing and remote execution depend on a fully lazy API, or would be significantly simpler to implement with.In Gradle 9.0 we are planning to migrate a large part of the remaining public API to use providers.
A demo of the upgrade experience can be tried here: https://github.com/gradle/provider-api-migration-testbed