About the Documentation

The documentation of the FreeFair Gradle Plugin collection docs-comprehensive-documentation-overhaul-SNAPSHOT consists of two parts:

  • This reference guide

  • The Javadoc API

The latest copy of the user guide is available at https://docs.freefair.io/gradle-plugins/current/reference
and the corresponding javadocs can be found at https://docs.freefair.io/gradle-plugins/current/api.

The source code for the plugins and this documentation can be found at https://github.com/freefair/gradle-plugins

1. Installation

All plugins are deployed to the Gradle Plugin Portal.

The plugins are grouped in multiple modules, each containing some plugins. These submodules are described by the different parts of this documentation.

Each plugin can be included using the Plugins DSL or by referencing its containing module in the buildscript-block:

Using the plugins DSL
Groovy
plugins {
    id "io.freefair.lombok" version "docs-comprehensive-documentation-overhaul-SNAPSHOT"
}
Kotlin
plugins {
    id("io.freefair.lombok") version "docs-comprehensive-documentation-overhaul-SNAPSHOT"
}
Using legacy plugin application
Groovy
buildscript {
  repositories {
    maven {
      url "https://plugins.gradle.org/m2/"
    }
  }
  dependencies {
    classpath "io.freefair.gradle:lombok-plugin:docs-comprehensive-documentation-overhaul-SNAPSHOT"
  }
}

apply plugin: "io.freefair.lombok"
Kotlin
buildscript {
  repositories {
    maven {
      url = uri("https://plugins.gradle.org/m2/")
    }
  }
  dependencies {
    classpath("io.freefair.gradle:lombok-plugin:docs-comprehensive-documentation-overhaul-SNAPSHOT")
  }
}

apply(plugin = "io.freefair.lombok")

2. System Requirements

2.1. Gradle

The plugins of version docs-comprehensive-documentation-overhaul-SNAPSHOT are targeted at Gradle 9.4.1.

Starting with version 8, the Major.Minor version of the plugins matches those of Gradle itself.

2.2. Java

Most of the plugins should work all Java versions supported by Gradle 9.4.1, but some of the included external tools or libraries like Lombok or AJC might have additional constraints.

2.3. Kotlin

For most of the plugins, the Kotlin version is irrelevant.

Some plugins may interface with the Kotlin Gradle plugin or are implemented in Kotlin.

Whenever possible, we use the same Kotlin version that Gradle uses, currently 2.3.0.

Module I: Plugin Quick Reference

Use this table to find the right plugin for your use case. All plugin IDs follow the pattern io.freefair.<name>.

3. Build & Compilation

Plugin ID Purpose

io.freefair.lombok

Automates Lombok setup: adds annotation processor, creates delombok tasks, configures Javadoc.

io.freefair.aspectj

Compile-time AspectJ weaving. Replaces javac with ajc. Supports .aj and @Aspect sources.

io.freefair.aspectj.post-compile-weaving

Post-compile AspectJ weaving. Runs ajc after javac/kotlinc/groovyc. Use with Lombok or Kotlin.

io.freefair.sass-java

Compiles Sass/SCSS files from src/main/resources/ to CSS using Dart Sass.

io.freefair.sass-war

Compiles Sass/SCSS files from src/main/webapp/ for WAR projects.

io.freefair.sass-webjars

Adds WebJars support to Sass compilation (e.g., @import "scss/bootstrap").

io.freefair.mjml.java

Compiles MJML email templates to HTML as part of resource processing.

io.freefair.gwt

Google Web Toolkit compilation and DevMode integration.

io.freefair.plantuml

Generates images (PNG, SVG, etc.) from PlantUML diagram files.

io.freefair.compress

Provides Ar, Cpio, 7z archive tasks and GZip, BZip2, LZMA, Deflate compression tasks via Apache Commons Compress.

io.freefair.code-generator

Framework for custom code generation plugins.

io.freefair.quicktype

Generates code from JSON Schema using quicktype.

io.freefair.maven-plugin

Build Maven plugins using Gradle. Generates Maven plugin descriptors.

4. Documentation

Plugin ID Purpose

io.freefair.aggregate-javadoc

Aggregates Javadoc from multiple subprojects into a single documentation set. Apply to the root project.

io.freefair.javadocs

Adds a javadocJar task and publishes it alongside the main artifact.

io.freefair.javadoc-links

Automatically resolves and adds -link arguments to Javadoc tasks based on dependencies.

io.freefair.javadoc-utf-8

Sets UTF-8 encoding for all Javadoc tasks.

io.freefair.mkdocs

Integrates MkDocs into the Gradle build for documentation generation.

5. Publishing

Plugin ID Purpose

io.freefair.maven-publish-java

Configures maven-publish for Java libraries with sources and Javadoc JARs.

io.freefair.maven-publish-war

Configures maven-publish for WAR projects.

io.freefair.github.package-registry-maven-publish

Publishes artifacts to the GitHub Package Registry.

io.freefair.maven-central.validate-poms

Validates that generated POM files meet Maven Central requirements.

io.freefair.maven-optional

Adds an optional configuration similar to Maven’s <optional>true</optional>.

6. Project Setup & Utilities

Plugin ID Purpose

io.freefair.settings.plugin-versions

Apply in settings.gradle to manage FreeFair plugin versions in one place. Subprojects can omit the version.

io.freefair.git-version

Sets the project version based on the current Git tag or branch. Apply to the root project only.

io.freefair.github.base

Detects the GitHub repository slug and provides a shared GithubExtension for other GitHub plugins.

io.freefair.github.pom

Fills POM metadata (URL, SCM, license, developers) from the GitHub API.

io.freefair.okhttp

Provides a shared OkHttpClient and HTTP tasks (download, upload, request).

io.freefair.war

Adds Maven-like WAR features (attached classes, archive classes).

io.freefair.war-overlay

Adds Maven-like WAR overlay support for merging WARs.

io.freefair.aggregate-jacoco-report

Aggregates JaCoCo code coverage reports from multiple subprojects.

7. Base Plugins

Base plugins provide shared infrastructure and are applied automatically by the higher-level plugins listed above. You typically do not need to apply these directly.

Plugin ID Applied by

io.freefair.aspectj.base

io.freefair.aspectj, io.freefair.aspectj.post-compile-weaving

io.freefair.sass-base

io.freefair.sass-java, io.freefair.sass-war

io.freefair.gwt-base

io.freefair.gwt

io.freefair.mjml.base

io.freefair.mjml.java

Module II: Settings

8. Settings Plugins

8.1. io.freefair.settings.plugin-versions

Apply this plugin in settings.gradle(.kts) to manage FreeFair plugin versions in one place. Once applied, all FreeFair plugins can be used in subprojects without specifying a version.

Groovy
// settings.gradle
plugins {
    id "io.freefair.settings.plugin-versions" version "docs-comprehensive-documentation-overhaul-SNAPSHOT"
}
Kotlin
// settings.gradle.kts
plugins {
    id("io.freefair.settings.plugin-versions") version "docs-comprehensive-documentation-overhaul-SNAPSHOT"
}

In your subproject build files, the version can then be omitted:

Groovy
// build.gradle (subproject)
plugins {
    id "io.freefair.lombok" // no version needed
}
Kotlin
// build.gradle.kts (subproject)
plugins {
    id("io.freefair.lombok") // no version needed
}

The plugin reads all known FreeFair plugin IDs from the classpath and registers them in the settings plugin management block with the matching version.

Module III: AspectJ

  • a seamless aspect-oriented extension to the Javaâ„¢ programming language

  • Java platform compatible

  • easy to learn and use

AspectJâ„¢ enables

  • clean modularization of crosscutting concerns, such as error checking and handling, synchronization, context-sensitive behavior, performance optimizations, monitoring and logging, debugging support, and multi-object protocols

— https://www.eclipse.org/aspectj/

9. Getting Started

The FreeFair AspectJ plugins support two approaches: compile-time weaving and post-compile weaving. Choose the one that fits your project.

9.1. Quick Start: Compile-Time Weaving

Use this when your project only has Java and AspectJ sources and does not need javac-specific features like annotation processing with Lombok.

Groovy
plugins {
    id "io.freefair.aspectj" version "docs-comprehensive-documentation-overhaul-SNAPSHOT"
}

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

dependencies {
    implementation "org.aspectj:aspectjrt:1.9.25.1"
}
Kotlin
plugins {
    id("io.freefair.aspectj") version "docs-comprehensive-documentation-overhaul-SNAPSHOT"
}

java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(17))
    }
}

dependencies {
    implementation("org.aspectj:aspectjrt:1.9.25.1")
}

Place your aspects in src/main/aspectj/ (.aj files) or use @Aspect-annotated Java classes in src/main/java/. The plugin disables the standard compileJava task and compiles both directories with ajc.

./gradlew compileAspectj

9.2. Quick Start: Post-Compile Weaving

Use this when you need AspectJ together with annotation processors (e.g., Lombok), or with Kotlin, Groovy, or Scala sources.

Groovy
plugins {
    id "java"
    id "io.freefair.aspectj.post-compile-weaving" version "docs-comprehensive-documentation-overhaul-SNAPSHOT"
}

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

dependencies {
    implementation "org.aspectj:aspectjrt:1.9.25.1"
}
Kotlin
plugins {
    java
    id("io.freefair.aspectj.post-compile-weaving") version "docs-comprehensive-documentation-overhaul-SNAPSHOT"
}

java {
    toolchain {
        languageVersion.set(JavaLanguageVersion.of(17))
    }
}

dependencies {
    implementation("org.aspectj:aspectjrt:1.9.25.1")
}

Your source code is compiled by javac first, then ajc weaves aspects into the resulting bytecode. Write your aspects as @Aspect-annotated classes in src/main/java/.

Post-compile weaving only supports pre-compiled aspects (annotation-based @Aspect classes or aspects provided as bytecode on the aspectpath). Native .aj source files require compile-time weaving.
./gradlew compileJava
For complete working examples (including multi-module setups with separate aspect libraries), see the aspectj example projects.

10. AspectJ Plugins

The aspectj-plugin module provides the following plugins. They implement compile-time weaving and post-compile weaving respectively.

10.1. Compile-time weaving

When using compile-time weaving, your sources are directly compiled by ajc. This works well for simple projects which only have .java and .aj sources and don’t need javac-specific features like annotation processing with Project Lombok.

The io.freefair.aspectj plugin is built analogous to the existing plugins for Groovy, Scala and Kotlin. It adds an additional aspectj directory to every source set which will be compiled by ajc. This creates the additional source folders src/main/aspectj, src/test/aspectj and so forth.

In order to avoid conflicts and confusion between ajc and javac, the default compile*Java tasks will be disabled, and src/<sourceSet>/java will be compiled by ajc as well. This aligns with the AspectJ Maven Plugin, which also uses src/<sourceSet>/java.

Technically, each Gradle SourceSet will get two new SourceDirectorySets: aspectj and allAspectj.

aspectj contains src/<sourceSet>/aspectj while allAspectj combines aspectj with the default java SourceDirectorySet.

The compile*Aspectj tasks the use allAspectj as its source, in order to compile both src/<sourceSet>/aspectj and src/<sourceSet>/java

If you need both ajc and javac, just reenable the compile*Java tasks and switch the compile*AspectJ tasks from allAspectj to aspectj.

10.2. Post-compile weaving

The io.freefair.aspectj.post-compile-weaving enhances the compileJava (compileGroovy, compileScala, compileKotlin) tasks of all source sets with an additional ajc action in order to perform post-compile weaving.

With this setup, your source code is first compiled by javac, groovyc, scalac and/or kotlinc as usual. The resulting byte-code is then post-processed by ajc. This enables the usage of AspectJ in combination with annotation processors like Lombok or even other Languages like Groovy, Scala and Kotlin.

10.3. Configuration Options

10.3.1. AspectJ Runtime

Groovy
dependencies {
    implementation "org.aspectj:aspectjrt:1.9.21.1"
}
Kotlin
dependencies {
    implementation("org.aspectj:aspectjrt:1.9.21.1")
}

10.3.2. Aspectpath

Additional advices (the -aspectpath) can be declared as dependencies of the aspect configuration:

Groovy
dependencies {
    aspect project(":my-aspect")
    testAspect "com.example.foo:bar-aspect:1.0.0"
}
Kotlin
dependencies {
    aspect(project(":my-aspect"))
    testAspect("com.example.foo:bar-aspect:1.0.0")
}

10.3.3. Inpath

Additional jars/classes which should be woven and added to the output as well (the -inpath) can be declared as dependencies fo the inpath configuration:

Groovy
dependencies {
    inpath project(":my-lib")
    testInpath "com.example.foo:bar-lib:1.0.0"
}
Kotlin
dependencies {
    inpath(project(":my-lib"))
    testInpath("com.example.foo:bar-lib:1.0.0")
}

10.3.4. io.freefair.aspectj.post-compile-weaving

This plugin enhances the compileJava (compileGroovy, compileScala, compileKotlin) tasks of all source sets with an additional ajc action in order to perform post-compile-weaving.

The output of the compilation (javac, etc.) becomes the -inpath for ajc.

The -classpath, -source and -target arguments of ajc are set automatically to the corresponding values taken from the compile task. Additional ajc arguments can be configured using the ajc.options.compilerArgs property as shown below.

The following things are configurable:

Groovy
compileJava {
    ajc {
        enabled = true (1)
        classpath (2)
        options {
            aspectpath.setFrom configurations.aspect (3)
            compilerArgs = [] (4)
        }
    }
}
compileTestJava {
    ajc {
        enabled = true (1)
        classpath (2)
        options {
            aspectpath.setFrom configurations.testAspect (3)
            compilerArgs = [] (4)
        }
    }
}
Kotlin
tasks.compileJava {
    configure<AjcAction> {
        enabled = true (1)
        classpath (2)
        options {
            aspectpath.setFrom(configurations.aspect) (3)
            compilerArgs = listOf("") (4)
        }
    }
}
tasks.compileTestJava {
    configure<AjcAction> {
        enabled = true (1)
        classpath (2)
        options {
            aspectpath.setFrom(configurations.testAspect) (3)
            compilerArgs = listOf("") (4)
        }
    }
}
1 Specifies if ajc should run at all. Defaults to true
2 The classpath containing ajc itself (aspectjtools.jar). Inferred from the compile/runtime classpaths by default.
3 The classpath containing additional advices to weave. This directly maps to the -aspectpath argument of ajc.
4 Addittional arguments which will be passed to ajc.
The official documentation of ajc can be found here: https://www.eclipse.org/aspectj/doc/released/devguide/ajc-ref.html

11. AspectJ Tasks

11.1. AspectjCompile

This AbstractCompile task can be used to run ajc.

Groovy
task myAjcTask(type: io.freefair.gradle.plugins.aspectj.AspectjCompile) {
    aspectjClasspath.setFrom configurations.aspectj
    ajcOptions {
        inpath = files()
        aspectpath = files()
    }
}
Kotlin
tasks.register<AspectjCompile>("myAjcTask") {
    aspectjClasspath.setFrom(configurations.aspectj)
    ajcOptions {
        inpath = files()
        aspectpath = files()
    }
}

Module IV: Commons Compress

The Apache Commons Compress library defines an API for working with ar, cpio, Unix dump, tar, zip, gzip, XZ, Pack200, bzip2, 7z, arj, lzma, snappy, DEFLATE, lz4, Brotli, Zstandard, DEFLATE64 and Z files.
— https://commons.apache.org/proper/commons-compress/

12. Compress Plugins

The compress-plugin module provides archive and compression tasks based on Apache Commons Compress.

12.1. io.freefair.compress

This plugin applies all of the plugins listed below for convenience.

12.2. io.freefair.compress.trees

This plugin adds the commonsCompress Extension to the project, which provides the following methods:

FileTree arTree(Object arFile);

FileTree arjTree(Object arjFile);
FileTree arjTree(Object arjFile, String charsetName);

FileTree cpioTree(Object cpioFile);
FileTree cpioTree(Object cpioFile, String encoding);
FileTree cpioTree(Object cpioFile, int blockSize);
FileTree cpioTree(Object cpioFile, int blockSize, String encoding);

FileTree sevenZipTree(Object sevenZipFile);
FileTree sevenZipTree(Object sevenZipFile, char[] password);

FileTree dumpTree(Object dumpFile);
FileTree dumpTree(Object dumpFile, String encoding);

FileTree tarXzTree(Object tarXzFile);
FileTree tarLzmaTree(Object tarLzmaFile);

These methods can be used to open ar, arj, cpio, 7z, dump, tar.xz or tar.lzma archives. They work the same way as the zipTree and tarTree methods which are described here

Example
Groovy
task example(type: Sync) {
    from commonsCompress.arTree(file("foo.ar"))
}
Kotlin
tasks.register<Sync>("example") {
    from(commonsCompress.arTree(file("foo.ar")))
}

12.3. io.freefair.compress.ar

This plugin makes the Ar task available without it’s qualified name.

12.4. io.freefair.compress.cpio

This plugin makes the Cpio task available without it’s qualified name.

12.5. io.freefair.compress.7z

This plugin makes the SevenZip task available without it’s qualified name.

13. Compress Tasks

13.1. Ar

This AbstractArchiveTask implementation can be used to create ar archives.

Groovy
task packageArArchive(type: io.freefair.gradle.plugins.compress.tasks.Ar) {
    archiveFileName = "my-distribution.ar"
    destinationDirectory = file("$buildDir/dist")

    from "$buildDir/toArchive"

    longFileMode = org.apache.commons.compress.archivers.ar.ArArchiveOutputStream.LONGFILE_ERROR
}
Kotlin
tasks.register<io.freefair.gradle.plugins.compress.tasks.Ar>("packageArArchive") {
    archiveFileName = "my-distribution.ar"
    destinationDirectory = file("$buildDir/dist")

    from("$buildDir/toArchive")

    longFileMode = org.apache.commons.compress.archivers.ar.ArArchiveOutputStream.LONGFILE_ERROR
}

13.2. BZip2

This task can be used to compress individual files using BZip2.

Groovy
task compressBZip2(type: io.freefair.gradle.plugins.compress.tasks.BZip2) {
    source "src/main/resources"
    destinationDir = file("$buildDir/compressed")
    fileExtension = "bz2"
}
Kotlin
tasks.register<io.freefair.gradle.plugins.compress.tasks.BZip2>("compressBZip2") {
    source("src/main/resources")
    destinationDir = file("$buildDir/compressed")
    fileExtension = "bz2"
}

13.3. Cpio

This AbstractArchiveTask implementation can be used to create cpio archives.

Groovy
task packageCpioArchive(type: io.freefair.gradle.plugins.compress.tasks.Cpio) {
    archiveFileName = "my-distribution.cpio"
    destinationDirectory = file("$buildDir/dist")

    from "$buildDir/toArchive"

    format = org.apache.commons.compress.archivers.cpio.CpioConstants.FORMAT_NEW
    blockSize = 512
    encoding = "US-ASCII"
}
Kotlin
tasks.register<io.freefair.gradle.plugins.compress.tasks.Cpio>("packageCpioArchive") {
    archiveFileName = "my-distribution.cpio"
    destinationDirectory = file("$buildDir/dist")

    from("$buildDir/toArchive")

    format = org.apache.commons.compress.archivers.cpio.CpioConstants.FORMAT_NEW
    blockSize = 512
    encoding = "US-ASCII"
}

13.4. Deflate

This task can be used to compress individual files using the zlib deflate algorithm.

Groovy
task compressDeflate(type: io.freefair.gradle.plugins.compress.tasks.Deflate) {
    source "src/main/resources"
    destinationDir = file("$buildDir/compressed")
    fileExtension = "deflate"

    compressionLevel = 9
    withZlibHeader = false
}
Kotlin
tasks.register<io.freefair.gradle.plugins.compress.tasks.Deflate>("compressDeflate") {
    source("src/main/resources")
    destinationDir = file("$buildDir/compressed")
    fileExtension = "deflate"

    compressionLevel = 9
    withZlibHeader = false
}

13.5. GZip

This task compresses individual files using GZip.

Groovy
task compressGZip(type: io.freefair.gradle.plugins.compress.tasks.GZip) {
    source "src/main/resources"
    destinationDir = file("$buildDir/compressed")
    fileExtension = "gz"

    compressionLevel = 9
    comment = ""
    addFilename = false
}
Kotlin
tasks.register<io.freefair.gradle.plugins.compress.tasks.GZip>("compressGZip") {
    source("src/main/resources")
    destinationDir = file("$buildDir/compressed")
    fileExtension = "gz"

    compressionLevel = 9
    comment = ""
    addFilename = false
}

13.6. LZMA

This task can be used to compress individual files using LZMA.

Groovy
task compressLZMA(type: io.freefair.gradle.plugins.compress.tasks.LZMA) {
    source "src/main/resources"
    destinationDir = file("$buildDir/compressed")
    fileExtension = "lzma"
}
Kotlin
tasks.register<io.freefair.gradle.plugins.compress.tasks.LZMA>("compressLZMA") {
    source("src/main/resources")
    destinationDir = file("$buildDir/compressed")
    fileExtension = "lzma"
}

13.7. SevenZip

This AbstractArchiveTask implementation can be used to create 7z archives.

Groovy
task packageSevenZipArchive(type: io.freefair.gradle.plugins.compress.tasks.SevenZip) {
    archiveFileName = "my-distribution.7z"
    destinationDirectory = file("$buildDir/dist")

    from "$buildDir/toArchive"

    contentCompression = org.apache.commons.compress.archivers.sevenz.SevenZMethod.LZMA2
}
Kotlin
tasks.register<io.freefair.gradle.plugins.compress.tasks.SevenZip>("packageSevenZipArchive") {
    archiveFileName = "my-distribution.7z"
    destinationDirectory = file("$buildDir/dist")

    from("$buildDir/toArchive")

    contentCompression = org.apache.commons.compress.archivers.sevenz.SevenZMethod.LZMA2
}

Module V: Embedded Sass

14. Getting Started

The Embedded Sass plugins compile Sass/SCSS files to CSS using the Dart Sass embedded compiler. Choose the plugin variant that matches your project type.

14.1. For Java / Resource Projects

Place .scss files in src/main/resources/. The compiled CSS is included in the processed resources automatically.

Groovy
plugins {
    id "java"
    id "io.freefair.sass-java" version "docs-comprehensive-documentation-overhaul-SNAPSHOT"
}
Kotlin
plugins {
    java
    id("io.freefair.sass-java") version "docs-comprehensive-documentation-overhaul-SNAPSHOT"
}
src/main/resources/styles/main.scss
$primary: #3366cc;

body {
  font-family: system-ui, sans-serif;

  a {
    color: $primary;

    &:hover {
      color: darken($primary, 15%);
    }
  }
}
./gradlew compileSass

The compiled CSS appears in build/sass/main/ and is included in processResources output.

14.2. For WAR Projects

Place .scss files in src/main/webapp/.

Groovy
plugins {
    id "war"
    id "io.freefair.sass-war" version "docs-comprehensive-documentation-overhaul-SNAPSHOT"
}
Kotlin
plugins {
    war
    id("io.freefair.sass-war") version "docs-comprehensive-documentation-overhaul-SNAPSHOT"
}
./gradlew compileWebappSass
For complete working examples (Java resources, WAR, and WebJars integration), see the embedded-sass example projects.

15. Embedded Sass Plugins

The embedded-sass-plugin module provides the following plugins.

15.1. io.freefair.sass-base

This plugin adds the sass extension to the project and applies it to all SassCompile tasks.

Groovy
sass {
    omitSourceMapUrl = false
    outputStyle = com.sass_lang.embedded_protocol.OutputStyle.EXPANDED
    sourceMapContents = false
    sourceMapEmbed = false
    sourceMapEnabled = true
}
Kotlin
sass {
    omitSourceMapUrl = false
    outputStyle = com.sass_lang.embedded_protocol.OutputStyle.EXPANDED
    sourceMapContents = false
    sourceMapEmbed = false
    sourceMapEnabled = true
}

15.2. io.freefair.sass-webjars

This plugin adds webjars support to the sass compilation:

Groovy
dependencies {
    implementation 'org.webjars:bootstrap:5.1.3'
}
Kotlin
dependencies {
    implementation("org.webjars:bootstrap:5.1.3")
}
@import "scss/bootstrap";

15.3. io.freefair.sass-java

This plugin configures a compileSass task for the resources of each source set.

15.4. io.freefair.sass-war

This plugin creates a compileWebappSass for the src/main/webapp folder of your war project.

16. Sass Tasks

Module VI: Git

17. Git Plugins

17.1. io.freefair.git-version

This plugin sets the project version automatically based on the current Git state. Apply it to the root project only — the resolved version is propagated to all subprojects.

Groovy
plugins {
    id "io.freefair.git-version" version "docs-comprehensive-documentation-overhaul-SNAPSHOT"
}
Kotlin
plugins {
    id("io.freefair.git-version") version "docs-comprehensive-documentation-overhaul-SNAPSHOT"
}

17.1.1. Version Resolution

The plugin resolves the version using the following strategy (in priority order):

  1. If the project already has an explicit version set, it is kept as-is.

  2. CI/CD environment variables are checked (GitHub Actions, GitLab CI, Travis CI, CircleCI, Jenkins).

  3. git describe --tags --exact-match is executed to match an exact tag.

  4. git symbolic-ref --short HEAD is used as a fallback to get the branch name.

17.1.2. Tag and Branch Processing

  • Tags matching vX.Y.Z have the leading v stripped (e.g., v1.2.3 becomes 1.2.3).

  • Release branches matching release-X.Y.Z produce X.Y.Z-SNAPSHOT.

  • Hotfix branches matching hotfix-X.Y.Z produce X.Y.Z-SNAPSHOT.

  • Forward slashes in branch names are replaced with hyphens (e.g., feature/foo becomes feature-foo).

  • Dirty working trees append -SNAPSHOT to tag-based versions.

17.1.3. Prerequisites

  • Git must be installed and available on the system PATH.

  • The project directory must be inside a Git repository.

Module VII: GitHub

18. GitHub Plugins

The github-plugin module provides plugins for GitHub integration: repository detection, POM enrichment, and publishing to the GitHub Package Registry.

18.1. io.freefair.github.base

Common base plugin which is applied by the other plugins in this module. It adds the github extension to the project:

Configuration options of the github extension
Groovy
github {
    slug = "freefair" (1)
    username = findProperty('githubUsername') (2)
    token = findProperty('githubToken') (3)
    tag = 'HEAD' (4)
    travis = true (5)
}
Kotlin
github {
    slug = "freefair" (1)
    username = findProperty("githubUsername") (2)
    token = findProperty("githubToken") (3)
    tag = "HEAD" (4)
    travis = true (5)
}
1 The owner/name identifier of the GitHub repository. This is auto-detected using the configured git remotes.
2 The username which should be used when accessing the GitHub API.
3 The token which should be used when accessing the GitHub API.
4 See io.freefair.github.pom
5 Whether the GitHub project uses TravisCI (true) or not (false). This is auto-detected by default.
This plugin should only be applied to the root project.

18.2. io.freefair.github.pom

This plugin pre-fills the POMs of all MavenPublication instances with information available from the GitHub project.

The scm.tag element of the POM is auto-detected by default, but can be overridden using the github.tag extension property.

This plugins calls the GitHub API. Configure a username and token as described in io.freefair.github.base if you have problems with GitHub’s rate limit. (The token does not need any scopes for this).

18.3. io.freefair.github.package-registry-maven-publish

This plugin pre-configures publishing to the GitHub Package Registry using the maven-publish plugin.

It also applies the io.freefair.github.pom plugin.

When using this plugin, you have to configure a username and token as described in io.freefair.github.base. The token needs the read:packages and write:packages scopes as described here.

19. GitHub Tasks

This module does not contain tasks.

Module VIII: JaCoCo

JaCoCo is a free code coverage library for Java, which has been created by the EclEmma team based on the lessons learned from using and integration existing libraries for many years.
— https://www.eclemma.org/jacoco/

20. JaCoCo Plugins

The jacoco-plugin module provides plugins for aggregating code coverage data across multi-project builds.

20.1. io.freefair.aggregate-jacoco-report

This plugin adds an aggregateJacocoReport task to the project it is applied to. The task generates an aggregated JaCoCo report for the main source sets of all subprojects by collecting the execution data from their test tasks.

Apply this plugin to the root project:

Groovy
plugins {
    id "io.freefair.aggregate-jacoco-report" version "docs-comprehensive-documentation-overhaul-SNAPSHOT"
}
Kotlin
plugins {
    id("io.freefair.aggregate-jacoco-report") version "docs-comprehensive-documentation-overhaul-SNAPSHOT"
}
./gradlew aggregateJacocoReport

The aggregated report is of type JacocoReport.

For a multi-module example, see the jacoco example project.

21. JaCoCo Tasks

21.1. JacocoDump

The io.freefair.gradle.plugins.jacoco.tasks.JacocoDump task is the Gradle equivalent of the dump Ant-Task. It connects to a remote JaCoCo agent via TCP and downloads execution data.

