Locally testing annotation processors in Java projects with Gradle

Originally posted 2020-11-27

Latest update 2021-04-06

Nobody wants to publish a bunch of versions of a library to a public repository to test things out. This is especially true when working with annotation processors. Lots of time can be spent tweaking annotation processors to debug them and add features. Doing a round trip to a public repository, even something as quick as JitPack.io, can really slow you down.

Instead, you should publish the artifact to a local repo and then test from there. In order to do that you'll need to add your Maven local repo to the configuration of the project you're testing the annotation processor in like this:

repositories {
    // Add this!
    mavenLocal()
}
Gradle's Kotlin DSL example of adding the Maven local repository

NOTE: This is the Kotlin DSL, if you use the Groovy DSL it will be slightly different.

Then in the project where the annotation processor is implemented you'll need to add the Maven plugin if you don't have it already:

plugins {
    // Add this!
    id("maven-publish")
}
Gradle's Kotlin DSL example of adding the Maven plugin

You'll want to specify some publishing options so you can easily add your library to the project that needs it like this:

publishing {
    publications {
        create<MavenPublication>("maven") {
            // For local publishing only
            groupId = "local"
            version = "1.0-SNAPSHOT"

            from(components["java"])
        }
    }
}

NOTE: The options above 👆are only for testing locally! You'll want to remove them when you publish your project publicly.

Also, if you've disabled the distZip and distTar tasks you'll need to re-enable them or you'll run into an error that says it "Cannot publish artifact" ... "as it does not exist". Typically when they're disabled with the Kotlin DSL they look like this:

tasks.distZip { enabled = false }
tasks.distTar { enabled = false }
🚨Remove this if you have it!🚨

Alternatively you can explicitly enable it like this:

tasks.distZip { enabled = true }
tasks.distTar { enabled = true }

Then you can reference your project in the local repository like this:

implementation("local:PROJECT-DIR:1.0-SNAPSHOT")

The Maven plugin will fill in the value PROJECT-DIR with the name of the directory that your library is in. So if your library is located in /home/javaprojects/libraries/my-library the PROJECT-DIR value will be my-library and the line above will look like this:

implementation("local:my-library:1.0-SNAPSHOT")

Each time you make a change to your library simply install it in the local repo like this:

./gradlew publishToMavenLocal

Good luck!