The Source for Java Technology Collaboration
User: Password:
Register | Login help    

Search

Online Books:
java.net on MarkMail:


Fabiano Cruz

Fabiano Cruz has been working with the Java platform since 1999. He is currently working as Software Architect at BenQ Mobile, Research and Development department, dealing with embedded (java and native), desktop and enterprise systems development, architecture, design and coach. He founded two important Java User Groups - Manaus JUG (Amazon state) and Petropolis JUG (Rio de Janeiro state) in Brazil - and he is constantly speaking in Java community meetings and conferences in Brazil, such as JustJava (one of the largest tech conferences in Brazil), One Day Java 2001/2002/2003/2004/2005, SERPRO Symposium of Java Technology, JBoss in Rio, Maratona 4 Java, and Java in Rio. He talked about JSR 246 - Device Manage API ("BOF-7831 Device Management for Mobile Applications") at this year's JavaOne.

 

Fabiano Cruz's blog

Java Static Analysis made easy with Apache Maven 2

Posted by fabianocruz on October 4, 2006 at 4:42 PM PDT

Introduction

Many of today's software development projects are changing the ordinary code/compile/test/debug cycle to accommodate some other concerns, like: keeping track of what is being developed and consequently if the project is achieving its stated quality and goals. Therefore, no matter what process you use, but at some point of the project timeline, the source code [one of your most valuable assets] needs to be reviewed.

Indeed, the source code review process is usually done manually, and it demands a specialist to ensure that the development team is producing code that follows the language-specific programming standards, some rules and best practices. Error-detection, in the early phases of software development, reduces "big bangs" in the end of the projects and most of the companies know that, but on the other hand, they don't have available human resource for reviewing/verifying thousands of lines of code all the time. Therefore, the manual code review process becomes expensive and unmanageable, especially in large programs.

Static analysis and bug detection can be an effective way to improve software quality. They can be incorporated in the build process, automating the source code review process to find bugs and code defects as early as possible. Static analysis is used to locate problems (e.g.: potential bugs, unnecessary complexity and high maintenance areas) in code without running it.

There is a large body of literature related to static analysis for those who aim to produce high-quality software, out of bugs, focusing on early problem detection applying best practices, code standards compatibility and so forth.

So, when integrated in the build process (automation is really nice in this case – e.g.: continuous integration), those static analysis can be really useful and powerful to the entire team, given them tons of reports which are an x-ray of the system that lets them looking for potential inconsistencies all the time (daily builds). Therefore, when applying some holistic mining in the collected code metrics for your Java projects, you can figure out what's going on with the actual system development, where you should reengineer and/or refactor and so on.

In this short article, I'm gonna present some tools to support the development process in the static analysis and bug detection field, showing how they fit together in the build process using Apache Maven 2.

Author note: it's not the intention here talk about data-flow analysis, flow-graph analysis, static analysis algorithms (e.g.: Unique Name, Class Hierarchy Analysis, Rapid Type Analysis etc) and stuff like that.

Anyways, I hope you enjoy the power of static analysis and bug detection in your daily work life.

Tools for Java static code analysis

Now, we'll see a couple of tools for Java Static Code Analysis, but of course, I've probably overlooked some projects/products, because there are a large number of tools. So, my apologies if one of them was yours, but please feel free to hand in your comments about your [preferable] tool.

I've tried to make a comprehensive table [Table 1] of those tools, including some information like IDE support, license and stuff like that.

Key:
EP: Eclipse 3.2 plug-in
NBM: NetBeans 5.5 module
M2: Maven 2 compatible
ANT: Apache Ant compatible
CLI: standalone or command line application


Tool EP NBM M2 ANT CLI License
Checkstyle check.gif check.gif check.gif check.gif check.gif LGPL
Findbugs check.gif check.gif check.gif * check.gif check.gif LGPL
JDepend check.gif check.gif check.gif check.gif check.gif BSD
PMD check.gif check.gif check.gif check.gif check.gif BSD
CPD check.gif check.gif check.gif check.gif check.gif BSD
JavaNCSS check.gif error.gif check.gif check.gif check.gif GPL
SA4J error.gif error.gif error.gif error.gif check.gif Proprietary License
Lattix DSM check.gif error.gif error.gif error.gif check.gif Proprietary License
QAJ check.gif error.gif error.gif error.gif check.gif Proprietary License
XRadar error.gif error.gif check.gif error.gif error.gif BSD
Structure101 for Java error.gif error.gif error.gif error.gif check.gif Proprietary License
Classycle check.gif error.gif check.gif error.gif check.gif BSD
Table 1: Java static analysis and bug detectors


(*) Sandboxed Plug-in (plugins which have been contributed but have not gained the attention of users or a committer interested in seeing it released).
See also "Known-issues and limitations" in the end of this article.

NOTE: If you are using IntelliJ IDEA, version 5.0 and 6.0 Beta also supports over 500 inspections for common problems, performance issues, and style issues and it provides most of the same inspections FindBugs and PMD perform.

Integrating some of them into your build process using Maven 2

If you don't have the Apache Maven 2 environment set up, please follow the instructions below:

1. Download the binary (version 2.0.4 or better) and unpack. Put Maven 2's bin/ in your PATH. http://maven.apache.org/download.html

2. Follow the Installation Instructions: http://maven.apache.org/download.html#Installation