JacocoDump Example
Groovy
task dump(type: io.freefair.gradle.plugins.jacoco.tasks.JacocoDump) {
    address = "localhost"
    port = 6300
    retryCount = 10
    dump = true
    reset = false
    destfile = file("build/dump.exec")
    append = true
}
Kotlin
tasks.register<io.freefair.gradle.plugins.jacoco.tasks.JacocoDump>("dump") {
    address = "localhost"
    port = 6300
    retryCount = 10
    dump = true
    reset = false
    destfile = file("build/dump.exec")
    append = true
}

Module IX: Lombok

Project Lombok is a java library that automatically plugs into your editor and build tools, spicing up your java. Never write another getter or equals method again, with one annotation your class has a fully featured builder, Automate your logging variables, and much more.
— https://projectlombok.org

22. Getting Started

Apply the plugin and you are done — no manual dependency management required.

Groovy
plugins {
    id "java"
    id "io.freefair.lombok" version "docs-comprehensive-documentation-overhaul-SNAPSHOT"
}
Kotlin
plugins {
    java
    id("io.freefair.lombok") version "docs-comprehensive-documentation-overhaul-SNAPSHOT"
}

The plugin adds Lombok to annotationProcessor and compileOnly for every source set automatically. Use Lombok annotations in your Java sources right away:

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

@Data
@Slf4j
public class User {
    private String name;
    private String email;
}

Build as usual:

./gradlew build

To inspect the generated code, run delombok:

./gradlew delombok

The delomboked sources appear in build/delombok/.

For a complete working example (including MapStruct integration), see the lombok example project.

23. Lombok Plugins

The lombok-plugin module provides the following plugins.

23.1. io.freefair.lombok-base

This plugin adds the lombok configuration and the lombok extension to the project. It also configures all Lombok related tasks to use the lombok configuration.

The used Lombok version can be customized using the lombok extension:

Setting a custom Lombok version
Groovy
lombok {
    version = "1.18.44"
}
Kotlin
lombok {
    version = "1.18.44"
}

23.2. io.freefair.lombok

This plugin simplifies the use of Lombok in Gradle by performing the following steps:

  • Lombok is added to the annotationProcessor and compileOnly configurations of each source set

  • For each source set a delombok task is created.

  • The javadoc task will be configured to read the delombok-ed sources instead of the actual sources.

  • lombok-mapstruct-binding is added to each source-set when 'org.mapstruct:mapstruct-processor' is found.

  • The compile tasks for each source set will consider the lombok.config(s) in their up-to-date checks

Only the default javadoc Javadoc task will be modified to work on the delombok-ed sources. If you create your own custom Javadoc tasks, it’s up to you to assign the correct source. The delombok task created by this plugin can be used as source for the javadoc task:

Groovy
task myJavadocs(type: Javadoc) {
  source = delombok
}
Kotlin
tasks.register<Javadoc>("myJavadocs") {
  source = tasks.named<Delombok>("delombok")
}

In contrast to the javadoc task, the sourcesJar task is not adjusted to use the delomboked sources. This is done on purpose, so the line numbers in the -sources.jar match the LineNumberTable in the generated class files.

24. Lombok Tasks

Module X: Maven

25. Maven Plugins

The maven-plugin module provides Maven-like features for Gradle: WAR overlays, Javadoc aggregation, Maven Central publishing helpers, and more.

25.1. io.freefair.war

This plugin is a shortcut which applies the following plugins:

25.2. io.freefair.war-overlay

This plugin ports the overlays feature of the Maven War Plugin to Gradle.

The overlays can be configured using the overlays property, which is added to every War task.

Groovy
war {
    overlays {
        foo {
            from "com.example:some-war:1.2.3@war" (1)
            enabled = true (2)
            into "sub-path/foo" (3)
            enableCompilation = true (4)
            provided = false (5)
        }
        bar {
            from project(":some-other-war") (1)
            skip = false (2)
            targetPath = "sub-path/bar" (3)
            include "*.html"
            includes = ["*.html", "**/*.xml"]
        }
    }
}
Kotlin
tasks.withType<org.gradle.api.tasks.bundling.War> {
    val extension: NamedDomainObjectContainer<WarOverlay> = extensions["overlays"] as NamedDomainObjectContainer<WarOverlay>
    extension.create("foo") {
        from("com.example:some-war:1.2.3@war") (1)
        enabled = true (2)
        into("sub-path/foo") (3)
        enableCompilation = true (4)
        provided(false) (5)
    }
    extension.create("bar") {
        from(project(":some-other-war")) (1)
        skip = false (2)
        targetPath = "sub-path/bar" (3)
        include("*.html")
        includes = ["*.html", "**/*.xml"]
    }
}
1 The source of the overlay. This can be another project, a File instance or a dependency notation.
2 Whether the overlay is enabled or should be skipped.
3 The target relative path in the webapp structure. By default, the content of the overlay is added in the root structure of the webapp.
4 Whether the classes and jars in the overlay should be added to the compile classpath of the project.
5 Whether the contents of the overlay should not be added to the war. Setting this to true can be used to compile against the classes in the war and have IDE auto-completion without actually adding the files of the overlay to the war.

The overlays property of the war task is a NamedDomainObjectContainer of WarOverlay instances.

25.3. io.freefair.war-attach-classes

This plugin ports the attachClasses feature of the Maven War Plugin to Gradle.

Groovy
war {
    attachClasses.set(true) (1)
    classesClassifier.set('classes') (2)
}
Kotlin
war {
    val attachClasses = extensions["attachClasses"] as Property<Boolean>
    val classesClassifier = extensions["classesClassifier"] as Property<String>
    attachClasses.set(true) (1)
    classesClassifier.set("classes") (2)
}
1 Whether classes (that is the content of the WEB-INF/classes directory) should be attached to the project as an additional artifact.
2 The classifier to use for the attached classes artifact.

25.4. io.freefair.war-archive-classes

This plugin ports the archiveClasses feature of the Maven War Plugin to Gradle.

Groovy
war {
    archiveClasses.set(true) (1)
}
Kotlin
war {
    val archiveClasses = extensions["archiveClasses"] as Property<Boolean>
    archiveClasses.set(true) (1)
}
1 Whether a JAR file will be created for the classes in the webapp. Using this optional configuration parameter will make the compiled classes to be archived into a JAR file and the classes directory will then be excluded from the webapp.

25.5. io.freefair.aggregate-javadoc

This plugin can be used to generate the aggregated javadocs of multiple projects. It is inspired by the aggregate mojo of the javadoc-maven-plugin.

This plugin is designed to be used in multi-module Gradle builds. It can either be applied directly to the root project or to a separate subproject.

The projects which sources should be included into the aggregated javadocs have to be added as dependencies to the javadoc configuration:

Groovy
dependencies {
    // Option 1: List projects explicitly
    javadoc project(":moduleA")
    javadoc project(":moduleB")

    //Option 2: Add all java projects automatically
    rootProject.subprojects { subproject ->
        subproject.plugins.withId("java") {
            javadoc subproject
        }
    }
}
Kotlin
dependencies {
    // Option 1: List projects explicitly
    javadoc(project(":moduleA"))
    javadoc(project(":moduleB"))

    //Option 2: Add all java projects automatically
    rootProject.subprojects.forEach { subproject ->
        subproject.plugins.withId("java") {
            javadoc(subproject)
        }
    }
}

25.6. io.freefair.aggregate-javadoc-legacy

This is the old io.freefair.aggregate-javadoc plugin which was deprecated and replaced with version 8.0.

This plugin adds a aggregateJavadoc task to the project which will generate the aggregated javadoc for the project itself and all of its subprojects (which have the java plugin applied).

25.7. io.freefair.aggregate-javadoc-jar

This plugin adds an aggregateJavadocJar task based on the io.freefair.aggregate-javadoc-legacy Plugin.

Consider using the new io.freefair.aggregate-javadoc Plugin which was rewritten for Version 8.0 which now also directly includes a jar task.

25.8. io.freefair.javadocs

This plugin is a shortcut which applies the following plugins:

This plugin configures the links of each Javadoc task based on the dependencies in the classpath of the task.

25.10. io.freefair.javadoc-utf-8

This plugin configures all Javadoc tasks to use UTF-8.

25.11. io.freefair.maven-publish-java

This plugin applies the maven-publish and java plugins and configures a mavenJava publication.

25.12. io.freefair.maven-publish-war

This plugin applies the maven-publish and war plugins and configures a mavenWeb publication.

25.13. io.freefair.maven-optional

This plugin adds a Maven-like optional configuration to the project.

Groovy
dependencies {
    optional "com.example:foo-bar:1.0.0"
}
Kotlin
dependencies {
    optional("com.example:foo-bar:1.0.0")
}

25.14. io.freefair.maven-central.validate-poms

This plugin adds a ValidateMavenPom task for each GenerateMavenPom task.

26. Maven Tasks

26.1. ValidateMavenPom

This task validates, that a given pom file contains all the information required by maven central.

Groovy
task validateMyPom(type: io.freefair.gradle.plugins.maven.central.ValidateMavenPom) {
    pomFile = file("path/to/my/pom.xml")
    ignoreFailures = false
}
Kotlin
tasks.register<io.freefair.gradle.plugins.maven.central.ValidateMavenPom>("validateMyPom") {
    pomFile = file("path/to/my/pom.xml")
    ignoreFailures = false
}

Module XI: Maven Plugin

27. Maven Plugin Plugins

27.1. io.freefair.maven-plugin

Use this plugin to build Maven plugins with Gradle. It applies the java and maven-publish plugins, sets the POM packaging to maven-plugin, and generates a Maven plugin descriptor from your annotated source code.

Groovy
plugins {
    id "io.freefair.maven-plugin" version "docs-comprehensive-documentation-overhaul-SNAPSHOT"
}

dependencies {
    implementation "org.apache.maven:maven-plugin-api:3.9.9"
    implementation "org.apache.maven.plugin-tools:maven-plugin-annotations:3.16.0"
}
Kotlin
plugins {
    id("io.freefair.maven-plugin") version "docs-comprehensive-documentation-overhaul-SNAPSHOT"
}

dependencies {
    implementation("org.apache.maven:maven-plugin-api:3.9.9")
    implementation("org.apache.maven.plugin-tools:maven-plugin-annotations:3.16.0")
}

Annotate your Mojo classes with @Mojo, @Parameter, etc. as usual. The plugin descriptor is generated automatically during the build.

For a working example, see the test-maven-plugin example project.

28. Maven Plugin Tasks

28.1. DescriptorGeneratorTask

Generates the Maven plugin descriptor (plugin.xml) from annotated source files. This is the Gradle equivalent of the DescriptorGeneratorMojo from the Maven Plugin Plugin.

The generated descriptor is placed in build/generated/resources/maven-plugin-descriptor and automatically included in the main source set resources.

Module XII: MkDocs

MkDocs is a fast, simple and downright gorgeous static site generator that’s geared towards building project documentation. Documentation source files are written in Markdown, and configured with a single YAML configuration file.
— https://www.mkdocs.org/

29. Getting Started

Groovy
plugins {
    id "io.freefair.mkdocs" version "docs-comprehensive-documentation-overhaul-SNAPSHOT"
}
Kotlin
plugins {
    id("io.freefair.mkdocs") version "docs-comprehensive-documentation-overhaul-SNAPSHOT"
}
MkDocs must be installed on your system (pip install mkdocs). The plugin calls the mkdocs CLI under the hood.

Initialize a new MkDocs project:

./gradlew mkdocsNew

Start the development server:

./gradlew mkdocsServe

Build the documentation:

./gradlew mkdocs

The built site appears in build/docs/mkdocs/ by default.

For a working example, see the mkdocs example project.

30. MkDocs Plugins

30.1. io.freefair.mkdocs

This plugin registers all MkDocs tasks listed below. It expects a mkdocs.yml configuration file in the project root directory.

