Brand new in 2.3 pluginManager.withPlugin is broken

The new PluginManager’s ‘withPlugin’ method is completely broken. My understanding is that ‘pluginManager.withPlugin’ should be considered a replacement for ‘plugins.withId’. Unfortunately, while it waits until the plugin’s apply statement is called, it does not wait until the ‘apply()’ method of the plugin exeutes.

You can see this in the following example:

println 'Before withPlugin.'
pluginManager.withPlugin('java') {
 println 'Plugin was applied.'
 println project.tasks['jar'].name
}
println 'After withPlugin'
  println 'Before apply plugin'
pluginManager.apply('java')
println 'After apply plugin'

If/when you file a Jira, I have a zip of a project showing that the apply method is never called.

This is the intended behavior. If you require that the plugin’s ‘apply()’ method be executed prior to your configuration closure then you should continue to use the ‘PluginContainer.withId()’ method. This new interface was primarily added to support new rules based plugins that are conditionally evaluated. Therefore it made sense to add a new plugin interface which could be used to add listeners that were called upon application of a plugin, not necessarily evaluation of that plugin.

Considering there was never a distinction between application and evaluation in the past, this should be more clear in the docs. Without that context the release notes and [DSL ref](https://gradle.org/docs/current/dsl/org.gradle.api.plugins.PluginManager.html#org.gradle.api.plugins.PluginManager:withPlugin(java.lang.String, org.gradle.api.Action)) seem to merely imply a replacement (with some improved behavior) for the old ‘plugins.withId’.

Can you clarify the reason for the distinction? Not being familiar with the new rules plugins, I’m struggling to understand what you could even use ‘withPlugin’ for if you can’t access anything the plugin provides.

Without going into too much detail, rule source plugins allow Gradle to evaluate only the parts of the configuration model necessary for any particular build. “Legacy” plugins on the other hand, have the entirety of the ‘apply()’ plugin evaluated for every project on every build during the configuration phase. The difference with rule plugins is that model elements are evaluated as they are queried. So when you say “can’t access anything the plugin provides” that is only the case for existing non-rules based plugins. Going forward, you would be able to access model elements defined by a rule source plugin using ‘withPlugin’ by placing configuration in a ‘model { }’ block.

The release notes are perhaps a bit vague and what is mean by using ‘PluginManager’ “when possible”. In this context it means when you are simply keying of the existence of the plugin.

Alright. Thanks.

We should fix this. We can make this callback fire after the plugin has been applied.

I’ve raised GRADLE-3249 for this and will push to get it fixed in 2.4.

Thanks!