Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Third-party plugins cannot be applied by ID from external build scripts #1262

Open
bmuschko opened this issue Jan 27, 2017 · 27 comments
Open

Third-party plugins cannot be applied by ID from external build scripts #1262

bmuschko opened this issue Jan 27, 2017 · 27 comments

Comments

@bmuschko
Copy link
Contributor

@bmuschko bmuschko commented Jan 27, 2017

Original issue: https://issues.gradle.org/browse/GRADLE-2136

Expected Behavior

An external plugin can be applied in a script plugin by ID. The plugin can be added to the build script's classpath and applied with the plugins DSL or the buildscript block.

Current Behavior

An external plugin can only be applied in a script plugin by type. If applied in a script plugin an exception is thrown saying that the plugin cannot be found.

* What went wrong:
A problem occurred evaluating script.
> Plugin with id 'com.bmuschko.tomcat' not found.

Context

This is an unnecessary limitation of Gradle's plugin system. Users run into the issue all the time. The limitation is not documented.

Steps to Reproduce (for bugs)

build.gradle:

apply from: 'script.gradle'

script.gradle:

buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        classpath 'com.bmuschko:gradle-tomcat-plugin:2.2.5'
    }
}

apply plugin: 'com.bmuschko.tomcat'

Another manifestation:

//build.gradle
buildscript {
  repositories { ... }
  dependencies {
    classpath "org._10ne.gradle:rest-gradle-plugin:0.4.2" //any external plugin can be used
  }
}

apply plugin: "org.tenne.rest"

task fromMain(type: org._10ne.gradle.rest.RestTask) { //works fine
  //...
}

apply from: 'gradle/other.gradle'
//other.gradle
task fromOther(type: org._10ne.gradle.rest.RestTask) { //fails
  //...
}
FAILURE: Build failed with an exception.

* Where:
Script '/tmp/plugin-class-other-script/gradle/other.gradle' line: 1

* What went wrong:
A problem occurred evaluating script.
> Could not get unknown property 'org' for root project 'plugin-class-other-script' of type org.gradle.api.Project.
@ghale
Copy link
Member

@ghale ghale commented Jan 27, 2017

Big +1 to this. Another (related) place where this is an issue is init scripts.

@pioterj
Copy link
Member

@pioterj pioterj commented Mar 7, 2017

I think that rather than fixing this issue we should address remaining gaps and un-incubate new plugin DSL. As a part of that we should allow the plugins block in all script types including script plugins.

@bmuschko
Copy link
Contributor Author

@bmuschko bmuschko commented Mar 7, 2017

@pioterj That would be another option. The buildscript is just one example. The same is true for the plugin DSL. We'd also need to lift some additional limitation the plugin DSL still has e.g. the ability to be applied in subprojects or allprojects - a common use case how script plugins are applied.

@pioterj
Copy link
Member

@pioterj pioterj commented Mar 7, 2017

We'd also need to lift some additional limitation the plugin DSL still has

Yes, that's what I meant by addressing the remaining gaps.

e.g. the ability to be applied in subprojects or allprojects

This is already available.

@BrainStone
Copy link

@BrainStone BrainStone commented Jun 23, 2017

Having this fixed would be highly appreciated!

@szpak
Copy link
Contributor

@szpak szpak commented Jun 24, 2017

Probably the same root cause as #1894 (Unable to refer classes from extenal plugins in other *.gradle files).

@bzon
Copy link

@bzon bzon commented Oct 5, 2017

Is there any update for this? I'm trying to use the OWASP dependency check plugin in an external gradle script because we have hundreds of repositories and we don't want to include it in all the build.gradle files in each repo.

This is the plugin - https://github.com/jeremylong/dependency-check-gradle

I'm getting this when the following is added to an external gradle script.

external-script.gradle:

buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath "org.owasp:dependency-check-gradle:2.1.1"
    }
}

allprojects {
    apply plugin: 'org.owasp.dependencycheck'
}

Error:

* What went wrong:
A problem occurred evaluating script.
> Plugin with id 'org.owasp.dependencycheck' not found.
@yetanotherion
Copy link

@yetanotherion yetanotherion commented Nov 29, 2017

@bzon your issue may be fixed by putting

apply plugin: org.owasp.dependencycheck.gradle.DependencyCheckPlugin

Instead of

apply plugin: 'org.owasp.dependencycheck'

https://github.com/jeremylong/dependency-check-gradle/blob/master/src/main/resources/META-INF/gradle-plugins/org.owasp.dependencycheck.properties

@mesibo
Copy link

@mesibo mesibo commented Dec 19, 2017

Any update on this issue. Fixing this issue will help maintain organization wide gradle files which can be directly imported (apply from) into new projects.

@emersonf
Copy link

@emersonf emersonf commented Mar 5, 2018

Any update on the status of this?

@wilkinsona have you seen this before? I tried to put dependencyManagement in a build script shared by multiple microservices projects via apply from:, but io.spring.dependency-management then doesn't resolve.

@bric3
Copy link

@bric3 bric3 commented Mar 21, 2018

Following a discussion on twitter with @melix on how to improve error message, in this case that the plugin with id cannot be found :

problem configuring root project 'edited'
…
Caused by: org.gradle.api.plugins.UnknownPluginException: Plugin with id 'org.springframework.boot' not found.

I propose the exception message suggest possible reasons for the error to happen, in this case one of the reason is this issue. Gradle could fail with a message like this (à la Mockito)

Plugin with id 'org.springframework.boot' not found.

This can happen for (but not limited to) the following reason :
  - There's a typo in the plugin id
  - The plugin id changed, make sure the plugin id is correct on https://plugins.gradle.org/
  - Gradle cannot use plugin ID with external (shared) build scripts. => https://github.com/gradle/gradle/issues/1262
  - Gradle cannot use plugin ID from initscript => https://github.com/gradle/gradle/issues/1322

Also in this regard the website https://plugins.gradle.org/ could link to these issues where the plugin id cannot be used. Also it could be useful to also describe the way to apply a plugin with the class (with a warning of course).

@Vampire
Copy link
Contributor

@Vampire Vampire commented Apr 11, 2018

The same is also true for settings.gradle.
I reported this at https://discuss.gradle.org/t/applying-a-plugin-by-alias-to-settings-gradle/7387 and also provided a self-contained example.
@breskeby started to look at it, but unfortunately at some point in time stopped responding completely

@italobb
Copy link

@italobb italobb commented Apr 18, 2018

@emersonf Instead of :

apply plugin: 'io.spring.dependency-management'

use

apply plugin: io.spring.gradle.dependencymanagement.DependencyManagementPlugin

You need to refer to the implementation-class when you're applying a plugin using an external script.

@voddan
Copy link

@voddan voddan commented Aug 8, 2018

Looks like this bug is not going to be fixed for a while.

Can we at least improve the error message? Something like:

Plugin with id 'io.spring.dependency-management' not found. 
If in external script pluginn, try refering to it by its class name `io.spring.gradle.dependencymanagement.DependencyManagementPlugin`
@guenhter
Copy link
Contributor

@guenhter guenhter commented Aug 28, 2018

Really looking forward to see this fixed. Took two hours of my time today...

@Bluexin
Copy link

@Bluexin Bluexin commented Oct 19, 2018

We'd also need to lift some additional limitation the plugin DSL still has

Yes, that's what I meant by addressing the remaining gaps.

e.g. the ability to be applied in subprojects or allprojects

This is already available.

So I know this is fairly old, but I've ran into issues trying to use the plugin DSL in allprojects/subprojects with Kotlin build scripts :

* What went wrong:
The plugins {} block must not be used here. If you need to apply a plugin imperatively, please use apply<PluginType>() or apply(plugin = "id") instead.
> The plugins {} block must not be used here. If you need to apply a plugin imperatively, please use apply<PluginType>() or apply(plugin = "id") instead.

Using

