Using plugin manager vs plugin container in java plugin

Hi,

In my code I am applying a 3rd party plugin using this syntax:

SpotlessPlugin spotless = project.getPlugins().apply(SpotlessPlugin.class);
spotless.getExtension().java(JavaExtension::removeUnusedImports);
spotless.getExtension().java(j -> j.googleJavaFormat("1.7"));
spotless.getExtension().java(j -> j.targetExclude("build/**"));

However, in the documentation for project.getPlugins() I see that its says:

While not deprecated, it is preferred to use the methods of this interface or the plugin manager than use the plugin container.

Use one of the ‘apply’ methods on this interface or on the plugin manager to apply plugins instead of applying via the plugin container.

Use PluginManager.hasPlugin(String) or similar to query for the application of plugins instead of doing so via the plugin container.

But I see that project.getPluginManager().apply (PluginManager (Gradle API 8.4)) the method returns void so I am not sure how I can configure the plugin after applying it like I am doing in the current code.

I guess I am asking 2 questions:

  1. Is there a way to use pluginManager (the recommended way) and then configure the plugin I applied?
  2. Why plugin.getPlugins() (that returns PluginContainer) is discouraged and not recommended like PluginManager?
1 Like

Very good question, I am facing the same dilemma.

If we should be using project.getPluginManager().apply(Class) instead of project.getPlugins().apply(Class), then why does the plugin manager return void instead of the plugin instance? (We can of course then make a subsequent project.getPlugins().getPlugin(Class) call to get the instance, but that’s just more code and we end up using the PluginContainer after all.)

Well, the answer is easy, use the recommended approach, that is with pluginManager and do not at all refer to the plugin instance.
Plugin instances are never meant to be accessed by 3rd party code.
Plugins register tasks and extensions and those are what you configure.

So using OP example the proper way would be more like

project.getPluginManager().apply(SpotlessPlugin.class);
Object spotlessExtensionAsObject = project.getExtensions().findByName("spotless");
if (!(spotlessExtensionAsObject instanceof SpotlessExtension)) {
    throw new IllegalStateException("spotless extension does not have expected type");
}
SpotlessExtension spotlessExtension = ((SpotlessExtension) spotlessExtensionAsObject);
spotlessExtension.java(JavaExtension::removeUnusedImports);
spotlessExtension.java(j -> j.googleJavaFormat("1.7"));
spotlessExtension.java(j -> j.targetExclude("build/**"));