Standalone Plugin to apply and import 3rd party plugins

Hi,

I am trying to write a standalone plugin to be used by our team, that will replace common plugin application code in different projects and will apply some preset standard configuration to those plugins, as a convention to work by.

I was successful in configuring an external 3rd party plugin I am importing, inside my plugin code, but wasn’t able to propagate that dependency to the users of my custom plugin, so it seems.

> gradlePlugin {
>   plugins {
>     javaBasePlugin {
>       id = "${project.group}.java"
>       implementationClass = "${project.group}.java.plugins.java.BasePlugin"
>     }
> }

> dependencies {
>   implementation  group: 'com.benjaminsproule.swagger', name: 'com.benjaminsproule.swagger.gradle.plugin', version: '1.0.6'
> }

When I apply my plugin, and run the build task - I get the following exception:

org.gradle.api.ProjectConfigurationException: A problem occurred configuring root project

Caused by: org.gradle.internal.event.ListenerNotificationException: Failed to notify project evaluation listener.

Caused by: java.lang.NoClassDefFoundError: com/benjaminsproule/swagger/gradleplugin/GradleSwaggerPlugin

The generated jar file indeed doesn’t contain the above dependency, but I was expecting Gradle to download it. Am I mistaken? What is the best practice here? Is there some way I can instruct Gradle to download the dependency on its own, or should I bundle the 3rd party plugin with my plugin?

How are you consuming the plugin? Generally you would publish the plugin to an artifact repository with a POM that would contain dependencies. Gradle will download the dependencies when published this way.

In addition to what @jjustinic wrote I recommend that you deploy your plugin artifact to mavenLocal() aka ~/.m2/repository/com/example/your/plugin first in order to verify that it can be applied to a sample project.

Well because I was looking into this issues recently as I understand you would like to apply 'com.benjaminsproule.swagger.gradle.plugin' in your plugin and gradle should download it immediately.

For your information if in your plugin’s module you create a build.gradle file and add dependencies there when you apply your plugin Gradle should automatically add your plugin’s dependencies as classpath dependencies in the project you applied the plugin.

Here is an example:

In your plugin’s build.gradle file add:

repositories {
    gradlePluginPortal()
    jcenter()
}

dependencies {
    compileOnly gradleApi()
    compileOnly localGroovy()
    compileOnly 'gradle.plugin.com.benjaminsproule:swagger-gradle-plugin:1.0.0'
}

This way when you apply your plugin to a project Gradle would add the above dependencies as classpath dependencies.

In your plugin you can add those:

project.apply { action: ObjectConfigurationAction ->
    action.plugin("com.benjaminsproule.swagger")
}

and then your plugin will automatically apply this plugin.

Hope it helps!!!

Thanks @jjustinic and @johnjohndoe ,
I publish the plugin as a jar to an artifact repo, and every user of the plugin applies it using the DSL.
e.g.

plugins {
id “com.acme.java” version “1.0.0”
}

But this doesn’t work, without me adding the encapsulated com.benjaminsproule.swagger directly as a plugin as well, to the above.
e.g.

plugins {
id “com.acme.java” version “1.0.0”
id “com.benjaminsproule.swagger” version “1.0.7”
}

@kostasdrakonakis
What I do in my acme plugin is this:

project.getPluginManager().apply(GradleSwaggerPlugin.class);

This should, in theory, bring the dependency as well, but it doesn’t happen.

Your dependencies section defines the swagger-gradle-plugin as compileOnly. I would think you’d put api here, for it to propagate to the users. I tried this and it didn’t work.

What am I missing?

This should, in theory, bring the dependency as well, but it doesn’t happen.

No it should not. As I have said above in your plugin’s build.gradle file you should add the dependency.
Then in your pom.xml make sure the dependency is added and then Gradle will automatically download the dependency when your plugin is applied to a project.

I would think you’d put api here, for it to propagate to the users. I tried this and it didn’t work.

You do not need api. Those dependencies will be applied as classpath dependencies in the projects that your plugin is applied. Then Gradle should be able to recognize the 3rd party plugin you want to add