Including a 3rd-party subproject with an identical plugin dependency
Asked Answered
R

2

6

I'm attempting to include a Git submodule as a subproject to my primary Gradle project, but Gradle refuses to validate the build script on the grounds that the both my project and the subproject require the same plugin ("Plugin request for plugin already on the classpath must not include a version").

Removing the plugin from the primary project isn't an option, since the tasks defined by the plugin will no longer be available to the primary build script. Nor is omitting the plugin version from the primary build script, since that's the first instance of the plugin declaration that Gradle sees (while the error is thrown on the declaration in the subproject).

Ordinarily I'd have my project patch out such an incompatibility, but since the build script doesn't validate, this obviously isn't an option. What can be done to resolve the conflict given that I have effectively no control over the subproject's build script?

Ruvolo answered 6/9, 2019 at 4:7 Comment(0)
W
7

I had a similar problem, I wanted to include a module which should also be able to be built on its own. More precise, the module which I wanted to include also declared com.github.johnrengelman.shadow for producing a runnable JAR. That resulted in two build.gradle files declaring this plugin with a version number.

The solution is to use a Composite Build. That causes the module's build to be completely separate, being able to declare plugins with any version whatsoever.

All you have to do is to add includeBuild "<pathToSubmodule>"in your root settings.gradle:

includeBuild "../submodule"

Then you can define the submodule as a normal dependency in your toplevel build.gradle:

dependencies {
    implementation 'com.mycompany:submodule:1.0-SNAPSHOT'
}
Whose answered 8/11, 2019 at 7:29 Comment(0)
S
0

A patch might still be conceivable though, as described in this thread (since it is not covered by the official Gradle documentation on plugin):

Currently, I can think of 2 “workarounds”:

1/ In your sub project, instead of applying with the plugins{} block, apply the plugin conditionally using legacy plugin application.
This is the method I used:

buildscript {
  repositories {
    maven {
      url "https://plugins.gradle.org/m2/"
    }
  }
  dependencies {
    classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.31"
  }
}

def kotlinPluginId = 'org.jetbrains.kotlin.multiplatform'
final hasPlugin = project.getPlugins().hasPlugin(kotlinPluginId);
if (hasPlugin) {
    final Plugin plugin = project.getPlugins().getPlugin(kotlinPluginId)
    println 'Plugin already applied - version ' + plugin.properties['kotlinPluginVersion']
} else {
    apply plugin: "org.jetbrains.kotlin.multiplatform"
}

OR:

2/ Create a dummy root project for the standalone project and use plugins{} block there for the sub-project. In this case the sub-project won’t have any logic to apply the plugin.

Schargel answered 6/9, 2019 at 4:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.