Is it possible to mix binary and precompiled script plugins in same build logic project?

I’m able to apply one precompiled script plugin to another in the same build-logic/buildSrc project. Per the docs, sometimes a binary plugin is the better choice, but I can’t seem to apply a binary plugin to a precompiled script plugin in the same build logic project. I get a “Plugin not found” error:

> Task :build-logic:generatePrecompiledScriptPluginAccessors
Failed to generate type-safe Gradle model accessors for the following precompiled script plugins:
 - src/main/kotlin/org.sdkotlin.buildlogic.kotlin-project.gradle.kts

org.gradle.internal.exceptions.LocationAwareException: Precompiled script plugin '/Users/ibrandt/Development/SDKotlin/sd-kotlin-talks/build-logic/src/main/kotlin/org.sdkotlin.buildlogic.kotlin-project.gradle.kts' line: 1
Plugin [id: 'org.sdkotlin.buildlogic.greeting'] was not found in any of the following sources:

- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
- Plugin Repositories (plugin dependency must include a version number for this source)
	at org.gradle.plugin.use.internal.DefaultPluginRequestApplicator.resolveToFoundResult(DefaultPluginRequestApplicator.java:239)

The docs show how to apply external plugins in precompiled script plugins. Is it not possible to do the same for a local binary plugin, or is there something wrong with my attempt?

Is it possible to apply a local precompiled script plugin in a local binary plugin?

If you want to apply a binary plugin from the same build in a precompiled script plugin, use its class, not its ID.
To use its ID, you would need to separate the binary plugin out into another build that you then include, then you could use the ID.

Thanks for the reply. Since as I understand it only Strings are supported, I tried specifying the fully qualified name of the class as the ID in the plugins block like so:

plugins {
    id("org.sdkotlin.buildlogic.GreetingPlugin")
}

This still gives me a “Plugin [id: ‘org.sdkotlin.buildlogic.GreetingPlugin’] was not found” error.

I then tried applying the plugin in the body of the script plugin like so:

import org.sdkotlin.buildlogic.GreetingPlugin
...
apply(GreetingPlugin::class.java)

The script plugin compiles now, but when I later try to apply it I get:

An exception occurred applying plugin request [id: 'org.sdkotlin.buildlogic.kotlin-project']
> Failed to apply plugin 'org.sdkotlin.buildlogic.kotlin-project'.
   > Cannot convert the provided notation to a File or URI: class org.sdkotlin.buildlogic.GreetingPlugin.
     The following types/formats are supported:
       - A String or CharSequence path, for example 'src/main/java' or '/usr/include'.
       - A String or CharSequence URI, for example 'file:/usr/include'.
       - A File instance.
       - A Path instance.
       - A Directory instance.
       - A RegularFile instance.
       - A URI or URL instance.
       - A TextResource instance.

Of course you cannot use an FQCN as plugin ID, that doesn’t make any sense at all.

Your second approach is almost it, though not fully, as the error tells you, so just use the right apply method.
You are using Kotlin DSL for a reason, it provides amazing IDE support and completion so use it.
What you call is fun PluginAware.apply(from: Any? = null, plugin: String? = null, to: Any? = null) so it is like apply(from = GreetingPlugin::class.java) which is how you apply a script plugin and would need the script plugin as argument as the error tells you.
What you intended to do is apply<GreetingPlugin>().

Thanks, apply<GreetingPlugin>() did the trick.

This may not be the proper place to debate this, but I’ve seen it mentioned before, and I’m not sure IDE code completion is as helpful to those not already well versed in the Gradle API and Kotlin DSL as one who is might think. In this instance, code completion in the latest 2022.3 version of IntelliJ Ultimate hints nothing at the option of supplying a plugin class as a reified type parameter:

That said, examples of this syntax are in the documentation multiple times:

https://docs.gradle.org/current/userguide/plugins.html#sec:applying_binary_plugins
https://docs.gradle.org/current/userguide/custom_plugins.html#sec:writing_a_simple_plugin

I just didn’t catch those examples, so that’s my bad.

It does for me in 2022.2.3 with Kotlin plugin 222-1.7.21-release.272.IJ4167.29:

Maybe you should report a bug to somewhere if it does not work for you.

It could be that I coincidentally already did:

https://youtrack.jetbrains.com/issue/KTIJ-23703/2022.3-RC-Import-intention-not-offered-in-Gradle-binary-plugin#focus=Comments-27-6690324.0-0.

I’ll file another one if that fix doesn’t cover this issue.