Thursday, April 5, 2012



Part 3: Play Application - Code analysis with Sonar

In CI Part 1 I have shown you how to configure Play Framework, how to configure the Jenkins Play Plugin.
In CI Part 2 I have shown you how to post your modules to a Nexus server, how to use the repository in the dependencies file, chained dependencies, continuous integration and auto deploy.
In this post I will show you how to do code analysis with Sonar for a !Play application.

Intro

The Play Framework is new around the block so the written is "not so pure OO code"(lots of static methods or POJOs with public fields) so the default sonar rules are violated. Because of this you will need to customize the sonar rules.
I have checked the web for sonar play plugin but didn't found anything so I have used the sonar-ant-task v.1.3.

Before going ahead check if you have the !Play framework installed. If not read CI Part 1 to see how to install it. Also you will need Ant installed on your machine.


Configure Ant on your machine

If you already have Ant installed then you can skip this section.

Download ant from here. Next follow the installation steps:

1. Unzip ant
    tar apache-ant-1.8.2-bin.tar.gz /destionation (hope this command is ok)
2. Create symbolic link to ant (this will help you at version upgrades)
    ln -s /destination.apache-ant-1.8.2 ant
3. Add ant to path. You will need to edit the profile file(usually is located in /etc folder)
    vi /etc/profile
    Add this to at the end of the file:
    ANT_PATH=/destination/ant
    export ANT_PATH

   PATH=$PATH:$ANT_PATH/bin
   export PATH
4. Logout so the paths are updated.

There you are, ant is installed and added to path; ant is ready to use.

Install sonar-ant-task

Download the sonar-ant-task from here.
Copy it in ant libs folder /destination/apache-ant-1.8.2/lib

Configure ant build with sonar task

Bellow is the basic build.xml for your play app and it should be located in your play app root folder.

<project basedir=".">
<property environment="env" />
<!-- We need the play path in the path -->
<property name="play.path" value="${env.PLAY_PATH}" />
<!-- We need the ant path in the path -->
<property name="ant.path" value="${env.ANT_PATH}"/>
<!-- Use the default play build.xml -->
<import file="${play.path}/resources/application-build.xml" />
<!-- Use sonar ant task -->
<taskdef uri="antlib:org.sonar.ant" resource="org/sonar/ant/antlib.xml" >
       <classpath path="${ant.path}/lib/sonar-ant-task-1.3.jar"/>
</taskdef>
<!-- The sonar task code analysis -->
<target name="sonar">
       <!-- Project name -->
       <property name="sonar.projectName" value="MyProjectName" />
       <!-- Location of the compiled classes -->
       <property name="sonar.binaries" value="precompiled/java/controllers"/>
       <!-- Source folder -->
       <property name="sonar.sources" value="app"/>
       <!-- Sonar hist -->
       <property name="sonar.host.url" value="localhost:9000"/>
       <property name="sonar.jdbc.url" value="jdbc:derby://localhost:1527/sonar"/>
       <property name="sonar.jdbc.driverClassName" value="org.apache.derby.jdbc.ClientDriver"/>
       <property name="sonar.jdbc.username" value="sonar" />
       <property name="sonar.jdbc.password" value="sonar" />
       <property name="sonar.dynamicAnalysis" value="reuseReports" />
       <property name="sonar.surefire.reportsPath" value="test-result" />
       <property name="sonar.cobertura.reportPath" value="test-result/code-coverage/coverage.xml" />
       <!-- This will create a project in sonar -->
       <sonar:sonar key="org.example:MyProjectName" version="0.1-SNAPSHOT" xmlns:sonar="antlib:org.sonar.ant"/>
</target>
<!-- Cleanup test results task -->
<target name="clean-tests-results">
    <delete dir="test-result" />
</target>
<!-- Run play auto-test comand -->
<target name="autotest">
     <exec executable="play">
         <arg value="auto-test" />
     </exec>
</target>
<target name="compile">
     <exec executable="play">
         <arg value="precompile" />
     </exec>
</target>
<!-- Run play auto-test comand -->
<target name="quality" depends="clean-tests-results, compile, autotest, sonar" />
</project> 

You are ready to do some code analysis, just run this command:
> ant quality

Code analysis takes some time but does the job.

Configure Jenkins job

I am a lazy person and I don't want to run what ever command to do the code analysis so I'll configure a Jenkins job so it will do all the hard work for me. 
If you don't have Jenkins CI installed check the my previous two post about continuous integration to see how it's done.

To configure a Jenkins job with ant is simple:

1. Create a new Jenkins job with and build
2. Fill in the targets field with: quality
3. Fill in Build file field: MyProjectName/build.xml
4. Save and you are done.


Conclusion

So there you are boys and girls: continuous integration with code analysis using sonar. I still have to customize the sonar rules.

2 comments:

  1. Really cool stuff, thx.
    I just had to change the sonar.host.url to http.

    ReplyDelete
  2. Hi, I am trying to use sonar with play 2.1.4 but it seems, does not work. I am really stuck on Sonar, Play 2.1.4 (my application is multi-module app), jenkins. Help is really appreciated,
    Thanks in advance

    ReplyDelete