------------------------------------------------------------
Gradle 4.10.2
------------------------------------------------------------

Build time:   2018-09-19 18:10:15 UTC
Revision:     b4d8d5d170bb4ba516e88d7fe5647e2323d791dd

Kotlin DSL:   1.0-rc-6
Kotlin:       1.2.61
Groovy:       2.4.15
Ant:          Apache Ant(TM) version 1.9.11 compiled on March 23 2018
JVM:          1.8.0_181 (Eclipse OpenJ9 openj9-0.9.0)
OS:           Windows 10 10.0 amd64

Should I make a separate issue for it on the kotlin dsl repo?

zeshanarifios pushed a commit to zeshanarifios/edx-app-ios that referenced this issue Oct 30, 2018
@MarkRx
Copy link

@MarkRx MarkRx commented Apr 25, 2019

@haianhsing each buildscript uses its own classloader and cannot see plugins from peer scripts. See #1370. Additionally scripts applied from other scripts should apply plugins using the fully qualified classname though I don't remember the reason.

You need to put those two plugin applications in the same gradle script file. It might even work if one is in the project build script and the other in an applied script I don't remember.

@haianhsing
Copy link

@haianhsing haianhsing commented Apr 26, 2019

@MarkRx Thanks for your answer! I know that Additionally scripts applied from other scripts should apply plugins using the fully qualified classname , but I don't know what is the full qualified classname of com.android.library. That is the problem.

The shared-build script is the common script and it include a lot of duplication of work. In addition, some other scripts apply it. So, put them in the same script is not the best way. Maybe there are some better solutions?

@nlwillia
Copy link

@nlwillia nlwillia commented Apr 26, 2019

@haianhsing It's possible to centralize resolution with pluginManagement, but it can be difficult to setup. For an example, take a look at this experiment. (Feel free to log an issue in that project if you have questions about what it's doing.)

@haianhsing
Copy link

@haianhsing haianhsing commented Apr 26, 2019

@nlwillia Finally, I find that running gradle moduleName:taskName in project dir works. But I don't know what is the difference of running gradle taskName in module dir.

@ahakanbaba
Copy link

@ahakanbaba ahakanbaba commented May 31, 2019

Using the implementation-class did not work work for me:

script.gradle:


buildscript {
  repositories {
    maven {
      url "https://plugins.gradle.org/m2/"
    }
  }
  dependencies {
    classpath "gradle.plugin.cz.alenkacz:gradle-scalafmt:1.8.0"
  }
}

allprojects {
   apply plugin: "cz.alenkacz.gradle.scalafmt.ScalafmtPlugin"
}

I still get the

A problem occurred evaluating script.
> Plugin with id 'cz.alenkacz.gradle.scalafmt.ScalafmtPlugin' not found.

Error.

The implementation-class is defined here and I think I am using it correctly.

$ ./gradlew --version

------------------------------------------------------------
Gradle 4.10.3
------------------------------------------------------------

Build time:   2018-12-05 00:50:54 UTC
Revision:     e76905e3a1034e6f724566aeb985621347ff43bc

Kotlin DSL:   1.0-rc-6
Kotlin:       1.2.61
Groovy:       2.4.15
Ant:          Apache Ant(TM) version 1.9.11 compiled on March 23 2018
JVM:          1.8.0_192 (Oracle Corporation 25.192-b12)
OS:           Mac OS X 10.13.6 x86_64
@ahakanbaba
Copy link

@ahakanbaba ahakanbaba commented May 31, 2019

Using the implementation-class did not work work for me:

script.gradle:


buildscript {
  repositories {
    maven {
      url "https://plugins.gradle.org/m2/"
    }
  }
  dependencies {
    classpath "gradle.plugin.cz.alenkacz:gradle-scalafmt:1.8.0"
  }
}

allprojects {
   apply plugin: "cz.alenkacz.gradle.scalafmt.ScalafmtPlugin"
}

I still get the

A problem occurred evaluating script.
> Plugin with id 'cz.alenkacz.gradle.scalafmt.ScalafmtPlugin' not found.

Error.

The implementation-class is defined here and I think I am using it correctly.

$ ./gradlew --version

------------------------------------------------------------
Gradle 4.10.3
------------------------------------------------------------

Build time:   2018-12-05 00:50:54 UTC
Revision:     e76905e3a1034e6f724566aeb985621347ff43bc

Kotlin DSL:   1.0-rc-6
Kotlin:       1.2.61
Groovy:       2.4.15
Ant:          Apache Ant(TM) version 1.9.11 compiled on March 23 2018
JVM:          1.8.0_192 (Oracle Corporation 25.192-b12)
OS:           Mac OS X 10.13.6 x86_64

Ohh my. I had to drop the quotes. This was very subtle.

The following script.gradle works fine:

 buildscript {
   repositories {
     maven {
       url "https://plugins.gradle.org/m2/"
     }
   }
   dependencies {
     classpath "cz.alenkacz:gradle-scalafmt:1.8.0"
   }
 }

 apply plugin: cz.alenkacz.gradle.scalafmt.ScalafmtPlugin

Note that the apply plugin: is not followed by a quoted string but by a literal.

lhotari added a commit to lhotari/asciidoctor-gradle-plugin that referenced this issue May 31, 2019
- Use fully qualified class name when applying plugin to
  workaround gradle/gradle#1262
lhotari added a commit to lhotari/gradle that referenced this issue Jun 1, 2019
Signed-off-by: Lari Hotari <lari@hotari.net>
lhotari added a commit to lhotari/gradle that referenced this issue Jun 1, 2019
…by id

Signed-off-by: Lari Hotari <lari@hotari.net>
@Vampire
Copy link
Contributor

@Vampire Vampire commented Jun 12, 2019

Note that the apply plugin: is not followed by a quoted string but by a literal.

@ahakanbaba not really, it can be followed by both.
If it is followed by a string, that string has to be the ID of the plugin.
If it is followed by a class (doesn't matter whether fully-qualified or whether you use an import) that plugin class is applied.

lhotari added a commit to lhotari/gradle that referenced this issue Jul 31, 2019
Signed-off-by: Lari Hotari <lari@hotari.net>
lhotari added a commit to lhotari/gradle that referenced this issue Jul 31, 2019
…by id

Signed-off-by: Lari Hotari <lari@hotari.net>
lhotari added a commit to lhotari/gradle that referenced this issue Aug 27, 2019
Signed-off-by: Lari Hotari <lari@hotari.net>
lhotari added a commit to lhotari/gradle that referenced this issue Aug 27, 2019
…by id

Signed-off-by: Lari Hotari <lari@hotari.net>
lhotari added a commit to lhotari/gradle that referenced this issue Sep 6, 2019
Signed-off-by: Lari Hotari <lari@hotari.net>
lhotari added a commit to lhotari/gradle that referenced this issue Sep 6, 2019
…by id

Signed-off-by: Lari Hotari <lari@hotari.net>
lhotari added a commit to lhotari/gradle that referenced this issue Sep 15, 2019
Signed-off-by: Lari Hotari <lari@hotari.net>
lhotari added a commit to lhotari/gradle that referenced this issue Sep 15, 2019
…by id

Signed-off-by: Lari Hotari <lari@hotari.net>
@jjohannes
Copy link
Member

@jjohannes jjohannes commented Sep 30, 2020

Note that it is now recommended to use the plugins {} DSL and pre-compiled script plugin (convention plugins) in buildSrc where this all works well.

Example: https://docs.gradle.org/6.7-rc-2/samples/sample_convention_plugins.html

@jjohannes jjohannes removed the a:bug label Sep 30, 2020
@Vampire
Copy link
Contributor

@Vampire Vampire commented Sep 30, 2020

But that doesn't make this issue less a bug, does it?
And even more specifically, can you tell me how I use the plugins block, or even a buildSrc class in the settings script? ;-) [#1262 (comment)]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet