Gradle apply plugin vs plugins
Asked Answered
B

1

12

I have a simple plugin with greet task doing some 'Hello World' print.

plugins {
    id 'java-gradle-plugin'
    id 'groovy'
    id 'maven-publish'
}

group = 'standalone.plugin2.greeting'
version = '1.0'

gradlePlugin {
    plugins {
        greeting {
            id = 'standalone.plugin2.greeting'
            implementationClass = 'standalone.plugin2.StandalonePlugin2Plugin'    
        }
    }
}

publishing {
    publications {
        maven(MavenPublication) {
            groupId = 'standalone.plugin2.greeting'
            version = '1.0'
            from components.java
        }
    }
}

Now, I have runner application to just run the greet task

buildscript {
    repositories {
        mavenLocal()
    }
    dependencies {
        classpath 'standalone.plugin2.greeting:standalone-plugin2:1.0'
    }
}

apply plugin: 'standalone.plugin2.greeting'

With apply plugin notation it works OK, but when I use plugins notation instead like this:

plugins {
    id 'standalone.plugin2.greeting' version '1.0'
}

it doesn't work.

The error message is:

* What went wrong:
Plugin [id: 'standalone.plugin2.greeting', version: '1.0'] was not found in any of the following sources:

- Gradle Core Plugins (plugin is not in 'org.gradle' namespace)
- Plugin Repositories (could not resolve plugin artifact 'standalone.plugin2.greeting:standalone.plugin2.greeting.gradle.plugin:1.0')
  Searched in the following repositories:
    Gradle Central Plugin Repository

What is the difference? According to documentation apply plugin is old and should not be used.

Bemuse answered 7/7, 2020 at 9:25 Comment(0)
M
13

Before the introduction of the plugins block, plugin dependencies had to be resolved in the same way as regular project dependencies using a combination of repositories and dependencies. Since they need to be resolved before running the actual build script, they need to be defined in the special buildscript block:

buildscript {
    repositories {
        // define repositories for build script dependencies
    }
    dependencies {
        // define build script dependencies (a.k.a. plugins)
    }
}

repositories {
    // define repositories for regular project dependencies
}

dependencies {
    // define regular project dependencies
}

Once the dependencies were resolved, they could be applied using apply plugin:.

By default, the new plugins block just resolves the plugins from the Gradle Plugin Repository. This is a regular Maven repository, so it can be used using the old way, too:

buildscript {
    repositories {
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
}

In your case, the plugin only exists in mavenLocal, so the plugins block cannot resolve it, as it only looks into the Gradle Central Plugin Repository. You may use the pluginManagement block to resolve plugins from custom repositories.

As described in the article linked above, it is necessary to create a link between the plugin identifier (used inside the plugins block) and the Maven coordinates that provide the respective plugin. To create this link a marker artifact following a specific convention must be published. The Gradle Plugin Development Plugin automatically publishes this marker artifact if used in combination with the Maven Publish Plugin.

Musick answered 7/7, 2020 at 10:31 Comment(8)
A made a pluginManagement in the settings.gradle, and now my plugin is resolved, but task greet is not found. I guess I'll stick with apply plugin then.Bemuse
Could you please elaborate on how to properly declare the mavenLocal() repository in order for a plugin to be resolved in the plugins section? I have the same issue and I couldn't solve it with pluginManagement.Kaule
@SashaShpota Could you create another question with the code you tried and the issues you encountered?Bunsen
@LukasKörfer the problem is exactly the same as OP describes it (with apply it works, with id "plugin-d" it does not). You suggest to use pluginManagement, but it deson't work in my case. Could you please elaborate on this?Kaule
@SashaShpota The problem is, that without any code of what you tried so far, I can only take a guess. If this would be your own question, I would recommend you to edit the question to include the code involving pluginManagement and the code how your plugin is published. But it is not your question, so you should not edit it, as it could confuse future readers. Now the only way to get a look at your code is a new question (linking to this one).Bunsen
@SashaShpota To actually take a guess: Do you use the java-gradle-plugin plugin for your plugin project? If not, you need to manually publish plugin marker artifacts to create a link between your plugin identifier (used inside the plugins block) and the actual artifact that should be resolved from the Maven repositories.Bunsen
I do use java-gradle-plugin. I publish the plugin to maven local via ./gradlew install and use the plugin in a different project. The problem is that it works with apply, but it doesn't work with the plugins {...} declaration.Kaule
@SashaShpota The maven plugin (that creates the install task) is deprecated and should not be used. Use the maven-publish plugin instead, as it will be configured by the java-gradle-plugin plugin. You may then call gradle publishToMavenLocal to publish your plugin and it should automatically publish the marker artifact. If you encounter any additional problems, please open a new question.Bunsen

© 2022 - 2024 — McMap. All rights reserved.