# Callback after plugin initialisation done and plugin extension configured?

**URL:** <https://discuss.gradle.org/t/callback-after-plugin-initialisation-done-and-plugin-extension-configured/37518>\
**Category:** Help/Discuss\
**Created:** [September 7, 2020, 11:11pm UTC](https://discuss.gradle.org/t/callback-after-plugin-initialisation-done-and-plugin-extension-configured/37518 "2020-09-07T23:11:02Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tomas\_Prochazka](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/tomas_prochazka/32/261_2.png) [@Tomas\_Prochazka](https://discuss.gradle.org/u/Tomas_Prochazka)\
**Post date:** [September 7, 2020, 11:11pm UTC](https://discuss.gradle.org/t/callback-after-plugin-initialisation-done-and-plugin-extension-configured/37518/1 "2020-09-07T23:11:02Z")

</div>

Is there any callback that is fired after plugin initialization is done, but before all other build configuration code? And also after closed own plugi extension? I would like to use some features from another plugin, but `afterEvaluate` is too late.

```gradle
plugins {
    `java-library`
    `maven-publish`
    id("my-plugin")
}

{callback here}

myPluginExntension {
   ...
}
{second callback here}

... rest of the buil.gradle file

```

---

<div class="post-metadata">

**Author:** ![Lance](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/lance/32/787_2.png) [@Lance](https://discuss.gradle.org/u/Lance)\
**Post date:** [September 8, 2020, 5:06am UTC](https://discuss.gradle.org/t/callback-after-plugin-initialisation-done-and-plugin-extension-configured/37518/2 "2020-09-08T05:06:08Z")

</div>

Take a look at this thread which discusses some lazy configuration techniques that can help you avoid afterEvaluate including

- the “live” collection methods on [DomainObjectCollection](https://docs.gradle.org/current/javadoc/org/gradle/api/DomainObjectCollection.html) (eg all(Closure) or matching(Closure))
- Property and Provider (see [lazy-configuration](https://docs.gradle.org/current/userguide/lazy_configuration.html) )

> [@Unit test plugin's afterEvaulate](https://discuss.gradle.org/t/unit-test-plugins-afterevaulate/37437):
>
> Lately I started writing my first gradle plugin (gradle 6.4.1) and used gradle init with selection 421 (Gradle Plugin, Java, Groovy) as starting point. My plugin features an extension (similar to the Java plugin’s sourceSets) with a NamedDomainObjectContainer in it. For each container entry a task will be created like apply${containerName}. Task creation is done the in the project’s afterEvaluate callback: aProject.afterEvaluate((p) -\> { final MyExtension myExtension = p.getExtensions().getB…

---

<div class="post-metadata">

**Author:** ![Tomas\_Prochazka](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/tomas_prochazka/32/261_2.png) [@Tomas\_Prochazka](https://discuss.gradle.org/u/Tomas_Prochazka)\
**Post date:** [September 8, 2020, 10:27am UTC](https://discuss.gradle.org/t/callback-after-plugin-initialisation-done-and-plugin-extension-configured/37518/3 "2020-09-08T10:27:31Z")

</div>

To be more specific I need to do this

```
the<PublishingExtension>().publications.whenObjectAdded {
 ....
}

```

It is already lazy, but it needs `maven-publish` to be initialized

So if I do this:

```
plugins {
    `java-library`
    `maven-publish`
    id("com.mycompany.myplugin") version "0.9.1-SNAPSHOT"
}

```

It always fails because my plugin is initialized first.  
I will check your response if there is some way to replace `the<PublishingExtension>()` with something more lazy.

---

<div class="post-metadata">

**Author:** ![Lance](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/lance/32/787_2.png) [@Lance](https://discuss.gradle.org/u/Lance)\
**Post date:** [September 8, 2020, 12:00pm UTC](https://discuss.gradle.org/t/callback-after-plugin-initialisation-done-and-plugin-extension-configured/37518/4 "2020-09-08T12:00:54Z")

</div>

If `my-plugin` requires `maven-publish` to run before it, then `my-plugin` should apply `maven-publish` . Eg:

```gradle
public class MyPlugin implements Plugin<Project> {
    public void apply(Project project) {
        project.apply plugin: 'maven-publish'
        MyExtension extension = project.extensions.create("extension", MyExtension.class);
        project.tasks.register("myTask", MyTask.class).configure(task -> {
            Callable<String> callable = () -> extension.property
            Provider<String> provider = project.getProviders().provider(callable);
            task.getProperty().set(provider);
        });
    }
}

```

There’s no need to worry about `maven-publish` being applied twice (eg once in your plugin, and another time in the client build.gradle) as [Gradle applies plugins idempotently](https://docs.gradle.org/current/userguide/plugins.html#sec:using_plugins)

---

<div class="post-metadata">

**Author:** ![Tomas\_Prochazka](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/tomas_prochazka/32/261_2.png) [@Tomas\_Prochazka](https://discuss.gradle.org/u/Tomas_Prochazka)\
**Post date:** [September 8, 2020, 12:06pm UTC](https://discuss.gradle.org/t/callback-after-plugin-initialisation-done-and-plugin-extension-configured/37518/5 "2020-09-08T12:06:18Z")

</div>

Thanks! I will do it this way.  
But what about if this dependency is optional?  
I mean that my plugin can cooperate with another plugin only if it is available?  
I can simply check the existence of `PublishingExtension`, but I cannot be sure because I don’t know the order of initialization.

---

<div class="post-metadata">

**Author:** ![Lance](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/lance/32/787_2.png) [@Lance](https://discuss.gradle.org/u/Lance)\
**Post date:** [September 8, 2020, 12:10pm UTC](https://discuss.gradle.org/t/callback-after-plugin-initialisation-done-and-plugin-extension-configured/37518/6 "2020-09-08T12:10:19Z")

</div>

[PluginContainer](https://docs.gradle.org/current/javadoc/org/gradle/api/plugins/PluginContainer.html) extends DomainObjectCollection so you can hook into this to receive an event if/when the plugin is added

```gradle
project.plugins.matching { it.class.simpleName == 'MavenPublishPlugin' }.all {
   the<PublishingExtension>().publications.whenObjectAdded { .... }
}

```

If maven-publish is never added to the project, the `all {...}` closure will never execute

---

<div class="post-metadata">

**Author:** ![Tomas\_Prochazka](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/tomas_prochazka/32/261_2.png) [@Tomas\_Prochazka](https://discuss.gradle.org/u/Tomas_Prochazka)\
**Post date:** [September 8, 2020, 12:43pm UTC](https://discuss.gradle.org/t/callback-after-plugin-initialisation-done-and-plugin-extension-configured/37518/7 "2020-09-08T12:43:28Z")

</div>

Thanks a lot!  
You saved my day.  
It is even better. I meantime tried to use this (in Kotlin DSL)

```
project.plugins.whenPluginAdded {
    if (it::class.simpleName == "MavenPublishPlugin") {            
         ....
    }
}

```

but for some reason, this doesn’t work.

But this yes:  
`project.matching { it::class.simpleName == "MavenPublishPlugin" }.all {}`

---

<div class="post-metadata">

**Author:** ![Lance](https://sea1.discourse-cdn.com/gradle/user_avatar/discuss.gradle.org/lance/32/787_2.png) [@Lance](https://discuss.gradle.org/u/Lance)\
**Post date:** [September 8, 2020, 1:19pm UTC](https://discuss.gradle.org/t/callback-after-plugin-initialisation-done-and-plugin-extension-configured/37518/8 "2020-09-08T13:19:26Z")

</div>

If you look at the [javadocs for DomainObjectCollection](https://docs.gradle.org/current/javadoc/org/gradle/api/DomainObjectCollection.html)

> void all​(Closure) - Executes the given closure against all objects in this collection, and any objects subsequently added to this collection.

And

> void whenObjectAdded​(Closure) - Adds a closure to be called when an object is added to this collection

With `whenObjectAdded`, ordering is important (I think). If you attach a `whenObjectAdded` listener after the object was added to the collection, you won’t get events for these objects (I think) and will only get notified for subsequent additions. With `all` and `matching` the order is not important (you always get the event)
