I recently found out about Sonar after finding issues with running Cobertura on multi-module maven projects (see nabble post). Sonar looked like it solved this issue and added a whole stack more insight into the code quality of a project.
I got a Sonar demo up and running fine locally and convinced my team it would be a benefical tool for us to use so the next step for me was to install Sonar on our development box and integration it with our CI server, Hudson.
There seems to be two ways you can achieve Sonar and Hudson integration:
- Use the Sonar Hudson plugin and run Sonar as an ‘after build’ task
- Run mvn sonar:sonar in a within Hudson
I had a lot of issues trying to get the plugin to work so I ended up going with option 2. Below are the steps I took to get it to work.
- Firstly you need to download and install Sonar. You can do this buy executing the run script or by building and deploying the war file into an applicaiton server. I had issues with Glassfish so I just opted for running it from the run script and for now, I just stuck with the default Derby database.
- Starup Sonar and browse to http://hostname:9000 to make sure it’s up and running.
- Edit the maven settings.xml that is located on the same machine as your Hudson server and add in the following
- Now you can create a new job in Hudson and run it with the following maven command:
clean install sonar:sonar
That’s it! You should be able to browse to your sonar page and see your project there with coverage results. I had my job execute ever day at 11pm rather than on SVN commit.
It’s worth pointing out that the above mvn command will run the tests twice, firstly during install and secondly during sonar:sonar. Take a look here for more info. In order to speed this up it might be worth adding in the following paramater at the end of the command:
If you want to generate sonar results even if the build fails add this paramater
All together that would be:
clean install sonar:sonar -Dsonar.dynamicAnalysis=reuseReports -Dmaven.test.failure.ignore=true
Add in a new repository under your exising one.
<repository> <id>sonar</id> <name>Sonar Repository</name> <snapshots> <updatePolicy>daily</updatePolicy> <checksumPolicy>ignore</checksumPolicy> </snapshots> <url>http://hostname:9000/deploy/maven</url> </repository>
Add in a new sonar profile
<profile> <id>sonar</id> <activation> <activeByDefault>true</activeByDefault> </activation> <properties> <sonar.jdbc.url> jdbc:derby://localhost:1527/sonar;create=true </sonar.jdbc.url> <sonar.jdbc.driver>org.apache.derby.jdbc.ClientDriver</sonar.jdbc.driver> <sonar.jdbc.username>sonar</sonar.jdbc.username> <sonar.jdbc.password>sonar</sonar.jdbc.password> <sonar.host.url>http://hostname:9000</sonar.host.url> </properties> </profile>
update your nexus mirror
<mirror> <id>hsl-repository-mirror</id> <mirrorOf>*,!sonar</mirrorOf> <url>http://maven-repository:8181</url> </mirror>
If you you are getting out of memory exceptions, consider editing the MAVEN_OPTS under Advanced in your job configuration to have the following value: