How to publish a Micronaut project using Gradle

johnnystarr

Johnny Starr

Posted on April 17, 2021

How to publish a Micronaut project using Gradle

I have really enjoyed working with Micronaut. It's a wonderfully fast framework that makes life easier. This new framework is really easy to get up and running. Publishing on the other hand isn't well documented, so I wanted to share some tips on how I was able to get this done.

Overview

We will specifically be publishing a Micronaut app using Gradle. You will need to install the Micronaut CLI. You can grab it here: https://guides.micronaut.io/micronaut-cli/guide/index.html

Create a Micronaut App

Now that you've grabbed the CLI, create a new project. The Launcher button on the Micronaut site will help you with the CLI commands if you want specific packages. But for the sake of simplicity, we won't be installing anything special. Run the following command to build a demo app:

$ mn create-app --build=gradle --jdk=11 --lang=java --test=junit to.dev.publishing
Enter fullscreen mode Exit fullscreen mode

Gradle Steps

If you're like me, you might have IntelliJ with the Gradle plugin installed. If so, this next part is a no brainer. By simply opening the project it will run Gradle in the background and generate your project. You should have a build.gradle file in the root of your project that looks something like this:

plugins {
    id("com.github.johnrengelman.shadow") version "6.1.0"
    id("io.micronaut.application") version "1.4.2"
}

version = "0.1"
group = "to.dev"

repositories {
    mavenCentral()
}

micronaut {
    runtime("netty")
    testRuntime("junit5")
    processing {
        incremental(true)
        annotations("to.dev.*")
    }
}

dependencies {
    implementation("io.micronaut:micronaut-http-client")
    implementation("io.micronaut:micronaut-runtime")
    implementation("javax.annotation:javax.annotation-api")
    implementation("io.micronaut:micronaut-validation")
    runtimeOnly("ch.qos.logback:logback-classic")
}


application {
    mainClass.set("to.dev.Application")
}
java {
    sourceCompatibility = JavaVersion.toVersion("11")
    targetCompatibility = JavaVersion.toVersion("11")
}
Enter fullscreen mode Exit fullscreen mode

Running Gradle Build

Run the following command to build your artifacts:

$ ./gradlew build

> Task :compileTestJava
Note: Creating bean classes for 1 type elements

BUILD SUCCESSFUL in 11s
15 actionable tasks: 3 executed, 12 up-to-date
Enter fullscreen mode Exit fullscreen mode

Your output may be slightly different depending on your dependencies and workstation.

Artifacts

To see the produced artifacts you can run:

$ ls ./build/libs/
publishing-0.1-all.jar
publishing-0.1-runner.jar
publishing-0.1.jar

Enter fullscreen mode Exit fullscreen mode

Hmm... Interesting right? We have 3, so which one is should we ship to production? The short answer, is publishing-0.1-all.jar. But how do we publish it? And what are the other two JARs for? (we'll discuss this on another post)

Publishing

It took some time to understand the best publishing strategy for my current use-case. What I wanted were the following 3 things:

  • The primary JAR
  • A Zip archive of the distribution
  • A Tar archive of the distribution

Ok. Great... So how do we do that? Add the following lines to your build.gradle file:

publishing {
    publications {
        myDist(MavenPublication) {
            artifact shadowJar
            artifact distZip
            artifact distTar
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

And that's it! shadowJar produces our large publishing-0.1-all.jar. The zip/tar produce the full distribution which includes all the required JAR files for your project.

Publishing to Maven Locally "Trick"

So you're not quite ready to publish to Maven Central, Nexus3 or Artifactory. No biggie. You can use the following "trick" to publish to your local machine. This is useful if you want to inspect distribution you can delete your local ~/.m2 directory:

$ rm -rf ~/.m2
Enter fullscreen mode Exit fullscreen mode

Afterwards, from your project repo run the following Gradle command:

$ ./gradlew publishMyDistPublicationToMavenLocal
Enter fullscreen mode Exit fullscreen mode

Now you can inspect your "published" artifacts:

$ find ~/.m2
/Users/johnny/.m2
/Users/johnny/.m2/repository
/Users/johnny/.m2/repository/to
/Users/johnny/.m2/repository/to/dev
/Users/johnny/.m2/repository/to/dev/publishing
/Users/johnny/.m2/repository/to/dev/publishing/maven-metadata-local.xml
/Users/johnny/.m2/repository/to/dev/publishing/0.1
/Users/johnny/.m2/repository/to/dev/publishing/0.1/publishing-0.1-all.jar
/Users/johnny/.m2/repository/to/dev/publishing/0.1/publishing-0.1.pom
/Users/johnny/.m2/repository/to/dev/publishing/0.1/publishing-0.1.tar
/Users/johnny/.m2/repository/to/dev/publishing/0.1/publishing-0.1.zip

Enter fullscreen mode Exit fullscreen mode

Takeaways

  • Micronaut is amazing and I love it. It's still quite new and documentation is hard. Getting up and running is fast, but publishing isn't super obvious at first glance.

  • Even without selecting it, our CLI command includes the Netty webserver. I think its pretty slick coming from a WAR/Tomcat background! Netty completely sidesteps the Servlet.

  • Gradle is awesome. As a UNIX expert my heart will always go out to to Make, but come on people its 2021!

I hope this helps save you some time. It took me a little bit to figure this one out.

💖 💪 🙅 🚩
johnnystarr
Johnny Starr

Posted on April 17, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related