I have a Java project build with Maven analyzed with SonarQube. Each project consists of a couple of Maven modules, let's say:
org.acme.module - API
org.acme.module.demo - a small demo application demonstrating the features of this module
org.acme.module.doc - documentation for developers
org.acme.module.it - integration tests
In an ideal world I'd want to analyze the code quality of all of these modules, but calculate the test coverage only for the API.
However I could not find a way to disable entire projects from the code coverage (sonar.coverage.exclusions only filters the class name, and some of these modules share a package with the API), so now I'm trying to disable these modules from Sonar.
I tried:
<properties>
<sonar.skippedModules>org.acme.module.demo,org.acme.module.doc,org.acme.module.it</sonar.skippedModules>
</properties>
Which works, but is a lot of work, since I have hundreds of these projects.
<properties>
<sonar.skip>true</sonar.skip>
</properties>
Works too, but I have to define it similarly for every single sub-module. Also, now Sonar won't analyze the files, which is bad for obvious reasons.
I'd rather have something like <excludedModules>*demo*,*doc*,*it*,<excludedModules> which I could define once in the parent pom.xml and use in all these modules.
This answer states:
You could also do this from the sonar admin page as documented in the Skipping Modules section here.
I was so happy for a moment until I realized the SonarQube documentation does not contain the "Skipping Modules" section anymore. Or maybe it was moved and I just can't find it.
How do I skip the code coverage analysis in multiple modules while still running other Sonar tests?
Or if that's not possible, how to skip these modules in Sonar in a generic way?
Login as administrator
Go to your projects, and you should see an Administration tab.
Then go to Analysis Scope, then in coverage exclusions add your exclusions:
src/main/java/org/acme/module/demo/**
In all the child/sub module pom you can add something like below to exclude all the files in that module only from coverage analysis. You still will get the rest of the SonarQube analysis for those modules.
<profiles>
<profile>
<id>sonar</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<sonar.coverage.exclusions>
**/*.*
</sonar.coverage.exclusions>
</properties>
</profile>
</profiles>
Related
I have two servers for my java application and I'm using jenkins to deploy my code on those servers. The application is same but because of the nature of work we are doing we need different versions of same custom jars on each server.
1: I've tried to set environment variables and tried to get artifact and group Id's of those in pom.xml but we can not access environment variables in pom.xml
2: I've tried changing their names and import both jars but that's insane one of them is ignored and both the servers use only one version.
I've been struggling with it for a long time now, The only possible solution that comes to my mind is that i create two different git repositories and make different jenkin jobs for every server.
Can anyone help me figure out how can I import different versions on different servers, that'd mean a lot. Thanks in advance.
If I get you correctly,
different versions of some custom jars
are different version of yours dependencies. This can be easily achieved using maven profiles. Your pom.xml would look similair to this (XML is simplified to minimum.
<project>
<!-- Basic info like model, artifact, group etc. -->
<dependencies>
<!-- Your usual deps as you are used to -->
</dependencies>
<profiles>
<profile>
<id>profile1</id>
<dependencies>
<!-- Extra deps for this profile -->
</dependencies>
</profile>
<profile>
<id>profile2</id>
<dependencies>
<!-- Extra deps for this profile -->
</dependencies>
</profile>
</profiles>
</project>
IDEs commonly provides way to set profile, so devs should not have problem . From jenkins, are while building from command line you would be invoking command with given profile. You can have separate jobs or you can create your job with parameters.
mvn install -P profile1
Alternatively, profile can be activated by enviroment variable. Problem may be that this variable must be availble during compilation.
Another aproach would be branching your code for different customers as Abhilas mentioned in comment.
I'm using SonarQube 5.3 and working a mavenized java project containing 3 submodules.
One of this submodule is my webapp for which there are not junit test, I would like to remove it from the coverage % shown on the main sonar page.
Also if possible, I would like to exclude some package from the other submodule, like Entity package ...
Didn't find any clear answer, I tried to add this in my webapp pom.xml :
<sonar.coverage.exclusions>src/main</sonar.coverage.exclusions>
But no luck.
Set this through the UI in the Administration > General Settings > Analysis Scope > Code Coverage section
After fiddling around I found out that the UI parameter was not taken into account.
I'd to add this in my submodule pom.xml
I'm pretty sure I'd tried this earlier but since then we had updated Sonar version.
<properties>
<sonar.coverage.exclusions>src/main/java/**</sonar.coverage.exclusions>
</properties>
My application should work in 2 modes: standard and custom.
I am using the same classes but it can react little bit differently in different modes.
How better to inject this mode into all(not all but a lot) classes?
Application should be switched in run-time.
Not boot time.
I am using java8 and groovy.
Thanks!
Agree with Igor, probably spring profiles would be helpful for you. Also, I could suggest maven profiles (in case if you use maven as a build tool of course). For example, if you have two different modes "production" and "development" you can create two directories with property file props.properties and do the following with maven:
<profiles>
<profile>
<id>production</id>
<properties>
<resource.location>classpath:production</resource.location>
</properties>
</profile>
<profile>
<id>development</id>
<properties>
<resource.location>classpath:development</resource.location>
</properties>
</profile>
</profiles>
After this you are free to configure your spring property placeholer in this way
<context:property-placeholder location="${resource.location}/props.properties" ignore-unresolvable="true"/>
And build you app with
mvn install -Pdevelopment
mvn install -Pproduction
As per runtime switch, could you provide more details on your application. In case if it is a web application you could create some webservice for switching modes.
I've searched through several questions related to multi-module maven projects and sonar, but those were mostly about aggregating code coverage metrics.
I have a multi-module maven project being analyzed by sonar.
If I run the analysis straight from the terminal using mvn sonar:sonar the resulting analysis will display the dependencies between the maven modules in the Design page.
However, if I run the analysis by invoking sonar-runner via Jenkins the resulting analysis will have missed the dependencies between the maven modules.
Here's a snippet of the top-level pom where I set sonar parameters:
<profile>
<id>sonar</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<sonar.jdbc.url>
jdbc:mysql://myhost:3306/sonar?useUnicode=true&characterEncoding=utf8
</sonar.jdbc.url>
<sonar.jdbc.username>sonar</sonar.jdbc.username>
<sonar.jdbc.password>sonar</sonar.jdbc.password>
<sonar.host.url>http://myhost:9999</sonar.host.url>
<sonar.java.source>1.7</sonar.java.source>
<sonar.login>jenkins</sonar.login>
<sonar.password>jenkins</sonar.password>
</properties>
</profile>
On Jenkins I configured the job to do a clean install -DskipTests=true in the build step followed by a post-build action to run Sonar.
I'm using Maven version 3.0.5, SonarQube version 3.7, Sonar Runner 2.3 and Java 1.7.0_45.
Any idea of what can I be missing in my configuration?
Indeed the SonarQube Maven bootstrapper relies on Maven to get the dependencies (either on modules or on external libraries). But SonarRunner doesn't have access to such kind of information and that's why when you analyse a project with SonarRunner you don't get any information about external dependencies.
Ok if you are using Jenkins, you need to install Sonar Plugin and set parameters. Then, you need to create a job and run maven target:
clean install
After that, mark Sonar checkbok. Run your job and you should see your code coverage.
PS: If you are using module you must have pom-root with all your modules.
Is there a way to change the version number without editing the POM?
<groupId>org.example</groupId>
<artifactId>example</artifactId>
<version>1.0.0</version>
We have a CI system where we want to release nightly builds, but without using the -SNAPSHOT solution of Maven, so if 1.0.0 is the current version, we just want to have CI-NIGHTLY-BIULD-20120426.
I suggested this would be possible with something like mvn deploy -Dversion=CI-NIGHTLY-BIULD-20120426, but obviously not. The bad solution would be to let the CI server edit the pom.xml every time, but I think this is very unhandy.
Thank you!
I suggest to use classifier.
<groupId>foo</groupId>
<artifactId>bar</artifactId>
<version>1.0</version>
<properties>
<!-- default classifier is empty -->
<my.project.classifier></my.project.classifier>
</properties>
<build>
...
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<classifier>${my.project.classifier}</classifier>
</configuration>
<executions>...</executions>
</plugin>
</plugins>
</build>
and
mvn package -Dmy.project.classifier=NIGHTLY-2012-04-26_02-30
Maven documentation says about classifier:
classifier: You may occasionally find a fifth element on the
coordinate, and that is the classifier. We will visit the classifier
later, but for now it suffices to know that those kinds of projects
are displayed as groupId:artifactId:packaging:classifier:version.
and
The classifier allows to distinguish artifacts that were built from
the same POM but differ in their content. It is some optional and
arbitrary string that - if present - is appended to the artifact name
just after the version number. As a motivation for this element,
consider for example a project that offers an artifact targeting JRE
1.5 but at the same time also an artifact that still supports JRE 1.4. The first artifact could be equipped with the classifier jdk15 and the
second one with jdk14 such that clients can choose which one to use.
Another common use case for classifiers is the need to attach
secondary artifacts to the project's main artifact. If you browse the
Maven central repository, you will notice that the classifiers sources
and javadoc are used to deploy the project source code and API docs
along with the packaged class files.
I think you could also use versions maven plugin. I find it quite useful for things like this.
You could do it in 2 steps:
set necessary version: mvn versions:set -DnewVersion=CI-NIGHTLY-BIULD-20120426
deploy: mvn deploy
in case you need to revert back the changes, use mvn versions:revert (as Mark suggests)
I highly recommend reading Maven Releases on Steroids (part 2, part 3) by Axel Fontaine. It is great, and I'm quite happy using it.
It not only details how you con do what you ask, but also contains good advice how you can tie your build versions with your CI server.
In a nutshell, here are the main points:
Maven Release is slow, needs to be done faster
You parametarize your project version like
<version>${VERSION_NUMBER}</version>
...
<properties>
...
<VERSION_NUMBER>1.0-SNAPSHOT</VERSION_NUMBER>
...
</properties>
Local builds get that version: 1.0-SNAPSHOT
Release builds are done only from your CI server
In your Jenkins/Hudson project configuration you use
clean deploy scm:tag -DVERSION_NUMBER=${BUILD_NUMBER}
That way you get a new release with each Jenkins build, not only nightly.
You can change the configuration to use
clean deploy scm:tag -DVERSION_NUMBER=1.0.0-CI-NIGHTLY-BIULD-${BUILD_ID}
and you would get versions like 1.0.0-CI-NIGHTLY-BIULD-2012-04-26_12-20-24
You could parameterize the version number as
<groupId>foo</groupId>
<artifactId>bar</artifactId>
<version>${my.project.version}</version>
<properties>
<my.project.version>1.0</my.project.version>
</properties>
and drive the version number from command line using
mvn package -Dmy.project.version=NIGHTLY
Although this is possible, Maven 3 discourages it.