Analyzing Groovy / Grails code

le 19/10/2010 par Cyril Picat
Tags: Software Engineering

Groovy and Grails are a breeze of fresh air in Java development and Web application development as they enable you to write far more expressive and readable code. They also solve most of the classic Java pitfalls (BigDecimal, equals(), etc…) all new Java programmers meet along their way. Even if you write more readable and thus more maintainable code in Groovy, this is not enough let alone: of course you need some good practices to keep your code under control as your application keeps growing.

One of these practices would be to analyze your source code and check how metrics and static checks evolve from release to release, or even on a more sporadic way for a specific release. In this field I must say that the Java programmer is one of the best tooled as there are plenty of choices, free or not, for performing such a task (PMD, FindBugs, CheckStyle, Sonar etc…). So, what about it in Groovy / Grails?

Tools available in Groovy and what they do

Groovy eco-system is far smaller than in Java when talking about code analysis tools. Basically you will find:

  • GMetrics: available either standalone or as a Grails or Griffon (Grails twin brother for RDA) plugin, it computes very basic metrics on your code. By default those are lines per method, lines per class and cyclomatic complexity. Very basic but very useful.
  • CodeNarc: available standalone, as a Grails/Griffon plugin and also as a Gradle (a groovier build system) plugin. It performs static source code analysis, thanks to a set of rules. It performs checks similar to what CheckStyle and PMD do. It has rules for Groovy code but also a set of specific rules for Grails. As an example of Groovy rules, it will find all sort of empty blocks, problem with generic throw/catch, etc… It will also enable you to define naming conventions or to define thresholds on code complexity. Concerning Grails rules, it will for example check that your Services are stateless as expected.
  • Sonar: actually we are talking about a plugin for Sonar. This is something very new as the plugin is in version 0.2 and had its first release in August this year… Version 0.2 added support for test reports and test coverage. The plugin relies mainly on CodeNarc and GMetrics as well as on Squid (rewrite of JavaNCSS by SonarSource) for some basic metrics. Although in version 0.2, it seems quite usable and I did not find too much trouble using it. It gives you all the power of Sonar: managing the software quality in an integrated tool and being able to see your quality evolving as time passes. Compared to the tools above, it will also give you the duplicated code, which is something definitively very useful.

Groovy is Java, isn't it? What about the other Java tools?

Can they work or not on Groovy code? Of course we haven't tried all of them but basically you will find two categories of tools:

  • those that work on source code (CheckStyle, PMD etc…): they won't work at all because their parser will surely fail on Groovy code. Note that, for example, you can still use PMD (CPD) to find duplicated code as it actually works for all languages (C, C++, Python etc…).
  • those that work on bytecode (XDepend, FindBugs etc…): they will be able to work but will generate all kind of noises. For example you will get plenty of warnings due to the Groovy framework if you run FindBugs on a Groovy application. In the same way, if you run XDepend on a Grails application, you will get weird dependencies due to Groovy internals (for example Groovy generates one class per closure using a naming convention) or to Grails internals (all GSPs will appear to be very long Groovy methods). I don't believe running Findbugs would make any sense but being able to use XDepend would be great of course, no matter what your language is.

So all those tools are of little help for what we are looking for!

Are we looking for the right tools for Groovy?

As Java programmers, we hope to find in Groovy / Grails eco-system the same tools we are used to in Java. What a shame there isn't a FindBugs for Groovy! But does it make sense?

Groovy is by nature a dynamic language and of course you don't develop code in the same way you develop it with a static language. Groovy is both weakly and strongly typed, as you wish, but is very often used with weak typing (I think I should say duck typing actually, see here). Of course there is a strong emphasis on tests in dynamic languages if you want your software to be both reliable and maintainable. But as mentalities evolve, I would say this is no more a difference between static and dynamic languages given tests have taken such an importance as well for static languages. We no longer ensure code quality afterwards by running analysis tools but we do ensure it beforehand by testing in TDD.

To make a long story short, I would say that the code coverage is thus one of the most important metric to watch, more than all the metrics and potential bugs that these tools can compute. Good news, there is a code coverage plugin for Grails which is called Test Code Coverage Plugin. It uses Cobertura underneath as Cobertura has a support for the Groovy language (Clover too).

To make my short story even shorter: we won't necessarily miss all these analysis tools we have in Java.

Of course the usefulness of all these tools is highly context-dependent and you might be in a context where you will truly miss one of these tools. For example I would truly miss Checkstyle, Findbugs and PMD in a project with several team members and different skill levels. Or I would truly miss XDepend in a big project where project architecture has been lost or is undefined. No doubt the support for Groovy in this kind of tools will grow if Groovy / Grails make their way in the enterprise or continue to spread in the small to mid-size projects where they are currently used. As usage will increase, anti-patterns will become clearer and enable this kind of tools to become more useful.

The final setup is…

Sonar looks like the perfect fit for the job even if the plugin is still in its early stage. Note, if you are already using a Hudson or plan to setup one, you could setup most of the above tools (CodeNarc, CPD, Cobertura etc...) in your Hudson.

Actually, even if Sonar is really easy to install, analyzing a Grails project with it is a little bit trickier.

Here is how to proceed:

Step 1: Install Sonar and Groovy plugin

Basically you just have to download Sonar and unzip it wherever you want. Then you download Groovy plugin for Sonar and you copy the downloaded JAR in [sonar]/extensions/plugins where [sonar] is the directory where you extracted Sonar ZIP file.

At last you run Sonar server, using sonar.sh or StartSonar.bat depending on you platform. For more info, see their 2-minutes tutorial.

Step 2: Configure your Grails project

A good starting point is the plugin home page. It is only valid for a Groovy project, setting up a Grails project is slightly different.

You have basically two choices:

1. Not-mavenized Grails project

This is, interestingly, my recommended approach. Actually this is the one that works best at this time. For this you need;

  • to install Grails Test Code Coverage plugin by running: $ grails install-plugin code-coverage- to configure Cobertura to generate the XML report needed by Sonar. For this, add these lines to your grails-app/conf/BuildConfig.groovy file:
coverage {
	enabledByDefault = false
	xml = true
}
  • to add a pom.xml file at the root of your project with the following content:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.yourcompany</groupId>
  <artifactId>yourproject</artifactId>
  <version>1.0</version>
  <packaging>pom</packaging>
  <name>Your Project</name>
  <build>
    <sourceDirectory>grails-app</sourceDirectory>
        <plugins>
           <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-compiler-plugin</artifactId>
              <configuration>
                  <source>1.6</source>
                  <target>1.6</target>
                  <excludes>
                      <exclude>**/*.*</exclude>
                  </excludes>
              </configuration>
           </plugin>
           <plugin>
              <groupId>org.codehaus.mojo</groupId>
              <artifactId>build-helper-maven-plugin</artifactId>
              <version>1.1</version>
              <executions>
                <execution>
                  <id>add-source</id>
                  <phase>generate-sources</phase>
                  <goals>
                      <goal>add-source</goal>
                  </goals>
                  <configuration>
                      <sources>
                          <source>src/groovy</source>
                          <source>src/java</source>
                      </sources>
                  </configuration>
                </execution>
              </executions>
           </plugin>
        </plugins>
  </build>
  <properties>
    <sonar.language>grvy</sonar.language>
    <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
    <sonar.surefire.reportsPath>test/reports</sonar.surefire.reportsPath>
    <sonar.cobertura.reportPath>test/reports/cobertura/coverage.xml</sonar.cobertura.reportPath>
    <sonar.phase>generate-sources</sonar.phase>
  </properties>
</project>
  • to generate the tests report and coverage before running Sonar analysis $ grails test-app -coverage
2. Mavenized Grails project

This setup is easier but, at the time of writing it out, you will get a few limitations. This is what you need to add in your POM:

  • tell Sonar your are analyzing Groovy code
<properties>
    <sonar.language>grvy</sonar.language>
 </properties>
  • setup the path for your source code (more on this later)
<build>
    <sourceDirectory>grails-app</sourceDirectory>
</build>
  • change the Surefire report path to match grails' one
<build>
   <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.6</version>
	<configuration>
	  <reportsDirectory>${project.build.directory}/test-reports</reportsDirectory>
	</configuration>
      </plugin>
   </plugins>
</build>

This is it!

Step 3: Enjoy!

You just need to run the following command at the root of your Grails project (make sure Sonar is running, refer to Step 1): $ mvn sonar:sonar

Then go to Sonar web interface by browsing to http://localhost:9000/ and enjoy it!

You will get the standard Sonar dashboard you are certainly used to:

Screenshot of Sonar dashboard on a Grails project

Be aware you will have to configure CodeNarc and CPD to only report warnings and errors you really want your team to fix. This is the hardest part in setting up this kind of tools on a project.

Step 4: Hold on there, there are still a few limitations...

The plugin has a few limitations, the greatest one being the problem in parsing some Groovy files (see SONARPLUGINS-596). It has obviously an impact on the report because the figures, violations and duplications will completely ignore the files in error. It will be interesting for you to see which files are impacted by looking at the stack traces when running 'mvn sonar:sonar'.

Otherwise, if you use Maven, you get a few more limitations: - Sonar Groovy plugin only locates your source files by the use of the sourceDirectory parameter therefore with the above setting (set to grails-app/), files in src/groovy and src/java won't be included in the analysis results (see SONARPLUGINS-737) - the analysis won't work if one of your tests is failing (unfortunately Grails Maven plugin ignores the parameter -Dmaven.test.failure.ignore=true, see GRAILS-6850)

Nothing else?

There is one last point about source code quality we did not mentioned at all in this article, which is the IDE. Of course the IDE is of great help to manage source quality at the root by the use of JavaDoc, code completion and refactoring, but also through the use of all sort of plugins (often the same tools as mentioned above). The same is true in Groovy and using a good IDE is certainly a productivity and quality boost. You will even find in IntelliJ IDEA checks on what is call 'idiomatic Groovy' - or Groovy code inspections. This is a broad subject and would be for sure an interesting subject to dig further in another article.

But here also, you could ask yourself are you really looking for the right tool? You will see plenty of Grails or Ruby on Rails developers going back to the use of a clever text editor like TextMate instead of the big IDE we are used in Java. In fact I am not sure they are wrong, depending of course on the size of the project they are presently working on...

Follow @cyrilpicat