Gradle 7

2021 11 02 head

Gradle Build Tool is my preferred build tool for all Java applications I am developing.

Google chose Gradle as the official build tool for Android.

Not only because build scripts are code, but because Gradle is modeled in a way that is extensible in the most fundamental ways.

Gradle’s model also allows it to be used for native development with C/C++ and can be expanded to cover any ecosystem.

For example, Gradle is designed with embedding in mind using its Tooling API.

What are my preferred goodies with the major version 7?

Java Module Native Support

Java modules were introduced with Java 9 in September 2017. Adoption was slow. Developers needed time to understand the tremendous advantages of language and compiler support of modules. Tooling was also a problem. It was cumbersome and error-prone to create Java modules either using the command line and experimental plugins.

Gradle Build Tool version 7 finally supports Java modules natively. Just use the java-library plugin.

The plugin will detect the presence of a module-info.java module declaration file and transparently switch to module compilation.

Dependencies Semantic Declaration

The Gradle team has decided to introduce semantic support for the declaration of dependencies.

All dependencies of a multi-module Java application are declared in a central file. The libs.versions.toml file under the gradle subdirectory of the root build can contain all plugin and library dependencies. The declarations can be used in all subprojects.

Support is provided to group a set of related dependencies and use the alias in the various Gradle modules.

IntelliJ Support

Jetbrains has improved support of Gradle in their new releases of IntelliJ. The 2021 versions offer native support of Gradle. Native support means IntelliJ finally uses Gradle for compilation and unit testing inside the IDE. You just need to take care of one build configuration and no more need to delve in the mysteries of IntelliJ build process.

The only glitch is that IntelliJ has its own concept of modules and are not synchronized with the Gradle modules. You have to be careful to align both structures to avoid surprises.

Jacoco Aggregated Test Coverage Reports

The support for coverage reports over multiple gradle subprojects is still limited. I use the following configuration to generate aggregated coverage report over all gradle modules.

apply plugin: 'jacoco'      (1)

jacoco {                    (2)
    toolVersion = "0.8.7"
}

jacocoTestReport {          (3)
    dependsOn test
    reports {
        xml.enabled true
        html.enabled true
    }
}


tasks.register("jacocoRootReport", JacocoReport) {      (4)
    subprojects { subproject ->
        subproject.plugins.withType(JacocoPlugin).configureEach {
            subproject.tasks.matching({ t -> t.extensions.findByType(JacocoTaskExtension) }).configureEach { testTask ->
                sourceSets subproject.sourceSets.main
                executionData(testTask)
            }
            subproject.tasks.matching({ t -> t.extensions.findByType(JacocoTaskExtension) }).forEach {
                rootProject.tasks.jacocoRootReport.dependsOn(it)
            }
        }
    }
    reports {
        xml.enabled true
        html.enabled true
    }
}


tasks.withType(Test) {
    finalizedBy jacocoTestReport        (5)
    useJUnitPlatform()
    jvmArgs += ['--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED', '--enable-preview', '-XX:+ShowCodeDetailsInExceptionMessages']
    reports.junitXml.mergeReruns = true
    options {
        setExcludeTags(['integration'] as Set)
    }
    maxParallelForks = 8
    failFast = false
}
1 Import the Jacoco plugin in the project
2 Allows the selection of the Jacoco version. I found it useful when using the latest JDK version. JaCoCo developers have a slow release rhythm.
3 Configure JaCoCo to generate a html and an XML report. The binary report is no more supported by external tool.
4 -
5 Configure JaCoCo test report to be generated after the running of a test task

Gradle has finally new plugins to better generate unit tests and test coverage reports for a multi-module project.

  • test-report-aggregation

  • jacoco-report-aggregation

The new approach to create aggregated reports is described in Multi-module Test Reporting with Gradle 7.

Wishes

I would greatly appreciate if the JaCoCo Gradle plugin is improved and align with the features of the Maven plugin. The process to aggregate the coverage reports on a multi-module project is cumbersome and brittle.

I am waiting for the Gradle 7.3 release to have native support of JDK 17. [1] The tool chain supports the newer JDKs without trouble but Gradle can only run with JDK 16 or older versions.


1. Gradle 7.3 was released in the first half of November 2021. JDK 17 is now natively supported. As usual the early version of the next JDK - in this case JDK 18 - is only currently supported through the toolchain feature.