In the first post I discussed different kinds of quality and gave some reasons on why the quality tends to suffer as project grows. In this post I’ll try to give some hints on how to keep quality high. If we have our quality goal set then we must use proper tools and actions to enforce the quality. Enforce is a good word here, because quality must be enforced after being measured, because there is a lot of different inputs and changes in today’s projects. Requirements change, developers change, libraries change. We must adapt quickly and provide fast feedback about quality. Sounds like Continuous Integration ? 🙂 Traditional Continuous Integration does include running various tests – unit tests, integration tests mostly, but other tests can also be executed. In case of some projects, for which quality goals include matters like high performance requirements or high security requirements, we must execute performance and security tests on CI server. Not on every build, event not in a build pipeline started by SCM change, but according to a schedule, like nightly builds. If we add this and add some static analysis tools that the process is something more than Continuous Integration, it is Continuous Inspection. Why do this inspections of CI server? Well, I’m fan of automation – Jenkins, Hudson, Bamboo or some other CI server does not get tired (if we don’t include build queues and garbage collection 😉 – but here we can change the CI process or add hardware to run more smoothly), it does not have bad days, does not need coffee and doesn’t fall asleep when reviewing class change number 53. But let’s get down to the trenches
Here’s what we can monitor (a non-comprehensive list):
- Code standards – we can use Checkstyle, PMD or some other tool
- Code metrics – here we can use Checkstyle, Sonar, Dependometer, JDepend
- Library and classpath issues – JBoss Tattletale
- Architecture and design issues – Sonar, Dependometer, Structure101, Sonargraph, JDepend
- Potential bugs – Findbugs, Sonar (including security issues)
- Bad practices – PMD
- Potential security vulnerabilities – Sonar, ZED Attack Proxy
- Insufficient test coverage – JaCoCo (we can break the build if test coverage is not met)
There are more tools (see this link), but I focus here on tools that I have experience with and that can be integrated with Continuous Integration server. Check Google CodePro Analytix – an excellent developer desktop tool to analyze code – plus it it helps to write unit tests, generated comment skeletons. Check tools for architects that can compute quality metrics, visualize code structure and perform simulated refactorings – Dependometer, Sonargraph (a.k.a. SonarJ) and Structure101. Of course JBoss Tattletale also does dependencies visualization but can’t simulate refactoring.
In my opinion Sonar is underestimated tool for a few reasons:
- It still grows and new things are being added that go unnoticed (like provisioning and disabling automatic project creation)
- It gets misused often – I’ve seen many time Sonar without custom rule sets, that shows like half a million of Dead Local Storage or unnecessary Boxing (BX_BOXING_IMMEDIATELY_UNBOXED) reported on critical (DLS) or major (Boxing) level, that while being important and being a code smell are not critical or even major for 99% projects out there. Here the problem is half a million of one issue report not that the code uses autoboxing and the immediately unboxes.
- Often the quality gates feature is not used
- Sonar can and will report false positives, so again it must be configured and used appropriately
To use sonar effectively we must configure it according to our projects standards and use quality gates. It should be plugged in into CI process – that is the main point of this discussion, but it can be also used by developers on their desktops. And since using CI server plugin is also more popular I will discuss the usage of Maven plugin that can be used as part of CI build pipeline or on developer desktop.
To maximize the profits from introducing Sonar we want to automate the process then we want the CI server to notify us of error found. We can do this by using Maven and Sonar – if quality of project is below some threshold than the build will be broken by sonar or maven plugin. Static analysis of code with Sonar (including Checkstyle, PMD and Findbugs) is pretty popular so I won’t write about it. But what is maybe not so well known and popular is that we can use Sonar to check some architectural constraints like:
- Dependency direction
This checks can be implemented in Dependometer or straight in Sonar. Using Dependometer gives more flexibility (like Structure 101), but Sonar provides possibility to break the build as feedback. I like this option, as this forces attention. Sadly there is no Dependometer plugin for Sonar, so we must integrate it with Maven and use build project using Maven on CI server.
In order to analyze project in Sonar we can use CI server plugin or Maven. Below is example fo maven configuration
<!-- important - sonar analyzers store data in this db,
this must be the same as the db used by sonar web app! -->
You can find full list of analysis parameters in Sonar documentation, I don’t want to repeat these docs 🙂 Important thing to note is that we provide Sonar database property as Sonar Maven plugin is an analyzer and stores information in the database so it need to be the same as the one used by Sonar Web app.
We can also use e.g. Jenkins plugin to integrate sonar with Jenkins. After we do this we are able to inspect the code on various levels as Sonar has plugins for Findbugs, Checkstyle, Structure101, JBoss Tattletale (unofficial), PMD and can large rule base of its own (e.g. OWASP TOP 10 violations).
Adding architectural constraint in Sonar is simple – in Rules we search for Architectural constraint and click into the rule
Then we enter name pattern of source and target package specifying that source package can’t depend on target package
In Dependometer we can enter allowed dependencies and specify threshold on various metrics. Specifying allowed dependencies is more convenient in my opinion by both ways give us what we wanted. We monitor no not only project standards, inspect code for bad practices, check for possible bugs but also look for layering violations, cycles, code that can be difficult to extend or maintain (complex, tangled, unstable). Tattletale can check if there are duplicated libraries in our application deployment archive (WAR, EAR – after doing some tricks). Now we have Continuous Inspection 🙂
Hav en dejlig dag !