# Why does gradle deprecate and remove things so often?

**URL:** <https://discuss.gradle.org/t/why-does-gradle-deprecate-and-remove-things-so-often/40964>\
**Category:** Help/Discuss\
**Created:** [September 10, 2021, 2:02pm UTC](https://discuss.gradle.org/t/why-does-gradle-deprecate-and-remove-things-so-often/40964 "2021-09-10T14:02:50Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![mjparme](https://avatars.discourse-cdn.com/v4/letter/m/8c91f0/32.png) [@mjparme](https://discuss.gradle.org/u/mjparme)\
**Post date:** [September 10, 2021, 2:02pm UTC](https://discuss.gradle.org/t/why-does-gradle-deprecate-and-remove-things-so-often/40964/1 "2021-09-10T14:02:50Z")

</div>

This is a little bit of a rant but I am curious why Gradle deprecates and removes things so often? This is not ideal for a build tool we need stability and backwards compatibility from a build tool.

I can understand if there is a fundamental design flaw that needs to be fixed but something like this?

```gradle
The Report.enabled property has been deprecated. This is scheduled to be removed in Gradle 8.0. Please use the required property instead. See https://docs.gradle.org/7.1.1/dsl/org.gradle.api.reporting.Report.html#org.gradle.api.reporting.Report:enabled for more details.

```

What possible reason could there be to break everyone’s build just to change “enabled” to “required”?

I fight things like this on every release, just deprecations and removals that don’t seem to have any reason behind them whatsoever.

Another example, just got done upgrading from 6.8.x to 7.1.1 and I had to add this seemingly random DSL block to my builds so they worked under 7.1.x:

```gradle
project.tasks.named("sourcesJar") {
    duplicatesStrategy = DuplicatesStrategy.EXCLUDE
}

```

Why would something like this all of a sudden be necessary?

Does Gradle have any future plans to stabilize the API and to stop breaking shit for no particular reason?

---

<div class="post-metadata">

**Author:** ![pucgenie](https://avatars.discourse-cdn.com/v4/letter/p/278dde/32.png) [@pucgenie](https://discuss.gradle.org/u/pucgenie)\
**Post date:** [September 15, 2021, 6:56pm UTC](https://discuss.gradle.org/t/why-does-gradle-deprecate-and-remove-things-so-often/40964/2 "2021-09-15T18:56:09Z")

</div>

Semantics are based on conventions. Conventions are defined by opinions supported by the “majority” of people (or the more powerful people). Working against conventions isn’t “bad” by itself but may cause unnecessary gray hair for fellow developers.

> [@mjparme](#):
>
> why Gradle deprecates and removes things so often

I don’t have an answer to your question, but personally I’m grateful for pointers such as

> [@](#):
>
> Please use […] instead. See […] for more details.

so that **creating a tool to automatically update build scripts should be possible** (and should be working in more than 50% of the cases).

> [@mjparme](#):
>
> What possible reason could there be to break everyone’s build just to change “enabled” to “required”? I fight things like this on every release, just deprecations and removals that don’t seem to have any reason behind them whatsoever.

As non-native English speaker I can’t help you with semantics explanations.  
A certain programming language runtime I use used to be backwards-compatible for two decades and then changed quite a few fundamental things requiring quite a bit of additional configuration for making old things work on newer runtime versions.

> [@mjparme](#):
>
> Why would something like this all of a sudden be necessary?

I, too, don’t understand why EXCLUDE (or better yet: some sort of exclude-if-identical) shouldn’t be the default - could you find some more references on [discussions](https://github.com/gradle/gradle/issues/10038#issuecomment-514149324) about that?

> [@mjparme](#):
>
> Does Gradle have any future plans to stabilize the API and to stop breaking shit for no particular reason?

To my knowledge the principles of [semantic versioning](https://semver.org/) are applied. If someone needs to stick to an old Major version backporting newer fixes etc. could be an (time-consuming) alternative. See my first paragraph - changing conventions based on evolved knowledge isn’t simple on Gradle’s side too I believe.

---

<div class="post-metadata">

**Author:** ![ingokegel](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/ingokegel/32/2126_2.png) [@ingokegel](https://discuss.gradle.org/u/ingokegel)\
**Post date:** [September 16, 2021, 4:07pm UTC](https://discuss.gradle.org/t/why-does-gradle-deprecate-and-remove-things-so-often/40964/3 "2021-09-16T16:07:53Z")

</div>

These are the easy problems that have mechanical fixes. The more worrying changes are when behavior is altered or even removed like in

> <https://github.com/gradle/gradle/issues/13891>
>
> In many places we already assume that the root directory includes all the source… code for the project. And it's a good assumption, allowing us to do optimizations like watching only the project root for changes (see #13887).
> 
> However, it's actually possible to include subprojects from directories outside the root dir:
> 
> \`\`\`groovy
> include("side-project")
> project(":side-project").projectDir = file("../side-dir")
> \`\`\`
> 
> We should deprecate this as bad practice and remove it soon.
> 
> \---
> cc: @gradle/execution

There are always good reasons for them to do so, but it does feel like a constant fight to stay up to date.

---

<div class="post-metadata">

**Author:** ![chrisjr](https://avatars.discourse-cdn.com/v4/letter/c/dec6dc/32.png) [@chrisjr](https://discuss.gradle.org/u/chrisjr)\
**Post date:** [September 16, 2021, 9:53pm UTC](https://discuss.gradle.org/t/why-does-gradle-deprecate-and-remove-things-so-often/40964/4 "2021-09-16T21:53:44Z")

</div>

I feel your pain. My job description these days could easily be summarised as “Running after the Gradle developers with a bucket”.

The answer to “Why has `Report.enabled` been replaced with `Report.required`?” probably lies in the [JavaDocs](https://docs.gradle.org/current/javadoc/org/gradle/api/reporting/Report.html):

`boolean Report.isEnabled()`

returns a Java primitive, whereas

`Property<Boolean> Report.getRequired()`

returns a lazy property. As a rule, we _want_ to use lazy properties instead of Java primitives or POJOs because lazy properties will be evaluated once all Gradle build scripts have been parsed and Gradle’s “configuration” phase is complete. However changing an existing property from a `boolean` to a `Property<Boolean>` would be a breaking ABI change, and no-one wants that either.

The bottom line is that Gradle is slowly retro-fitting its lazy property API over its POJO-based one. _And this is important_, because otherwise the ordering of the statements inside the `build.gradle` scripts becomes very significant. I remember learning this lesson the hard way, back when I wrote my very first Gradle plugin: The only way to copy values set via my plugin’s DSL extension into a task my plugin had also created was to use a `Project.afterEvaluate` handler. However, other plugins can create `afterEvaluate` handlers too, and there is still no way to control the order that Gradle executes them all in.

I am far more forgiving of Maven’s `pom.xml` files these days. XML is verbose, but it also declarative rather than imperative. Whereas Gradle needs to bend over backwards to make its imperative Groovy/Kotlin scripts _appear_ to be declarative.

Cheers,  
Chris
