Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Maven 3 Code Analysis and Reporting

DZone's Guide to

Maven 3 Code Analysis and Reporting

· Java Zone
Free Resource

The single app analytics solutions to take your web and mobile apps to the next level.  Try today!  Brought to you in partnership with CA Technologies

If you have read any of my other blogs, you will know that I am a fan (and defender) of Maven 3. One of the biggest changes in Maven 3 was the reporting capabilities with the Maven Site Plugin.

I will show example configuration for the Site 3.1 plugin using Markdown syntax for the page content and the Markdown project at Daring Fireball.

Most of us have multi projects to build. When I was setting up the Site configuration, I had to keep this in consideration. I ran into issues with aggregating reports, and AspectJ classes with Cobertura for code test coverage.

Old Config (a.k.a. things to forget)

The OLD Maven reporting section.

<reporting/>

New Config

The Maven Site 3.x plugin is a “container” for reporting plugins.

Here is a table of some of the more common open source plugins.

Report Description
Javadoc Generates JavaDoc
Java XRef Cross reference report of project source code
Tag List Reports on Tags such as @todo and //TODO
Project Info A plethora of miscellaneous report: info, ci, dependencies, scm, plugins, etc.
Check Style Checks Code Style for Developers
Surefire Reports Test Results
PMD Source Code Analyzer
FindBugs Reports on common code mistakes and pitfalls
Sonar Analysis and metrics on code over time
Cobertura Reports Test Coverage
Versions Reports on application and plugin versions, and any updates available

Configuration

...
<properties>
  <maven.checkstyle.plugin>2.7</maven.checkstyle.plugin>
  <maven.cobertura.plugin>2.5.1</maven.cobertura.plugin>
  <maven.doxia.module.markdown.version>1.3</maven.doxia.module.markdown.version>
  <maven.javadoc.plugin>2.8.1</maven.javadoc.plugin>
  <maven.jxr.plugin>2.3</maven.jxr.plugin>
  <maven.pmd.plugin>2.7.1</maven.pmd.plugin>
  <maven.project.info.reports.plugin>2.4</maven.project.info.reports.plugin>
  <maven.site.plugin>3.1</maven.site.plugin>
  <maven.sonar.plugin>3.2-RC3</maven.sonar.plugin>
  <maven.surefire.plugin>2.12</maven.surefire.plugin>
  <maven.taglist.plugin>2.4</maven.taglist.plugin>
  <maven.versions.plugin>1.3.1</maven.versions.plugin>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
...
<build>
  <plugins>
    <plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-site-plugin</artifactId>
	<version>${maven.site.plugin}</version>
	<executions>
	    <!-- used for multiproject builds -->
		<execution>
			<id>attach-descriptor</id>
			<goals>
				<goal>attach-descriptor</goal>
			</goals>
		</execution>
	</executions>
	<configuration>
		<reportPlugins>
        <!-- Report Plugins go here -->
		</reportPlugins>
		<locales>en</locales>
	</configuration>
	<dependencies>
	    <!-- To use the Markdown format -->
		<dependency>
			<groupId>org.apache.maven.doxia</groupId>
			<artifactId>doxia-module-markdown</artifactId>
			<version>${maven.doxia.module.markdown.version}</version>
		</dependency>
	</dependencies>
	</plugin>
  </plugins>
</build>
...

Now add each plugin into the reportPlugins section just as you would any other dependency.

Page Templates

Maven will look for page templates in the src/site directory of the project. If the project is a parent pom project, add the directory src/site to the root of the project.

Here is a sample directory layout:

├── projectA
│   ├── pom.xml
│   └── src
│       ├── main
│       └── test
├── projectB
│   ├── pom.xml
│   └── src
│       ├── main
│       └── test
├── pom.xml
├── src
│   └── site
|       ├── markdown
|       │   ├── build.md
|       │   ├── index.md
|       │   └── services
|       │       └── persistence.md
|       ├── resources
|       │   └── images
|       │       └── technophile.png
|       └── site.xml
└── projectZ
    ├── pom.xml
    └── src
        ├── main
        └── test

Notice that src is at the same level as the top level pom.

Files:
Line 24: site.xml defines the sites layout.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/DECORATION/1.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/DECORATION/1.0.0
  http://maven.apache.org/xsd/decoration-1.0.0.xsd">

  <body>
    <menu name="Overview">
      <item name="Introduction" href="index.html"/>
      <item name="Building MyProject" href="build.html"/>
    </menu>

    <menu name="Common Services">
      <item name="Persistence Detail" href="services/persistence.html"/>
    </menu>

    <menu ref="reports"/>
  </body>
</project>

This generates a page with links for the index page, a build page and a persistence page. Also, line 17: menu ref=”reports” is a special link for the report plugins.

The *.md pages will convert from Markdown format into HTML. The build.md file might contain something like this:

![Technophile](images/technophile.png)

Building Core Spring
==========================

[Gordon Dickens](mailto:gordon@gordondickens.com)

-----

My Project
----------

This project infuses time, space and dimension into a convenient war file.

Line 1 is a reference to an image file. NOTE: this has to be in the site/resources directory.
Line 6 shows how to include a link or hyperlink.

Complete Reporting Config

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-site-plugin</artifactId>
  <version>${maven.site.plugin}</version>
  <executions>
    <execution>
      <id>attach-descriptor</id>
      <goals>
        <goal>attach-descriptor</goal>
      </goals>
    </execution>
  </executions>
  <configuration>
   <reportPlugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-report-plugin</artifactId>
      <version>${maven.surefire.plugin}</version>
      <configuration>
        <outputDirectory>${project.reporting.outputDirectory}/testresults</outputDirectory>
      </configuration>
    </plugin>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-javadoc-plugin</artifactId>
      <version>${maven.javadoc.plugin}</version>
      <configuration>
        <aggregate>true</aggregate>
      </configuration>
    </plugin>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-checkstyle-plugin</artifactId>
      <version>${maven.checkstyle.plugin}</version>
    </plugin>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-project-info-reports-plugin</artifactId>
      <version>${maven.project.info.reports.plugin}</version>
    </plugin>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-jxr-plugin</artifactId>
      <version>${maven.jxr.plugin}</version>
      <configuration>
        <aggregate>true</aggregate>
      </configuration>
    </plugin>
    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>cobertura-maven-plugin</artifactId>
      <version>${maven.cobertura.plugin}</version>
      <configuration>
        <aggregate>true</aggregate>
        <outputDirectory>%{project.reporting.outputDirectory}/cobertura</outputDirectory>
      </configuration>
    </plugin>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-pmd-plugin</artifactId>
      <version>${maven.pmd.plugin}</version>
      <configuration>
        <aggregate>true</aggregate>
        <sourceEncoding>${project.build.sourceEncoding}</sourceEncoding>
        <!-- The minimum tokens before a violation -->
        <minimumTokens>100</minimumTokens>
        <!-- Turn off if no xref report -->
        <linkXRef>true</linkXRef>
        <verbose>true</verbose>
        <targetJdk>${java.version}</targetJdk>
        <rulesets>
          <ruleset>/rulesets/maven.xml</ruleset>
          <ruleset>/rulesets/migrating_to_junit4.xml</ruleset>
          <ruleset>/rulesets/design.xml</ruleset>
          <ruleset>/rulesets/unusedcode.xml</ruleset>
          <ruleset>/rulesets/typeresolution.xml</ruleset>
        </rulesets>
      </configuration>
    </plugin>
    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>findbugs-maven-plugin</artifactId>
      <version>${maven.findbugs.plugin}</version>
    </plugin>
    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>versions-maven-plugin</artifactId>
      <version>${maven.versions.plugin}</version>
    </plugin>
    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>taglist-maven-plugin</artifactId>
      <version>${maven.taglist.plugin}</version>
      <configuration>
        <aggregate>true</aggregate>
      </configuration>
    </plugin>
   </reportPlugins>
  <locales>en</locales>
  </configuration>
  <dependencies>
    <dependency>
      <groupId>org.apache.maven.doxia</groupId>
      <artifactId>doxia-module-markdown</artifactId>
      <version>${maven.doxia.module.markdown.version}</version>
    </dependency>
  </dependencies>
</plugin>

Summary

Wow, that’s a lot of config! The configuration sample above has a bit of overlap. Simple remove the report plugins that are not as important to you at the present time.

Watch out for the JXR plugin, this is a very time consuming report to generate. If this becomes something you want to run infrequently, I recommend different Maven profiles, one with JXR and one without.

CA App Experience Analytics, a whole new level of visibility. Learn more. Brought to you in partnership with CA Technologies.

Topics:

Published at DZone with permission of Gordon Dickens, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}