1 year ago

#352601

test-img

Hauke

Gradle Plugin with dependencies

I am kind of new in developing plugins for gradle but I finally figured out how to create a gradle plugin with java and use that plugin inside a different gradle project.

The next step was to add a dependency to my gradle project but as soon as I try to use that plugin, I get an error unable to load class xyz

Here is what I did so far

build.gradle of the plugin project

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

compileJava.options.encoding = 'UTF-8'
sourceCompatibility = 17

group 'de.mycompany.gradle.plugin'
version '1.0.34'

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1'
    implementation 'com.google.guava:guava:30.1.1-jre'
    implementation gradleApi()
    implementation 'commons-io:commons-io:2.11.0'
    implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.1'
    implementation 'org.apache.commons:commons-lang3:3.12.0'

}

repositories {
    mavenLocal()
    mavenCentral()
    maven {
        url "http://172.20.9.171:8081/repository/mainrepository/"
        allowInsecureProtocol = true
    }
}


publishing {
    publications {
        maven(MavenPublication) {
            artifact("build/libs/mycompany-gradle-plugin-$version" + ".jar") {
                extension "jar"
            }
        }
    }
    repositories {
        maven {
            name "nexus"
            url "http://cs-nexus:8081/repository/release/"
            allowInsecureProtocol = true
            credentials {
                username "user"
                password "password"
            }
        }
    }
}

gradlePlugin {
    plugins {
        simplePlugin {
            id = 'mycompany-gradle-plugin'
            implementationClass = 'de.mycompany.gradle.plugin.JIRAReleaseNotesPlugin'
        }
    }
}

here is the JIRARelaseNotesPlugin

public class JIRAReleaseNotesPlugin implements Plugin<Project> {
    @Override
    public void apply(Project project) {
        project.getTasks().register("jira", JIRAReleaseNotesTask.class, task -> {
        });
    }
}

and the JIRAReleaseNotesTask class


public class JIRAReleaseNotesTask extends DefaultTask {

    @Input
    private String destinationFile = "releasenotes.json";

    @Input
    private String jql = "project = Testing and status = done";

    @TaskAction
    public void createReleaseNotes() {
        try {
           // call JIRA, find issues, convert them into the releasenotes.json file
        } catch (IOException e) {
            System.out.println(ExceptionUtils.getStackTrace(e));
        }
    }

    public String getDestinationFile() {
        return destinationFile;
    }

    public void setDestinationFile(String destinationFile) {
        this.destinationFile = destinationFile;
    }

    public String getJql() {
        return jql;
    }

    public void setJql(String jql) {
        this.jql = jql;
    }
}

The build.gradle file from my testing project looks like this:

plugins {
    id 'application'
    id 'maven-publish'
    id 'mycompany-gradle-plugin' version '1.0.33'
}

compileJava.options.encoding = 'UTF-8'
sourceCompatibility = 17

group 'de.mycompany.testing'
version '1.0.0'

dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1'
    implementation 'com.google.guava:guava:30.1.1-jre'
    implementation 'de.mycompany.gradle.plugin:mycompany-gradle-plugin-shared:1.0.50'
}

jira {
    destinationFile = 'src/main/java/de/mycompany/whatsnew.xml'
    jql = 'project = SOMEPROJECT and status = DONE'
}

repositories {
    mavenLocal()
    mavenCentral()
    maven {
        url "http://172.20.9.171:8081/repository/mainrepository/"
        allowInsecureProtocol = true
    }
}

Problem 1 - Unable to load class

As soon as I run gradle jira I get this error

Unable to load class 'com.fasterxml.jackson.databind.ObjectMapper'.

I guess the problem is, that the testing project does not know which dependency the plugin needs. I also tried to add the dependencies to the testing project but without any luck. Do I need to create a fat jar or something like that for my plugin?

Problem 2 - publishing is kind of wired

I have also some issues with the publishing process of the plugin to our nexus repository. I found out a solution, but that is just a work-a-round and I am wondering, what causes this issue.

If I call gradle clean jar publish the artifact will be published to nexus but I don't know why gradle tries to publish it twice

> Task :clean
> Task :mycompany-gradle-plugin-shared:clean
> Task :compileJava
> Task :pluginDescriptors
> Task :processResources
> Task :classes
> Task :jar
> Task :mycompany-gradle-plugin-shared:compileJava
> Task :mycompany-gradle-plugin-shared:processResources NO-SOURCE
> Task :mycompany-gradle-plugin-shared:classes
> Task :mycompany-gradle-plugin-shared:jar
> Task :generatePomFileForMavenPublication

> Task :publishMavenPublicationToNexusRepository
Execution optimizations have been disabled for task ':publishMavenPublicationToNexusRepository' to ensure correctness due to the following reasons:
  - Gradle detected a problem with the following location: 'C:\dev\git\mycompany-gradle-plugin\build\libs\mycompany-gradle-plugin-1.0.35.jar'. Reason: Task ':publishMavenPublicationToNexusRepository' uses this output of task ':jar' without declaring an explicit or implicit dependency. This can lead to incorrect results being produced, depending on what order the tasks are executed. Please refer to https://docs.gradle.org/7.2/userguide/validation_problems.html#implicit_dependency for more details about this problem.
Cannot upload checksum for module-maven-metadata.xml because the remote repository doesn't support SHA-256. This will not fail the build.
Cannot upload checksum for module-maven-metadata.xml because the remote repository doesn't support SHA-512. This will not fail the build.

> Task :generateMetadataFileForPluginMavenPublication
> Task :generatePomFileForPluginMavenPublication

> Task :publishPluginMavenPublicationToNexusRepository FAILED
Multiple publications with coordinates 'de.mycompany.gradle.plugin:mycompany-gradle-plugin:1.0.35' are published to repository 'nexus'. The publications will overwrite each other!

I use the publish plugin in other projects without any problems.

Anyways this command publishes the artifact to nexus but I also need to call gradle publishSimplePluginPluginMarkerMavenPublicationToNexusRepository in order to publish the plugin reference project to nexus.

That is kind of strange behavior and if I just use publishSimplePluginPluginMarkerMavenPublicationToNexusRepository instead of publish only the reference artifact will be uploaded but not the actual JAR artifact.

Like I said, I found a work-a-round for me, but maybe someone can give me some advice.

Thanks a lot and stay safe everyone!

java

gradle

gradle-plugin

0 Answers

Your Answer

Accepted video resources