3. You can find a bit longer introduction here: http://maven.apache.org/guides/getting-started/index.html

4. If you're behind a proxy, please include the information below within "$maven_instalation_path/maven-2.0.x/conf", where "x" is the Maven 2 version chosen:

Listing 1 - settings.xml

...
<proxies>
  <proxy>
  	<active>true</active>
  	<protocol>http</protocol>
  	<host> ... </host>
  	<port> ... </port>
  	<nonProxyHosts>10.*|localhost|*.url </nonProxyHosts>
  </proxy>
</proxies>
...

5. We can use the following command to have the maven-archetype-webapp create the web application skeleton-project for us:


mvn archetype:create
	-DgroupId=com.mycompany.app
	-DartifactId=my-webapp
	-DarchetypeArtifactId=maven-archetype-webapp

Now, you can ADD some java code inside ~\my-webapp\src\main\java folder (feel free to modify the generated project, including anything you want). Please, be aware that you need to change the dependencies tag within your pom.xml if you include any source code which depends on some library.

To compile the project, just use the following command within ~\my-webapp folder:
> mvn compile [This will put the output files (e.g.: .class files) in the target/ directory]
You can also try:
> mvn package [This will first compile, then run any tests, then create a WAR, etc, in the target/ directory]
> mvn install [This will generate the WAR (in this case) and installs it in your local repository]
> mvn site [This will generate reports on metrics, in target/site folder]

Run "mvn clean" to clean up the project.

After successfully install your Maven 2 environment, you can then include some static analysis plug-ins in the POM (Project Object Model) file:

Listing 2 – pom.xml


<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/maven-v4_0_0.xsd">

  <modelVersion>4.0.0</modelVersion>
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-webapp</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>Maven Webapp Archetype</name>
  <url>http://maven.apache.org</url>

  <pluginRepositories/>

  <!-- Create the reports and the target of the reports -->
  <reporting>
        <outputDirectory>target/site</outputDirectory>
        <plugins>
            <!-- General project information -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-project-info-reports-plugin</artifactId>
            </plugin>
            <!-- Cross references report -->
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>jxr-maven-plugin</artifactId>
            </plugin>
            <!-- Report about violations of coding standards -->
            <plugin>
                <artifactId>maven-checkstyle-plugin</artifactId>
            </plugin>
            <!-- Generate "PMD" and "CPD" reports -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-pmd-plugin</artifactId>
                <configuration>
                	<linkXref>true</linkXref>
                <sourceEncoding>utf-8</sourceEncoding>
                <minimumTokens>100</minimumTokens>
                <targetJdk>1.5</targetJdk>
                </configuration>
            </plugin>
            <!-- Generate "JDepend" report -->
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>jdepend-maven-plugin</artifactId>
                <version>2.0-beta-1-SNAPSHOT</version>
            </plugin>
            <!-- Generate "FindBugs Report" report -->
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>findbugs-maven-plugin</artifactId>
                <version>1.0-beta-1</version>
                <configuration>
                	<threshold>Normal</threshold>
                	<effort>Default</effort>
                	<excludeFilterFile>findbugs-exclude.xml
                                          </excludeFilterFile>
                	<includeFilterFile>findbugs-include.xml
                                          </includeFilterFile>
                	<visitors>FindDeadLocalStores,
                                        UnreadFields</visitors>
                	<omitVisitors>FindDeadLocalStores,
                                    UnreadFields</omitVisitors>
                	<pluginList>/libs/fb-contrib/fb-contrib-2.8.0.jar
                                                  </pluginList>
                </configuration>
            </plugin>
            <!-- Generate "JavaNCSS Report" report -->
            <plugin>
	            <groupId>org.codehaus.mojo</groupId>
	            <artifactId>javancss-maven-plugin</artifactId>
		    <version>2.0-beta-1</version>
            </plugin>
        </plugins>
  </reporting>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>

  <build>
    <finalName>my-webapp</finalName>
    <plugins>
      <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                    <source>1.5</source>
                    <target>1.5</target>
            </configuration>
            </plugin>
	</plugins>
    </build>

</project>

Before going any further, we need also to get the plug-in repository configured correctly within the POM, as stated below:

Listing 3 – pom.xml


...
<pluginRepositories>
  <pluginRepository>
    <id>Maven Snapshots</id>
    <url>http://snapshots.maven.codehaus.org/maven2</url>
  </pluginRepository>
  <pluginRepository>
    <id>codehaus-snapshot-plugins</id>
    <name>codehaus-shapshot-plugins</name>
    <url>http://snapshots.repository.codehaus.org/org/codehaus/mojo/</url>
    <snapshots>
    	<enabled>true</enabled>
    </snapshots>
    <releases>
    	<enabled>false</enabled>
    </releases>
  </pluginRepository>
</pluginRepositories>
...

Known-issues and limitations

Maven 2 FindBugs Plugin
When running findbugs on a project, the default heap size might not be enough to complete the build. For now there is no way to fork findbugs and run with it's own memory requirements, but the following system variable will allow you to do so for Maven:
export MAVEN_OPTS=-Xmx384M

Conclusion

Do the right thing the first time. ;)

Have fun!

Recommended reading:

Resources:

Send comments, corrections and updates.

Related Topics >> Open Source      
Comments
Comments are listed in date ascending order (oldest first)
Syndicate content