How to make SonarQube module analyze the project only once when sonar analysis is bound to maven lifecycle in a multi-module project?
Asked Answered
A

1

5

What I am trying to achieve is integrate SonarQube analysis into the build process, so that whenever mvn clean install is run, the code is analyzed with SonarQube. We want to use it for local analysis and also for build on Jenkins. If new issues are found, than the build should fail (we want to use build breaker plugin for that). This way the developer would know that by his code his is going to introduce new issues, and will have to fix them for the build to work.

When I run mvn sonar:sonar, the analysis takes 30 seconds, which is OK.

However, the problem occurs when I am trying to bind sonar goal to maven build phases. I bind sonar to verify phase. The build takes 5 minutes now, which is too long. It should take about 1 minute. The build itself, without SonarQube analysis takes 30 seconds.

Note (may help to figure out what the problem is): the project on which the build is run has multiple modules in it, and I guess that is the problem. It looks like sonar:sonar goal is executed multiple times, once for each submodule, and the whole project is analyzed multiple times (not only the submodules). So, we have 4 submodules, and the report is generated 5 times during the build.

Instead, we want to analyze the whole project only once, not 5 times. It's also important for this 1 analysis to be run at the end of the build, after the cobertura reports are generated for all modules.

So, how do I integrate SonarQube analysis into the build, so that it analyzes my multi-module project only once, in the end, after cobertura reports are generated for all the submodules?

SonarQube plugin properties in parent pom:

<!-- Sonar plugin properties -->
<sonar.jdbc.url>jdbc:url</sonar.jdbc.url>
<sonar.analysis.mode>preview</sonar.analysis.mode>
<sonar.issuesReport.html.enable>true</sonar.issuesReport.html.enable>       
<sonar.issuesReport.console.enable>true</sonar.issuesReport.console.enable>
<sonar.host.url>sonar.host:9000</sonar.host.url>
<sonar.language>java</sonar.language>
<sonar.buildbreaker.skip>false</sonar.buildbreaker.skip>
<sonar.qualitygate>Sonar%20way%20with%20Findbugs</sonar.qualitygate>
<sonar.preview.includePlugins>buildbreaker</sonar.preview.includePlugins>
<sonar.exclusions>file:**/target/**</sonar.exclusions>
<branch>development</branch>

Plugins configuration in the project pom:

                <!-- Run cobertura analysis during package phase -->
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>cobertura-maven-plugin</artifactId>
                    <executions>
                        <execution>
                           <phase>package</phase>
                              <goals>
                                 <goal>cobertura</goal>
                               </goals>
                        </execution>
                  </executions>
                </plugin>

                <!-- Run sonar analysis (preview mode) during verify phase. Cobertura reports need to be generated already -->
                <plugin>
                   <groupId>org.codehaus.mojo</groupId>
                   <artifactId>sonar-maven-plugin</artifactId>
                   <version>2.5</version>
                   <executions>
                        <execution>
                           <phase>verify</phase>
                              <goals>
                                 <goal>sonar</goal>
                               </goals>
                        </execution>
                  </executions>
                </plugin>
Affright answered 17/3, 2015 at 12:54 Comment(0)
S
0

IMO, this is just a Maven configuration issue, you're missing the <inherited>false</inherited> element on the execution of sonar:sonar:

                <!-- Run sonar analysis (preview mode) during verify phase. Cobertura reports need to be generated already -->
                <plugin>
                   <groupId>org.codehaus.mojo</groupId>
                   <artifactId>sonar-maven-plugin</artifactId>
                   <version>2.5</version>
                   <executions>
                        <execution>
                           <phase>verify</phase>
                           <goals>
                              <goal>sonar</goal>
                           </goals>
                           <inherited>false</inherited>
                        </execution>
                  </executions>
                </plugin>
Solfa answered 18/3, 2015 at 12:16 Comment(5)
Thanks for your answer! I've tried it, and this way the sonar analysis is run only once. The problem there is that in this case sonar is run at the very beginning of the build, when cobertura reports are not available yet. Instead, it would make sense for the sonar analysis to be run in the end when all the submodules are build already.Affright
I see 2 solutions to this problem, and I don't like either of them. Solution 1: add a new submodule to the parent project which would be built the last. Sonar analysis would be launched from that submodule only. This is confusing and not very transparant. Solution 2: put command mvn sonar:sonar in some script, and execute this script as a post build action. This results in problems with portability, and again, it's not elegant.Affright
What tool are you using to trigger your builds?Solfa
We are using quickbuild (moving away from Jenkins) for CI. However, we would like to be able to integrate this check into the local build, not only the one which runs on CIAffright
Another option that might help here is to use separate parent and aggregator POMs.The reason has to do with Maven build order and is described in more detail in this answer.Messer

© 2022 - 2024 — McMap. All rights reserved.