# Reading Extension Property\<Boolean\> During Plugin#apply

**URL:** https://discuss.gradle.org/t/reading-extension-property-boolean-during-plugin-apply/48692
**Category:** Help/Discuss
**Created:** [June 12, 2024, 4:13pm UTC](https://discuss.gradle.org/t/reading-extension-property-boolean-during-plugin-apply/48692 "2024-06-12T16:13:59Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![mankyd](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/mankyd/32/11087_2.png) [@mankyd](https://discuss.gradle.org/u/mankyd)
#### Post date: [June 12, 2024, 4:13pm UTC](https://discuss.gradle.org/t/reading-extension-property-boolean-during-plugin-apply/48692/1 "2024-06-12T16:13:59Z")

</div>

I am writing what is effectively a “convention” plugin around Google’s protobuf plugin. My plugin’s job is to apply the protobuf plugin and configure its sources in a manner specific to our source tree. The details aren’t relevant except that I want to add a boolean property to my plugin’s extension, and change the application/configuration of the protobuf plugin depending on the boolean’s value.

Something like this:

```gradle
interface MyProtoExtension {
    val nano: Property<Boolean>
}

```

If `nano` is true, I need to configure the protobuf plugin for javanano-protos. If its false, I need to configure it for javalite-protos.

However, in my plugin, if I access the boolean properties value, I always get false. When am I allowed to read the value?

```gradle
class MyProtoPlugin : Plugin<Project> {

    override fun apply(project: Project) = project.run {
        val myExtension = extensions.create("my_proto", MyProtoExtension::class.java)
                .apply {
                    nano.convention(false)
                }

        plugins.apply(ProtobufPlugin::class.java)
        val pbufExtension = project.extensions.getByType(ProtobufExtension::class.java)

        if (myExtension.nano.get()) { // <=== Always False
            // configure for nano
        } else {
            // configure for lite
        }
    }

```

I’d be perfectly happy making this non-lazy as well, but changing from `val nano: Property<Boolean>` to `var nano: Boolean` seems to have no effect.

I found this earlier discussion, but it didn’t seem to actually answer the question:

> [@Gradle custom extension with lazy configuration doesn't work](https://discuss.gradle.org/t/gradle-custom-extension-with-lazy-configuration-doesnt-work/46618):
>
> Hello! I am working on implementing a custom plugin in a standalone project that will be used by other projects. In this plugin, I want to configure many other plugins. Here’s the Plugin code: class CodeStylePlugin : Plugin\<Project\> { override fun apply(project: Project) { project.extensions.create( "myplugin", CodeStyleExtension::class.java ) val config = project.extensions.getByType(CodeStyleExtension::class.java) if (config.addCh…

---

<div class="post-metadata">

### Author: ![Vampire](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/vampire/32/9082_2.png) [@Vampire](https://discuss.gradle.org/u/Vampire)
#### Post date: [June 13, 2024, 8:54am UTC](https://discuss.gradle.org/t/reading-extension-property-boolean-during-plugin-apply/48692/2 "2024-06-13T08:54:34Z")

</div>

I do not agree that the question was not answered there, the recommendations are still the same as in my answer over there.

That is, if the question is “how to properly solve it”.

If the question is “when can I read the value safely”, then the answer is, you cannot at configuration time, only at execution time. At configuration time you never know whether the value might be modified further. Unless of course you force the value to read-only after you have read it, but that is not really good practice.

> I’d be perfectly happy making this non-lazy as well, but changing from `val nano: Property<Boolean>` to `var nano: Boolean` seems to have no effect.

Because this does not make it lazier. The `Property<Boolean>` is only lazy if you also treat it lazy, that is only read it as late as possible, optimally at execution time where configuration should not be changed anymore. If you have a `Property<Boolean>` and call `get()` on it this is just as eager as having a `boolean` and reading it.

---

<div class="post-metadata">

### Author: ![mankyd](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/mankyd/32/11087_2.png) [@mankyd](https://discuss.gradle.org/u/mankyd)
#### Post date: [June 13, 2024, 1:29pm UTC](https://discuss.gradle.org/t/reading-extension-property-boolean-during-plugin-apply/48692/3 "2024-06-13T13:29:30Z")

</div>

Thank you for your reply. I think this answers my question: “you cannot [read the value] at configuration time, only at execution time.” In other words, what I need to do is impossible.

I need to use the extension’s options to change configuration.

I suppose the alternative is to write, nearly identical plugins, one of which is configured differently than the other:

`my_proto { ... }`  
and  
`my_proto_nano { ... } `

This feels less optimal, but I will go with it unless an alternative can be proposed.

I’ll add: Google’s protobuf plugin uses `afterEvaluate` internally, and I don’t know if this is complicating things. From their own documentation you can find the “DO NOTS” section - [https://github.com/google/protobuf-gradle-plugin/tree/master:](https://github.com/google/protobuf-gradle-plugin/tree/master:)

> - DO NOT configure the tasks outside of the `generateProtoTasks` block, because there are subtle timing constraints on when the tasks should be configured.

I am using there `generateProtoTasks` block, but it has not helped.

---

<div class="post-metadata">

### Author: ![Vampire](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/vampire/32/9082_2.png) [@Vampire](https://discuss.gradle.org/u/Vampire)
#### Post date: [June 13, 2024, 1:42pm UTC](https://discuss.gradle.org/t/reading-extension-property-boolean-during-plugin-apply/48692/4 "2024-06-13T13:42:46Z")

</div>

As I recommended in that other thread you linked.

Yes, separate plugins are one option.  
You don’t have to make them nearly identical, you can make for example a third plugin that is applied from both for the common things, or have a common base class for the two plugins with the common logic.

Or as also recommended, you could have a function in your extension instead of a property and do the respective configuration in that function, something like `fun useNano()`or `fun useNano(useNano: Boolean)`. If you do it like that, make sure that the configuration changes work properly if you call it multiple times with different argument or ensure that it fails if it gets called a second time with different value.

If you would use `afterEvaluate` to delay the reading of the property to a time when your consumer had a chance to set the value, this will work, but only for example if your consumer does not himself use `afterEvaluate` to set your property for some reason. Hence the recommendations to either use a function or separate plugins, as `afterEvaluate`’s main effect is to introduce ordering problems, timing problems, and race conditions. That the ProtoBuf plugin is using `afterEvaluate` is bad practice and should be improved. The more plugins that are using `afterEvaluate`, the higher the probability, that you run into strange effects that are hard to understand. Hence `afterEvaluate` should almost always be avoided under almost any cost if possible.