31. MkDocs Tasks

All tasks are in the documentation group. Full API documentation is available in the io.freefair.gradle.plugins.mkdocs.tasks package.

31.1. MkDocsBuild

Executes mkdocs build to generate a static documentation site.

Output directory convention: build/docs/mkdocs.

31.2. MkDocsServe

Executes mkdocs serve to start a local development server with live-reload.

31.3. MkDocsNew

Executes mkdocs new to scaffold a fresh MkDocs project with a default mkdocs.yml and docs/index.md.

31.4. MkDocsGhDeploy

Executes mkdocs gh-deploy to publish the documentation to GitHub Pages.

Module XIII: MJML

MJML is a markup language for responsive email templates. It compiles to standard HTML that renders consistently across email clients.

32. Getting Started

Groovy
plugins {
    id "java"
    id "io.freefair.mjml.java" version "docs-comprehensive-documentation-overhaul-SNAPSHOT"
}
Kotlin
plugins {
    java
    id("io.freefair.mjml.java") version "docs-comprehensive-documentation-overhaul-SNAPSHOT"
}

Place .mjml files in src/main/mjml/. The compiled HTML is added to the Java resource output automatically.

./gradlew compileMjml
MJML is installed automatically via npm (requires Node.js on the system PATH). The plugin uses the gradle-node-plugin under the hood.
For a working example, see the mjml example project.

33. MJML Plugins

33.1. io.freefair.mjml.base

This plugin adds the mjml extension to the project and installs MJML via npm.

Configuration options
Groovy
mjml {
    validationMode = ValidationMode.strict
    minify = true
    beautify = false
    minifyOptions = "{\"minifyCSS\": true, \"removeEmptyAttributes\": false}"
    juiceOptions = "{\"preserveImportant\": true}"
    juicePreserveTags = "{\"myTag\": { \"start\": \"<#\", \"end\": \"</#\" }}"
}
Kotlin
mjml {
    validationMode = ValidationMode.strict
    minify = true
    beautify = false
    minifyOptions = "{\"minifyCSS\": true, \"removeEmptyAttributes\": false}"
    juiceOptions = "{\"preserveImportant\": true}"
    juicePreserveTags = "{\"myTag\": { \"start\": \"<#\", \"end\": \"</#\" }}"
}

33.2. io.freefair.mjml.java

Applies the base plugin and adds the MJML compile task output to the Java resource processing pipeline.

34. MJML Tasks

34.1. CompileMjml

Compiles .mjml files to .html using the MJML CLI with the configuration from the mjml extension.

Module XIV: OkHttp

An HTTP & HTTP/2 client for Android and Java applications
— https://square.github.io/okhttp/

35. OkHttp Plugins

35.1. Apply plugin

Groovy
plugins {
    id "io.freefair.okhttp"
}
Kotlin
plugins {
    id("io.freefair.okhttp")
}

35.2. io.freefair.okhttp

This plugin provides an OkHttpClient instance which can be used by other tasks and plugins.

Groovy
okHttp {
    loggingLevel = okhttp3.logging.HttpLoggingInterceptor.Level.BASIC
}
Kotlin
okHttp {
    loggingLevel = okhttp3.logging.HttpLoggingInterceptor.Level.BASIC
}

36. OkHttp Tasks

36.1. OkHttpRequestTask

This is the base class for all tasks executing an http request which provides the following common properties:

url

The URL for the Request

username

The username for HTTP Basic Auth

password

The password for HTTP Basic Auth

headers

Additional headers which will be added to the request.

36.2. DownloadFile

Groovy
tasks.register("myDownload", io.freefair.gradle.plugins.okhttp.tasks.DownloadFile) {
    url = "https://example.com/foo.txt"
    outputFile = file("build/foo.txt")
}
Kotlin
tasks.register<io.freefair.gradle.plugins.okhttp.tasks.DownloadFile>("myDownload") {
    url = "https://example.com/foo.txt"
    outputFile = file("build/foo.txt")
}

36.3. UploadFile

Groovy
tasks.register("myUpload", io.freefair.gradle.plugins.okhttp.tasks.UploadFile) {
    url = "https://example.com/foo.txt"
    file = file("build/file.txt")
    contentType = "text/plain"
}
Kotlin
tasks.register<io.freefair.gradle.plugins.okhttp.tasks.UploadFile>("myUpload") {
    url = "https://example.com/foo.txt"
    file = file("build/file.txt")
    contentType = "text/plain"
}

Module XV: PlantUML

This plugin generates images from plantuml files.

37. Basic usage

Groovy
plugins {
    id "io.freefair.plantuml"
}
Kotlin
plugins {
    id("io.freefair.plantuml")
}

This adds a PlantUML task to Gradle as well as a new source set. Place .puml files in src/plantuml/ and the generated images will be saved to the build directory.

For a working example, see the plantuml example project.

38. Configuration options

Option Description Default

includePattern

Pattern for filenames to include in the image generation process. This is different to source so that changes in included files will trigger a recompile as well

*/.puml

fileFormat

File format to generate. All valid options for PlantUML can be chosen.

PNG

outputDirectory

Directory to save generated files in.

build/plantuml

38.1. Configure

Groovy
plantUml {
    fileFormat = "PNG"
    outputDirectory = layout.buildDirectory.dir("dist")
}
Kotlin
tasks.plantUml {
    fileFormat = "PNG"
    outputDirectory = layout.buildDirectory.dir("dist")
}

39. Custom Task

Groovy
tasks.register("plantUml2", PlantumlTask) {
    source("src/plantuml2")
    includePattern = "**/*.tuml"
    fileFormat = "SVG"
    outputDirectory = layout.buildDirectory.dir("dist2")
}
Kotlin
tasks.register<PlantumlTask>("plantUml2") {
    source("src/plantuml2")
    includePattern = "**/*.tuml"
    fileFormat = "SVG"
    outputDirectory = layout.buildDirectory.dir("dist2")
}