Applying gradle plugin to all projects

I’m returning to a project I had setup years ago and am reorienting myself with gradle. I had setup a buildSrc/src/main/groovy/java-conventions.gradle file after reading about the conventions plugins as a way to share logic with gradle projects. It worked fine but now I want to add the id 'com.github.ben-manes.versions' version '0.52.0' dependency management plugin, but I wanted it automatically applied to all gradle subprojects in this file.

However, I get errors that versions aren’t allowed in precompiled scripts, but without the version I get errors that gradle can’t find the dependency.

Is there a better place to apply this with a version? What can I do about it not being able to find the dep without the version included?

If I move the plugin id to each subprojects’s build.gradle file, it works fine both with and without the versions number.

I tried researching this problem but am not asking the right questions.

You add a dependency to the plugin in your build script of the buildSrc project.
There you define the version in the dependency and in the actual plugin you can then apply it without version.

Can you give me a little more of an example of what you mean? I’m getting back into gradle after years away and trying to ensure I understand the right terminology.

1 Like

Sure, just ask about what you did not understand or are unsure about.

Is there no way to define the plugin once for all projects, or do I inevitably need to include it in all build.gradle files?

Here is my buildSrc/build.gradle file:

plugins {
    id 'groovy-gradle-plugin'
}

repositories {
    gradlePluginPortal()
}

dependencies {
    implementation 'io.franzbecker:gradle-lombok:5.0.0'
}

Here is most of my buildSrc/src/main/java-conventions.gradle file:

plugins {
    id 'java'
    id 'checkstyle'
    id 'io.franzbecker.gradle-lombok'
}

group = project.property('group')
description = project.property('description')

targetCompatibility = sourceCompatibility = JavaVersion.VERSION_21

repositories {
    mavenCentral()

    // ... extra repos here
}

lombok {
    version = '1.18.24'
    sha256 = ''
}

def getBuildNumber = {
    // get the name of the last tag
    def tagInfo = new ByteArrayOutputStream()
    exec {
        commandLine 'git', 'describe', '--tags'
        standardOutput = tagInfo
    }
    tagInfo = tagInfo.toString()

    if (!tagInfo.contains('-')) {
        return 0
    }
    return tagInfo.split("-")[1]
}

project.ext.fullVersion = version = project.property('version') + '-b' + getBuildNumber()

and all of my subprojects include that java-conventions plugin:

plugins {
    id 'prism.java-conventions'
}

I’m having difficulty figuring out how/where I can define this id 'com.github.ben-manes.versions' plugin so that I’m not having to add it to every subproject. Each step I try either requires the version to be included otherwise it fails to find the plugin, or it says a version can’t be included due to precompiled scripts.

Is there no way to define the plugin once for all projects, or do I inevitably need to include it in all build.gradle files?

Of course there is, and I told you how.
Add a dependency on the plugin in buildSrc/build.gradle, then you can apply it without version in your convention plugin.
Just like you also did for the gradle-lombok plugin.

I think I’m not following what you mean by “apply it” in this specific context.

image

I just seem to be trying every combination that’s wrong.

In the build.gradle I’ve tried variations of id 'com.github.ben-manes.versions' version '0.52.0' as well as adding it to the dependencies array too, and then including just id 'com.github.ben-manes.versions' in the conventions file.

The error is just always some version of Could not find com.github.ben-manes.versions:0.52.0:. and Plugin with id 'com.github.ben-manes.versions' not found.

I don’t even want a version listed as latest is usually good enough but again it fails to be found without it in a simpler gradle setup.

For example, one thing I tried was:

buildSrc/build.gradle:

plugins {
    id 'groovy-gradle-plugin'
}

repositories {
    gradlePluginPortal()
}

dependencies {
    implementation 'io.franzbecker:gradle-lombok:5.0.0'
    implementation 'com.github.ben-manes.versions:0.52.0'
}

java-conventions.gradle:

plugins {
    id 'java'
    id 'checkstyle'
    id 'io.franzbecker.gradle-lombok'
    id 'com.github.ben-manes.versions'
}

...

throws the error

Execution failed for task ':buildSrc:compileJava'.
> Could not resolve all files for configuration ':buildSrc:compileClasspath'.
   > Could not find com.github.ben-manes.versions:0.52.0:.
     Required by:
         project :buildSrc

implementation ‘com.github.ben-manes.versions:0.52.0’

This means you request the artifact with group com.github.ben-manes.versions, name 0.52.0, and without version, as you can also see in the error message Could not find com.github.ben-manes.versions:0.52.0:. where the . means “no version”.

What you want is either com.github.ben-manes.versions:com.github.ben-manes.versions.gradle.plugin:0.52.0 or com.github.ben-manes:gradle-versions-plugin:0.52.0.
The former is the marker artifact that is always <plugin id>:<plugin id>.gradle.plugin:<plugin version>, the latter is the actual code artifact that the marker artifact depends on.

Ack! I knew I was screwing up something stupid. Can’t believe I forgot about that format. I use it everywhere.

1 Like

Not everywhere, for the lombok plugin you use the actual code artifact :smiley: