I am working with a multi-module Gradle project I don’t control. It follows the preferred structure:
rootProject/
|-buildSrc
|-subprojectA
|-subprojectB
...
|-subprojectN
Most of the subprojects use custom plugins from buildSrc/. In the buildSrc/build.gradle.kts, dependency declarations are:
// buildSrc/build.gradle.kts
...
dependencies {
implementation("com.google.protobuf:protobuf-gradle-plugin:0.8.18")
// ...
}
One such custom plugin (call it, “X”) from buildSrc/ applies the Protobuf Gradle Plugin (at version 0.8.18).
Most subprojects [ A, B, etc ] in my example above apply plugin “X”.
// subprojectA/build.gradle.kts
plugins {
id("X")
// ...
}
//...
However, in my case, I want to apply an external, binary plugin (e.g. with id “com.external.Z”), to 1 of the subprojects (say, N) that also applies the Google Protobuf Plugin, but at version 0.9.5, using plugin with id “com.external.Z”, and no other plugin.
In the external plugin Z’s build.gradle.kts file, the dependencies are as follows:
dependencies {
implementation("com.google.protobuf:protobuf-gradle-plugin:0.9.5")
// ...
}
It therefore uses the configuration logic (Extensions, etc) supplied by the Google Protobuf Plugin at version 0.9.5, which is significantly different that 0.8.18.
You can safely assume plugin Z applies the Google Protobuf Plugin; for example:
class Z : Plugin<Project> {
override fun apply(project: Project) {
project.pluginManager.apply("com.google.protobuf")
// ...
}
// ...
}
I go onto modify subproject N, such that the configuration appears as:
// subprojectN/build.gradle.kts
plugins {
id("com.external.Z") version "0.1.0"
}
// ...
Again, only applies plugin Z and no other plugin, not even from the project’s buildSrc/ directory. Plugin Z was properly published to a (internal Artifactory) Maven repository that is resolvable from the root project above.
No matter what I try, the classpath determined by buildSrc/ applies to subproject’s N’s build script when resolving the Google Protobuf Plugin binary, despite subprojectN not using a single plugin from buildSrc/, or anything other plugin for that matter.
I have tried:
// subprojectN/build.gradle.kts
buildscript {
dependencies {
constraints {
classpath("com.google.protobuf:protobuf-gradle-plugin:0.9.5")
}
}
}
plugins {
id("com.external.Z") version "0.1.0"
}
// Optionally, this, though I think this only affects the configurations (classpath) of the project, not the Gradle buildscript (for subprojectN) itself
configurations.all {
resolutionStrategy.eachDependency {
if (requested.group == "com.google.protobuf" && requested.name == "protobuf-gradle-plugin") {
println("Current version of Protobuf Gradle Plugin is [${requested.version}]")
useVersion("0.9.5")
}
}
}
// ...
In all cases, I still get:
An exception occurred applying plugin request [id: 'com.external.Z, version: '0.1.0']
> Failed to apply plugin 'com.external.Z'.
> Extension of type 'ProtobufExtension' does not exist. Currently registered extension types: [ExtraPropertiesExtension, ... ]
Indeed, ProtofExtension(source) does not exist in version 0.8.18, but certainly does in 0.9.5 (source).
I know that 0.8.18 binary version for the Protobuf plugin is used in this case because I checked the Gradle build scan.
Is there any workaround, or other solution for this problem?
In the meantime, I will re-review the docs on buildSrc/ (and other related doc) in case I missed anything.
Thanks in advance.