Using sonarRunner on a multi-project java codebase using gradle, skips classes of exactly one project

StackOverflow https://stackoverflow.com/questions/17067905

  •  31-05-2022
  •  | 
  •  

Question

I have a multi-module java codebase, that I build using gradle's multi-project support. The version of gradle used is 1.6. The code is used to build an Oracle ATG application, and I use the gradle java plugin along with a custom resolver to manage dependencies between modules/projects and external ATG modules.

The build works fine, and I can compile and create jars without issues.

I also use the gradle eclipse plugin, and can import the gradle multi-project into eclipse, which results in all the sub-projects getting imported into Eclipse with the java build-path managed nicely.

I am using the sonar-runner plugin that ships with gradle, and the version of Sonar is 3.4.1. I'm using the H2 database that ships with Sonar.

This is what I use to configure sonarRunner in the root project in build.gradle:

apply plugin: "sonar-runner"

sonarRunner {
    sonarProperties {
      property "sonar.host.url", "http://localhost:9000"
      property "sonar.jdbc.url", "jdbc:h2:tcp://localhost:9092/sonar"
      property "sonar.jdbc.driverClassName", "org.h2.Driver"
      property "sonar.jdbc.username", "sonar"
      property "sonar.jdbc.password", "sonar"
    }
}

For each subproject, I do this:

sonarRunner {
    sonarProperties {
        property "sonar.projectName", pathToAtgModuleName(path)
        property "sonar.sourceEncoding", "UTF-8"
        property "sonar.language", "java"
    }
}

I set the sonar.projectName property so that the Sonar dashboard can show the nested modules correctly. The value of sonar.projectName looks like: ParentModule.ChildModule.SubChildModule.

The Sonar report works for most modules, except one. It simply seems to ignore all the classes in this module.

My project structure is like this (the number of java classes including inner classes is to the right):

RootProj/core 356
RootProj/MyMod 343
RootProj/MyMod/versioned 0
RootProj/MyMod/versioned/catalog 33
RootProj/integration/int1 9
RootProj/integration/int2 7
RootProj/integration/int3 5
RootProj/integration/int4 2
RootProj/integration/int5 17
RootProj/integration/int6 44
RootProj/perf 0
RootProj/REST 12
RootProj/Store 11
RootProj/TestRest 92
RootProj/TestStore 141
RootProj/TestVersioned 1
RootProj/webservices 14

The module that fails to show any classes, is RootProj/MyMod.

For a project where classes are detected, the output looks like this:

18:58:34.016 INFO  .s.b.b.ProjectModule - -------------  Analyzing RootProj.MyMod.versioned.catalog
18:58:34.019 INFO  .b.b.ProjectSettings - Load module settings
18:58:34.859 INFO  .s.b.ProfileProvider - Quality profile : [name=RCS_way,language=java]
18:58:34.883 INFO  nPluginsConfigurator - Configure maven plugins...
18:58:34.977 INFO        org.sonar.INFO - Compare to previous analysis (2013-06-12)
18:58:35.026 INFO        org.sonar.INFO - Compare over 5 days (2013-06-07, analysis of 2013-06-05 12:16:12.963)
18:58:35.066 INFO        org.sonar.INFO - Compare over 30 days (2013-05-13, analysis of 2013-06-03 15:12:37.359)
18:58:35.133 INFO  .b.p.SensorsExecutor - Initializer ProjectFileSystemLogger...
18:58:35.135 INFO  jectFileSystemLogger - Excluded tests: [**/package-info.java]
18:58:35.139 INFO  jectFileSystemLogger - Source directories:
18:58:35.140 INFO  jectFileSystemLogger -   D:\eCommerce\code\R0_3\RootProj\MyMod\versioned\catalog\src
18:58:35.140 INFO  .b.p.SensorsExecutor - Initializer ProjectFileSystemLogger done: 7 ms
18:58:35.185 INFO  p.PhasesTimeProfiler - Sensor JavaSourceImporter...
18:58:35.441 INFO  p.PhasesTimeProfiler - Sensor JavaSourceImporter done: 256 ms

This is the output SonarRunner for that project:

18:59:24.747 INFO  .s.b.b.ProjectModule - -------------  Analyzing RootProj.MyMod
18:59:24.748 INFO  .b.b.ProjectSettings - Load module settings
18:59:25.164 INFO  .s.b.ProfileProvider - Quality profile : [name=RCS_way,language=java]
18:59:25.175 INFO  nPluginsConfigurator - Configure maven plugins...
18:59:25.186 INFO        org.sonar.INFO - Compare to previous analysis (2013-06-12)
18:59:25.194 INFO        org.sonar.INFO - Compare over 5 days (2013-06-07, analysis of 2013-06-05 12:16:12.957)
18:59:25.203 INFO        org.sonar.INFO - Compare over 30 days (2013-05-13, analysis of 2013-06-03 15:12:37.355)
18:59:25.211 INFO  .b.p.SensorsExecutor - Initializer ProjectFileSystemLogger...
18:59:25.212 INFO  jectFileSystemLogger - Excluded tests: [**/package-info.java]
18:59:25.212 INFO  .b.p.SensorsExecutor - Initializer ProjectFileSystemLogger done: 1 ms
18:59:25.213 INFO  p.PhasesTimeProfiler - Sensor JavaSourceImporter...
18:59:25.224 INFO  p.PhasesTimeProfiler - Sensor JavaSourceImporter done: 11 ms

As you can see, the offending module doesn't show the line where it finds the source directories.

I turned on gradle debug logs, and I saw these values being printed:

RootProj.MyMod.sonar.modules: versioned
RootProj.MyMod.sonar.sources: D:\eCommerce\code\R0_3\RootProj\MyMod\src
RootProj.MyMod.versioned.catalog.sonar.sources: D:\eCommerce\code\R0_3\RootProj\MyMod\versioned\catalog\src
RootProj.MyMod.versioned.sonar.modules: catalog
RootProj.MyMod.versioned.sonar.sources: D:\eCommerce\code\R0_3\RootProj\MyMod\versioned\src

The above lines were not all together. I've just pasted the values I found interesting.

My guess was that since RootProj.MyMod.versioned doesn't have any java classes, a bug in either the gradle plugin or sonar-runner itself, causes it to skip the classes in the parent directory true.

So I used skipProject = true for RootProj.MyMod.versioned. That fixed the problem and I see the classes being reported on for RootProj.MyMod, but Sonar no longer tries to run a report for RootProj.MyMod.versioned.catalog, which does have files.

So I'm stuck with either losing Sonar reports on 343 classes, or 33 classes. I'd rather not choose either.

So finally, my question: Is there a way to disable the running the reports on only the project with ZERO classes, and not its parent or children?

FYI, in case it has any relevance, I only setup compile time dependencies using syntax like:

compile group:'ATG_MODULE', name:'mymodule', version:'10.1.1'

The dependencies are resolved by the custom resolver.

The custom resolver is maintained by me, but since compilation and the eclipse plugin work fine, I'm assuming that it isn't the source of the problem.

EDIT

As mentioned by Peter Niederwieser, Sonar runner only works with leaf projects. But there must be a way to configure the Gradle sonar runner plugin to treat the hierarchy as a flat one, so that all projects are leaf projects. In sonar-runner you could probably set sonar.modules at the root project to the names of each of the projects you want to analyze. But how to do this in Gradle?

I tried setting sonar.modules in each project to null but that doesn't seem to have any effect.

Was it helpful?

Solution

Sonar Runner (which Gradle is integrating with) is only capable of analyzing code in leaf projects. If you'd like to see support for analyzing code in non-leaf projects, ping the Sonar folks.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top