DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

The software you build is only as secure as the code that powers it. Learn how malicious code creeps into your software supply chain.

Apache Cassandra combines the benefits of major NoSQL databases to support data management needs not covered by traditional RDBMS vendors.

Generative AI has transformed nearly every industry. How can you leverage GenAI to improve your productivity and efficiency?

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Related

  • Introduce a New API Quickly Using Spring Boot and Gradle
  • Transitioning From Groovy to Kotlin for Gradle Android Projects
  • Building AI Applications With Java and Gradle
  • Understanding Dependencies...Visually!

Trending

  • Integrating Model Context Protocol (MCP) With Microsoft Copilot Studio AI Agents
  • Metrics at a Glance for Production Clusters
  • Data Quality: A Novel Perspective for 2025
  • How to Perform Custom Error Handling With ANTLR

Sonar and Gradle Multi-Module Projects

By 
Gunnar Hillert user avatar
Gunnar Hillert
·
Jan. 25, 12 · Interview
Likes (0)
Comment
Save
Tweet
Share
24.2K Views

Join the DZone community and get the full member experience.

Join For Free
I love Sonar. It is a wonderful way to collect some metrics for your Java projects - hassle-free and wrapped in a sweet-looking UI.  For Maven-based projects Sonar literally works out of the box. Just start up your Sonar instance (assuming you are using the default settings running on localhost) and then you simply fire it off using:
$ mvn sonar:sonar 
A few moments later you should have the metrics available at:
http://localhost:9000/
Well, the past few days I was setting up a multi-module Gradle project for Sonar. Let me start by stating that Gradle is awesome. Having the ability to declare dependencies as one-liners and also being able to customize your scripts easily, yet having sensible defaults, is very nice. Kind of the best of both worlds.

Setting up Sonar for a multi module project, though, is unfortunately a bit more complicated, compared to what I am used to in the Maven world. It is not awfully complicated, but it took me a while to collect all the pieces of information.

Getting your Sonar plugin to just doing something is fairly simple. Just follow the basic steps outlined in the plugin documentation at:
  • http://gradle.org/docs/current/userguide/sonar_plugin.html
One differentiator between the Sonar Plugin for Gradle and Maven is, that the Gradle version does not automatically run code coverage analysis. This needs to be manually setup. This is where the official doc just vaguely refers to Cobertura.

First, I tried using Cobertura for code coverage, but I seemed to run into difficulties for my multi-module projects. The Cobertura Plugin is here:
  • https://github.com/valkolovos/gradle_cobertura/wiki
By chance I realized that the Sonar guys have a GitHub repository with samples on how to setup sonars for various build systems, including Gradle:
  • https://github.com/SonarSource/sonar-examples/
In their examples, they are using JaCoCo, which is not mentioned in the original Gradle docs and maybe I could have continued with Cobertura but it seemed that Sonar was preferring JaCoCo and thus I continued with that.

Some Gradle Sonar Plugin Limitations

The Gradle Sonar Plugin has an annoying limitation, where I can run it for the ROOT project OR for the sub-projects individually. See the following Gradle Jira ticket for details:
  • http://issues.gradle.org/browse/GRADLE-1813
Furthermore, I hit the minor issue that I cannot set the links in the Sonar dashboard. This seems to be related to the following Sonar Jira issue:
  • https://jira.codehaus.org/browse/SONAR-2749
The JaCoCo code coverage plugin is "slightly less" supported by the Gradle Sonar Plugin, e.g. the  Gradle Plugin does not have an explicit setter for the JacocoReportPath and it assumes the "target" folder as the build directory by default. Therefore you must set explicitly:
props["sonar.jacoco.reportPath"]  = "${buildDirName}/jacoco.exec"
Lastly, I deviated a bit from the SonarSource Gradle example, and instead of System properties, I wanted to use Gradle properties to allow for users to provide non-default Sonar configuration settings (databasem url, jdbc parameters etc.). Well, while setting that up I ran into yet another Gradle Jira issue:
  • http://issues.gradle.org/browse/GRADLE-1826
But at the the end, I am happily able to run a multi-module Gradle project with Sonar and collecting Code Coverage statistics.  Here is the relavant code from my build.gradle file:

apply plugin: 'sonar'
 
sonar {
 
    if (rootProject.hasProperty('sonarHostUrl')) {
        server.url = rootProject.sonarHostUrl
    }
 
    database {
        if (rootProject.hasProperty('sonarJdbcUrl')) {
            url = rootProject.sonarJdbcUrl
        }
        if (rootProject.hasProperty('sonarJdbcDriver')) {
            driverClassName = rootProject.sonarJdbcDriver
        }
        if (rootProject.hasProperty('sonarJdbcUsername')) {
            username = rootProject.sonarJdbcUsername
        }
        if (rootProject.hasProperty('sonarJdbcPassword')) {
            password = rootProject.sonarJdbcPassword
        }
    }
 
    project {
        dynamicAnalysis  = "reuseReports"
        withProjectProperties { props ->
            props["sonar.core.codeCoveragePlugin"] = "jacoco"
            props["sonar.jacoco.reportPath"]       = "${buildDirName}/jacoco.exec"
        }
    }
 
    println("Sonar parameters used: server.url='${server.url}'; database.url='${database.url}'; database.driverClassName='${database.driverClassName}'; database.username='${database.username}'")
 
}
 
subprojects { subproject ->
 
    ...
 
    // See http://www.gradle.org/docs/current/userguide/dependency_management.html#sub:configurations
    // and http://www.gradle.org/docs/current/dsl/org.gradle.api.artifacts.ConfigurationContainer.html
    configurations {
        jacoco //Configuration Group used by Sonar to provide Code Coverage using JaCoCo
    }
 
    // dependencies that are common across all java projects
    dependencies {
        ...
        jacoco group: "org.jacoco", name: "org.jacoco.agent", version: "0.5.3.201107060350", classifier: "runtime"
        ...
    }
 
    test {
        jvmArgs "-javaagent:${configurations.jacoco.asPath}=destfile=${buildDir}/jacoco.exec,includes=org.your.project.*"
    }
    ...
}
I hope this is useful information for all Gradle users out there.

 

From http://hillert.blogspot.com/2012/01/sonar-and-gradle-multi-module-projects.html

Gradle

Opinions expressed by DZone contributors are their own.

Related

  • Introduce a New API Quickly Using Spring Boot and Gradle
  • Transitioning From Groovy to Kotlin for Gradle Android Projects
  • Building AI Applications With Java and Gradle
  • Understanding Dependencies...Visually!

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!