Viewing entries tagged
maven

Code Quality Unravelled: Part 2 Maven Multimodule Support in Your Site

Comment

Code Quality Unravelled: Part 2 Maven Multimodule Support in Your Site

This is the second installment in a series of posts about code quality, the tools that are available to track quality, and how to configure various systems to get all of the reporting.  There are a lot of posts on the internet about all of the tools and configurations that I'm going to describe, however, I thought it would be useful to have it all in one place.


Code Quality Unravelled: Part 1


What are multi-module projects?

There are times when you have a project that is made up of many components that you want to build together. When you have this setup there is a parent pom.xml and then each module is in a sub directory with its own pom.xml.

Aggregating Results

Multi-module projects have the ability to aggregate the quality reports and project information into one site. The site will include links to drilldown into each module as well as rolled up reports.

JXR, Javadoc, Checkstyle, JavaNCSS

Some plugins know how to handle aggregation without any extra configuration. JXR, Javadoc, Checkstyle, and JavaNCSS support aggregation with the same configuration that I listed in Part 1.


<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jxr-plugin</artifactId>
  <version>2.5</version>
</plugin>

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-javadoc-plugin</artifactId>
  <version>2.10.3</version>
  <configuration>
    <additionalparam>-Xdoclint:none</additionalparam>
  </configuration>
</plugin>

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-checkstyle-plugin</artifactId>
  <version>2.16</version>
</plugin>

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>javancss-maven-plugin</artifactId>
  <version>2.1</version>
</plugin>

Cobertura

Adding aggregation to Cobertura is as simple as adding an aggregate tag to the configuration section.


<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>cobertura-maven-plugin</artifactId>
  <version>2.7</version>
  <reportSets>
    <reportSet>
      <id>cobertura</id>
      <reports>
        <report>cobertura</report>
      </reports>
      <configuration>
        <aggregate>true</aggregate>
        <formats>
          <format>html</format>
          <format>xml</format>
        </formats>
      </configuration>
    </reportSet>
  </reportSets>
</plugin>

PMD/CPD, Surefire, and Taglist

In order to add aggregation for PMD, CPD, Surefire, and Taglist you need to add separate reportSets one for the individual module and one for the aggregate.


<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-pmd-plugin</artifactId>
  <version>3.5</version>
  <reportSets>
    <reportSet>
      <id>pmd-report</id>
      <reports>
        <report>pmd</report>
      </reports>
      <configuration>
        <skipEmptyReport>false</skipEmptyReport>
      </configuration>
    </reportSet>

    <reportSet>
      <id>pmd-aggregate</id>
      <inherited>false</inherited>
      <reports>
        <report>pmd</report>
      </reports>
      <configuration>
        <aggregate>true</aggregate>
        <skipEmptyReport>false</skipEmptyReport>
      </configuration>
    </reportSet>

    <reportSet>
      <id>cpd-report</id>
      <reports>
        <report>cpd</report>
      </reports>
      <configuration>
        <skipEmptyReport>false</skipEmptyReport>
      </configuration>
    </reportSet>

    <reportSet>
      <id>cpd-aggregate</id>
      <inherited>false</inherited>
      <reports>
        <report>cpd</report>
      </reports>
      <configuration>
        <aggregate>true</aggregate>
        <skipEmptyReport>false</skipEmptyReport>
      </configuration>
    </reportSet>
  </reportSets>
</plugin>

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-report-plugin</artifactId>
  <version>2.18.1</version>
  <reportSets>
    <reportSet>
      <id>unit-tests</id>
      <reports>
        <report>report-only</report>
      </reports>
      <configuration>
        <linkXRef>true</linkXRef>
        <alwaysGenerateSurefireReport>true</alwaysGenerateSurefireReport>
      </configuration>
    </reportSet>

    <reportSet>
      <id>unit-tests-aggregate</id>
      <inherited>false</inherited>
      <reports>
        <report>report-only</report>
      </reports>
      <configuration>
        <aggregate>true</aggregate>
        <linkXRef>true</linkXRef>
        <alwaysGenerateSurefireReport>true</alwaysGenerateSurefireReport>
      </configuration>
    </reportSet>
  </reportSets>
</plugin>

<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>taglist-maven-plugin</artifactId>
  <version>2.4</version>
  <reportSets>
    <reportSet>
      <id>taglist-report</id>
      <reports>
        <report>taglist</report>
      </reports>
      <configuration>
        <tagListOptions>
          <tagClasses>
            <tagClass>
              <displayName>Todo Work</displayName>
              <tags>
                <tag>
                  <matchString>todo</matchString>
                  <matchType>ignoreCase</matchType>
                </tag>
                <tag>
                  <matchString>FIXME</matchString>
                  <matchType>exact</matchType>
                </tag>
              </tags>
            </tagClass>
            <tagClass>
              <displayName>Architecture Review Needed</displayName>
              <tags>
                <tag>
                  <matchString>ARCH-REV</matchString>
                  <matchType>exact</matchType>
                </tag>
              </tags>
            </tagClass>
          </tagClasses>
        </tagListOptions>
      </configuration>
    </reportSet>

    <reportSet>
      <id>taglist-aggregate</id>
      <inherited>false</inherited>
      <reports>
        <report>taglist</report>
      </reports>
      <configuration>
        <aggregate>true</aggregate>
        <tagListOptions>
          <tagClasses>
            <tagClass>
              <displayName>Todo Work</displayName>
              <tags>
                <tag>
                  <matchString>todo</matchString>
                  <matchType>ignoreCase</matchType>
                </tag>
                <tag>
                  <matchString>FIXME</matchString>
                  <matchType>exact</matchType>
                </tag>
              </tags>
            </tagClass>
            <tagClass>
              <displayName>Architecture Review Needed</displayName>
              <tags>
                <tag>
                  <matchString>ARCH-REV</matchString>
                  <matchType>exact</matchType>
                </tag>
              </tags>
            </tagClass>
          </tagClasses>
        </tagListOptions>
      </configuration>
    </reportSet>
  </reportSets>
</plugin>

Not Everyone Plays Nicely

Unfortunately, not all of the reports we have talked about support aggregation. FindBugs and JDepend do not support aggregation, so when you run site you will have to look at these reports within each module instead of at the top level page. You can find more information about why FindBugs doesn't support this on the FindBugs site.

Generating the site

In addition to running the site report as I described in Part 1, there are a few other goals for the site plugin.

  • mvn site:site
    • Runs the site report putting the output in target/site
  • mvn site:stage
    • Runs the site report putting the output in target/staging
  • mvn site:deploy
    • Runs the site report and deploys the output to a location specified in a <distributionMangement> block

The generated reports contain deficiencies that you should be aware of:

  • Running maven site (or site:site) on a multi-module project will create links to the sub-modules that do not work. To get the links to work you will have to run site:stage or site:deploy after site:site.
  • For some reason when running site:stage, the cobertura report is a blank page. You can find the aggregate report for this in the target/site location.
  • The Surefire Report shows zeros for everything in the rolled up report, but the module reports still contain the information.

For a sample project that includes all of these reporting sections check out the repo on Github.


Code Quality Unravelled: Part 1


Comment

Code Quality Unravelled: Part 1 Building a Maven Site

Comment

Code Quality Unravelled: Part 1 Building a Maven Site

This is the first installment in a series of posts about code quality, the tools that are available to track quality, and how to configure various systems to get all of the quality reporting.  There are a lot of posts on the internet about all of the tools and configurations that I'm going to describe, however, I thought it would be useful to have it all in one place.


Code Quality Unravelled: Part 2


Building a Maven Site

Apache Maven is a build tool for Java. There are a ton of plugins to have your build do all sorts of processing and reporting. One of the key components of Maven is the site report. The site report collects all sorts of information about your project including descriptive information, contact information, license information and also various reports.

The pom.xml file is the place where you can configure all of the build information, dependencies, and reporting tools. The Apache Maven site has a great reference to all of the various components that make up a pom file. For the purposes of this post, I am going to focus on the reporting section of the pom file.

NOTE: This post was written using Maven version 3.2.3.


<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.mycompany</groupId>
    <artifactId>test-java-build</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>test-java-build</name>

    <properties>
      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <reporting>
      <plugins>
        <!-- This is where we will focus -->
      </plugins>
    </reporting>
</project>

There are a lot of reports that can be generated on the code base using Maven. I'm going to go over how to setup and configure the following tools: Cobertura, PMD/CPD, JXR, Javadoc, Surefire, FindBugs, JDepend, Taglist, Checkstyle.

Cobertura

Cobertura is a tool to report on the amount of code being covered by automated tests.


<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>cobertura-maven-plugin</artifactId>
    <version>2.7</version>
    <reportSets>
      <reportSet>
        <id>cobertura</id>
        <reports>
          <report>cobertura</report>
        </reports>
        <configuration>
          <formats>
            <format>html</format>
            <format>xml</format>
          </formats>
        </configuration>
      </reportSet>
    </reportSets>
</plugin>

This block will cause cobertura to generate the report in both xml and html format. You can find other configuration options on the plugin site. NOTE: If you are using Java 8 (specifically the new syntax) and start seeing stack traces referencing JavaNCSS, make sure you upgrade to version 2.7 of this plugin. This version brings in Cobertura 2.1.x which supports Java 8 correctly.

PMD/CPD

PMD analyzes your source code finding common programming flaws. CPD (Copy-paste-detector) also comes with PMD and looks for duplicate code in your project.


<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-pmd-plugin</artifactId>
    <version>3.5</version>
    <reportSets>
      <reportSet>
        <id>pmd-report</id>
        <reports>
          <report>pmd</report>
        </reports>
        <configuration>
          <skipEmptyReport>false</skipEmptyReport>
        </configuration>
      </reportSet>

      <reportSet>
        <id>cpd-report</id>
        <reports>
          <report>cpd</report>
        </reports>
        <configuration>
          <skipEmptyReport>false</skipEmptyReport>
        </configuration>
      </reportSet>
    </reportSets>
</plugin>

This block will run both PMD and CPD and include the reports regardless of whether there are issues detected or not. Plugin configuration options can be found on the plugin site. One key section to take a look at in the documentation is the Rule Set section. This shows you how to define or customize the rules you want PMD to check against.

JXR

JXR is plugin that produces an html view of all of the source in the project. This plugin is also used by other reports in order to link directly to the source.


<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jxr-plugin</artifactId>
    <version>2.5</version>
</plugin>

Javadoc

The Javadoc plugin will generate the Javadoc for your project and include the documentation in the site output.


<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-javadoc-plugin</artifactId>
    <version>2.10.3</version>
</plugin>

Note: if using JDK 8 or newer, the Javadoc command has added a strict validator that checks for broken references and invalid HTML. This validator will fail the build if it finds anything it deems unacceptable. There is a good run down on this behavior on this blog. To have maven still present the warnings but not fail the build a configuration section can be added to the plugin definition like so:


<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-javadoc-plugin</artifactId>
    <version>2.10.3</version>
    <configuration>
      <additionalparam>-Xdoclint:none</additionalparam>
    </configuration>
</plugin>

JavaNCSS

The JavaNCSS Plugin generates metrics for quality and complexity on the project.


<plugin>
  <groupId>org.codehaus.mojo</groupId>
  <artifactId>javancss-maven-plugin</artifactId>
  <version>2.1</version>
</plugin>

Surefire

The Surefire Report Plugin generates a nice easy to read report of all of your test results.


<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-report-plugin</artifactId>
    <version>2.18.1</version>
    <reportSets>
      <reportSet>
        <id>unit-tests</id>
        <reports>
          <report>report-only</report>
        </reports>
        <configuration>
          <linkXRef>true</linkXRef>
          <alwaysGenerateSurefireReport>true</alwaysGenerateSurefireReport>
        </configuration>
      </reportSet>
    </reportSets>
</plugin>

This block will generate the surefire report without running the tests a second time (the default report "report" type runs the tests twice). The configuration option linkXRef links the line references in the tests to the actual source provided by JXR. The alwaysGenerateSurefireReport option will generate the surefire report whether all of the tests pass or not.

FindBugs

FindBugs analyzes the code looking for potential bugs.


<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>findbugs-maven-plugin</artifactId>
    <version>3.0.2</version>
</plugin>

JDepend

JDepend looks through the source tree analyzing the quality of the code in terms of extensibility and reusability.


<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>jdepend-maven-plugin</artifactId>
    <version>2.0</version>
</plugin>

Taglist

The Taglist plugin searches the code for various defined tags that are used to highlight areas of code that need more attention (e.g. TODO and FIXME).


<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>taglist-maven-plugin</artifactId>
    <version>2.4</version>
    <reportSets>
      <reportSet>
        <id>taglist-report</id>
        <reports>
          <report>taglist</report>
        </reports>
        <configuration>
          <tagListOptions>
            <tagClasses>
              <tagClass>
                <displayName>Todo Work</displayName>
                <tags>
                  <tag>
                    <matchString>todo</matchString>
                    <matchType>ignoreCase</matchType>
                  </tag>
                  <tag>
                    <matchString>FIXME</matchString>
                    <matchType>exact</matchType>
                  </tag>
                </tags>
              </tagClass>
              <tagClass>
                <displayName>Architecture Review Needed</displayName>
                <tags>
                  <tag>
                    <matchString>ARCH-REV</matchString>
                    <matchType>exact</matchType>
                  </tag>
                </tags>
              </tagClass>
            </tagClasses>
          </tagListOptions>
        </configuration>
      </reportSet>
    </reportSets>
</plugin>

This block configures taglist to search for the TODO tag (regardless of case), FIXME tag, and a custom ARCH-REV tag.

Checkstyle

Checkstyle is similar to PMD and FindBugs but instead of search for potential bugs focuses more on keeping a consistent coding style across the project.


<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-checkstyle-plugin</artifactId>
    <version>2.16</version>
</plugin>

The Checkstyle maven plugin has a lot of options to help configure the level of warnings and errors to include in the generated report. The plugin documentation has some good examples of adding extra configuration to customize the items that Checkstyle will check for you.

Generating the site

Now that we have all of our reports configured we can easily generate our maven site by running the following:

mvn clean test site

When the command is finished running you should have a directory under the target folder. This site folder contains all of the files needed to display the html website.

For a sample project that includes all of these reporting sections check out the repo on Github.


Code Quality Unravelled: Part 2


Comment