Home | About Us | Stelligent  

TestEarly Weblog
Paul Duvall

Paul Duvall

Chief Executive Officer
Stelligent
As CEO of Stelligent, Mr. Duvall is responsible for overall financial and operational management of Stelligent. His primary responsibilities include business development, technical direction, marketing, strategic planning, partner relations, corporate operations, financial management and board relations.
Mr. Duvall is a featured speaker at many leading software conferences. He is the principal author of Continuous Integration: Improving Software Quality and Reducing Risk (Addison-Wesley, 2007; Jolt 2008 Product Excellence Award Winner). He contributed to the UML 2 Toolkit (Wiley, 2003) and the No Fluff Just Stuff Anthology: The 2007 Edition (Pragmatic Programmers, 2007) and authors a series for IBM developerWorks called Automation for the people. He has worked in virtually every role on software projects: developer, project manager, architect and tester. He is passionate about accelerating software delivery through automation. Prior to his role as CEO, he served as CTO of Stelligent.
Developer Testing and News and Training and /Duvall23 Mar 2009 08:04 am

My friend Andy Glover will be leading a two-day training class in Reston, VA on April 2nd and 3rd, 2009. If you haven’t attended any of Andy’s training sessions, you’re missing out. Having worked with Andy for several years, I can tell you first hand that he’s got unique combination of depth and breadth in technical skills…while making the material he’s covering extremely interesting. The two-day course contains 16 hands-on labs, so you’re not just walking out with a bunch of theory. Therefore, if you want to get up to speed with Groovy and Grails in a short amount of time, I highly recommend you register for this course.

Groovy logo

Groovy is a dynamic language that runs on the Java platform. It makes programming easier and more powerful, while taking advantage of everything that’s been built up around Java. Grails is a framework, built on Groovy, to help you quickly develop web-based applications.

Continuous Integration and Publications and Screencast and /Duvall17 Mar 2009 07:31 am

The Integrate Button website (from Paul Duvall’s book on Continuous Integration) recently published a screencast on using the Hudson Continuous Integration server - along with Subversion, Ant, HSQL and other tools. Click the image below to get started.

Continuous Integration Hudson screencast

The screencast demonstrates the following steps:

  • Checkout source files from the Subversion repository - locally
  • Run the automated build locally
  • Commit files to Subversion
  • Download, install and configure Hudson - from Hudson website or from IntegrateButton scripts
  • Make a code change (with error) and checkin files
  • Get notified of error, automatically, via Hudson
  • Fix code errors, commit change and see results in Hudson
News and Interview and /Duvall28 Feb 2009 10:35 am

Jurgen Appelo who writes a blog on Understanding Development & Management asked Stelligent CEO Paul Duvall to answer 5 easy questions about his toughest challenge, software development and other interesting topics. His answers join a list of software luminaries such as Steve McConnell, Grady Booch, Mike Cohn, Ron Jeffries, Mary Poppendieck and Alistair Cockburn.

Developer Testing and Continuous Integration and Business Perspectives and /Duvall11 Feb 2009 07:10 pm

I like repeatable processes. To me, it’s a waste of time to do the same thing more than once. I’m also reminded of this when I start repeating answers to the same questions. When considering knowledge companies, virtually everything valuable to us are our people and information, not physical assets. As I said in “Fire your Best People…”, if information is locked inside someone’s head, they are a less valuable resource. It’s all about sharing: files, knowledge, pertinent information from emails and so on. If the asset only exists on one person’s machine, or worse: their head, and is relevant to others, your company has a problem.

My Library of Information

When considering software, if all of the assets necessary to create working software haven’t been committed to the version-control repository, the software doesn’t exist. Sounds simple doesn’t it? Then, why do so many projects and companies fail to follow this simple rule? If I was cynical, I might think it’s because some think that by harboring this information, they can essentially hold the organization “hostage” - and increasing job security. In my experience, this is no longer the primary reason in the organizations I’ve seen (although there are always a few exceptions). I think the main problem is leadership. It takes discipline for each person in an organization to ask themselves after they’ve sent instructions on how to do something in an email…

Is this something I want to keep permanent for all current and future employees?

Other examples include:

  • Realizing that a configuration file used to deploy the software should be checked into the version-control system so that the software can be built in any target environment, not just on their machine.
  • The workaround for that strange bug in your Content Management System should be posted to the Wiki
  • That pointing to a file in a version-control repository may be preferred over sending email attachments with every change .
  • The email that documented the steps that Human Resources performs when a new employee starts with the company, should be published to the company’s Intranet .

Here are some possible tools where you might capture these assets:

  • Version-control repository
  • Corporate Intranet
  • Hosted Wiki
  • Electronic Corporate bulletin board
  • Company blog

Leaders in knowledge organizations understand their most vital assets are their people and the information produced by these people. When people leave, you need to have a way to continue to leverage this knowledge. Leaders understand that this philosophy of sharing information must be institutionalized. Just remember…

If it’s not in the System, it doesn’t exist

Build Management and Continuous Integration and Publications and /Duvall11 Nov 2008 04:41 pm

It can be a significant burden to manually apply upgrades to an existing database. Moreover, it’s often an error-laden activity. IBM developerWorks’ recently published an article on this topic for Paul Duvall’s (Stelligent CTO) popular Automation for the people series called Hands-free database migration.

Databases are often out of sync with the applications they support, and getting the database and data into a known state is a significant challenge to manage. Learn how the open source LiquiBase database-migration tool can reduce the pain of managing the constant of change with databases and applications.

Developer Testing and /Duvall24 Sep 2008 07:14 am

easyb-imageLast week, JavaLobby published an article about easyb called “Is easyb Easy?”.

Yes, that’s exactly what you will find out by reading this article. easyb is a BDD framework for the Java platform written by Andrew Glover. This article goes in detail about how to write a

1. Scenarios within Stories
2. Run these Stories from Ant
3. Generate a report.

Check out the article to find out what the verdict was. Also, give it a try and let us know your verdict as well.

Developer Testing and Build Management and Tutorial and Agile and /Duvall23 Sep 2008 07:02 am

gant-imageYes, this is exactly what I am frequently asked by my clients and many developers. It isn’t easy to answer this question. There are several projects using Ant. Should you run away from Ant just because there is a new cool tool out there called Gant? Should you switch to Gant just because you dislike XML? Not at all. Let’s take a closer look and see what might make you switch to Gant.

When to choose Gant?

1. Complicated Build Files. If your ant build files are becoming too complicated, and hard to manage, it’s time to see if using Gant can help. Let me explain what I mean by complicated build files. If you have too much of conditional logic within your build files, say something similar on the lines shown below in Listing 1:

Code Listing 1:


    <if>
      <isset property="sqlserver"/>
      <then>
        <do something here/>
      </then>
    </if>
    <if>
      <isset property="oracle"/>
      <then>
        <do something else here/>
      </then>
    </if>
    <if>
      <isset property="derby"/>
      <then>
       <do something for derby here/>
      </then>
    </if>
    <if>
      <isset property="db2"/>
      <then>
        <do something for db2 here/>
      </then>
    </if>

Or even something like this where you might be supporting deployment to different application servers based on some property in your build.properties or by the user as shown in listing 2.

Code Listing 2:

    <if>
      <isset property="server.jboss4"/>
      <then>
        <deploy to JBoss 4/>
      </then>
      <elseif>
        <isset property="server.weblogic10"/>
        <then>
	<deploy to web logic/>
        </then>
      </elseif>
      <elseif>
        <isset property="server.glassfish"/>
        <then>
          <deploy to GlassFish/>
        </then>
      </elseif>
      <elseif>
        <isset property="server.someother version"/>
        <then>
          <deploy to this some other version/>
        </then>
      </elseif>
    </if>

Things get out of hand when you have conditional logic as shown above in your build scripts. The listings I have are just the skeleton, imagine what happens when we start adding the actual deployment logic for all these application servers. It doesn’t matter how you refactor this, it is still going to be very complicated. Trust me, I have written build scripts which were several thousand lines, and refactoring them was not a trivial task.

2. Custom Ant Tasks. I myself am guilty of writing many of these. There are many situations which arise in projects where we create custom ant tasks. It is simple once you know how to write one, and than for every complicated task you need to perform, you involuntarily will start writing custom ant tasks.

Anyone writing a custom ant task will:
a. Create a new class that extends Ant’s org.apache.tools.ant.Task class.
b. For each attribute, write a setter method.
c. Write an execute()method that does what you want this task to do.

There isn’t anything wrong in doing the above, but imagine each time you want to make a small change you will have to make changes within your Java source code, compile, test, re-package.

3. Scripting. You can extend Ant further by not writing custom ant tasks, but by using small snippets of code written in an interpreted language like JRuby, BeanShell, or Groovy. These code snippets can be placed within your build files or in separate text files. If you are using Groovy’s Ant task, your build file might look something like this:

 <groovy classpathref="build.classpath">
  import some.package
  import another.package
  def fullpath = "${.basedir}/${defaulttargetdir}"
   def somefile = new SomeFile(projectName:"${pname}",
     buildLabel:"${label}", buildTime:"${new Date()}")
   def xml = "${fullpath}/dashboard.xml"
   new File(path).write(somefile.generateReport())
   ant.xslt(in:path,
    out:"${properties.defaulttargetdir}/some.html",
    style:"${properties.defaulttargetdir}/lib/report-style.xsl")
 </groovy>

Imagine having several lines of XML in your build files which have many of these small snippets of scripts. I myself don’t like mixing and matching build files with code snippets. If you have a team where everyone is in the same page, everything works fine. What if a team member has no clue about any of the Scripting languages? He/She will have no clue how to make minor changes when things go badly. If you have all the above or even one of the above three cases, you seriously need to consider using Gant. To quote Aristotle:

For the things we have to learn before we can do them, we learn by doing them.

So, lets see how easy it is to learn Gant and see how things can improve.

This part covers some very basics of Gant. The next part, will dive deeper into Gant by using it with a sample project to build our application, and we will also see how to use it with our CI Server.

What’s Gant?

Gant is a build tool that uses both Groovy and Ant. With Gant, you describe your build process using Groovy scripts. Stated simply, Gant allows you to specify the build logic using Groovy instead of XML. The next thing you may ask is ” Is Gant a competitor to Ant?”. Let me quote from the Gant web site to make things more clear here :

Whilst it might be seen as a competitor to Ant, Gant uses Ant tasks for many of the actions, so Gant is really an alternative way of doing builds using Ant, but using a programming language rather than XML to specify the build rules.

Download and Install Gant.

In order for Gant to work, you should have Groovy installed. You can download and follow the installation instructions for Groovy here.
As I said earlier also, in order to use Gant, you should have knowledge of Groovy as well. If you have never written Groovy code before, there are many interesting books on Groovy like:

a. Groovy in Action

b. Groovy Recipes

c. Groovy Refcardz

You can also read the getting started guide on the Groovy web site, which should give you a good starting point.

Download the latest version of Gant from here. Gant is currently at version 1.4.0. Unzip it to a folder. If you already have your GROOVY_HOME set, that’s all you need to use Gant.

Getting Started.

Open a console, and type gant. You should see a message as shown below:

meera-subbaraos-macbook-9:~ meerasubbarao$ gant
Cannot open file build.gant
meera-subbaraos-macbook-9:~ meerasubbarao$

You are all set at this point to use Gant in your projects.

Help Information: Open a console, and type gant -h. This will provide you with all the necessary help information you need as shown below:

meera-subbaraos-macbook-9:CodeMetricsProject meerasubbarao$ gant -h
usage: gant [option]* [target]*
-c,–usecache Whether to cache the generated class and

perform modified checks on the file before re-compilation.
-n,–dry-run Do not actually action any tasks.
-C,–cachedir The directory where to cache generated
classes to.
-D = Define to have value .
Creates a variable named for use in the scripts and a property
named for the Ant tasks.
-L,–lib
Add a directory to search for jars and
classes.
-P,–classpath
Specify a path to search for jars and
classes.
-T,–targets Print out a list of the possible targets.
-V,–version Print the version number and exit.
-d,–debug Print debug levels of information.
-f,–file Use the named build file instead of the
default, build.gant.
-h,–help Print out this message.
-l,–gantlib
A directory that contains classes to be used
as extra Gant modules,
-p,–projecthelp Print out a list of the possible targets.
-q,–quiet Do not print out much when executing.
-s,–silent Print out nothing when executing.
-v,–verbose Print lots of extra information.

Create a new file called build.gant at the root of your project. gant-project

Did a similarity between Ant and Gant strike you here? Ant build files are usually called build.xml, and they are created as a common practice within the root of your project folder as well.

If you have written or even modified Ant build files, you will know that it contains one project element, which in turn contains a name,the default target and the base directory.

Code Listing 4:

<project name="GantSamples" basedir="." default="compile">

So for example, sayHello target in Ant would look something like this:

<target name="sayHello" description="Saying Hello">
	<echo message="Hello from Stelligent"/>
</target>

Lets create the sayHello target, and also see how to set it as the default target in Gant as well.

A Gant target has a name and a description:

Code Listing 5:
target ( target-name : target-description ) {
groovy code sequence
}

The above sayHello target in Gant would translate as shown below:
target(sayHello:"Saying hello"){
Ant.echo(message:"Hello from Stelligent")
}

Now, open a command window and type gant at the root of the project where the build.gant file exists. You should be able to see a output like:

meera-subbaraos-macbook-9:CodeMetricsProject meerasubbarao$ gant
Target default does not exist.

Gant is complaining that we haven’t set a Default target. Lets see how to do the same:

Default target: Within Ant, you define the default target from within the project element as seen in Listing 4. The default target is the target called if no target is specified from the command line. There however is no project tag within Gant. There are two ways of specifying the default target as shown below

1. You simply create a target whose name is default.
target ( 'default' , 'The default target.' ) { aTarget ( )
2. or even simply:
setDefaultTarget ( aTarget )

In order to get our sayHello target working, we need to add one of the above scirpts to our build.gant file.

Code Listing 6:
setDefaultTarget(sayHello)
or
target ("default": "The default target." ) {
sayHello ( )
}

Complete listing of build.gant:
target(sayHello:"Saying hello"){
Ant.echo(message:"Hello from Stelligent")
}
/*
target ("default": "The default target." ) {
sayHello ( )
}
*/
setDefaultTarget(sayHello)

And you should be able to see:

meera-subbaraos-macbook-9:CodeMetricsProject meerasubbarao$ gant
[echo] Hello from Stelligent
meera-subbaraos-macbook-9:CodeMetricsProject meerasubbarao$

That was easy! If you have build files and it is becoming unmanageable by your team, there is a tool out there which can convert your Ant scripts to Gant scripts as well. I haven’t used it, but you can try it here.

In this part of the series, we learned when to move over from Ant to Gant, downloaded and installed Gant, and finally wrote a simple gant build file. In the next part of this series, we will see Gant in Action within a simple Java project.

And as always, keep us posted here if you are encountering any problems getting started with Gant. Stay tuned.

Developer Testing and /Duvall22 Sep 2008 11:48 am

Roy has some provocative thoughts on TDD and getting developers to write unit tests.  I don’t agree with all of them, but it’s worth a read.
Some of his interesting points:

  • 99% of the developers out there aren’t ready for the “testability” message
  • Don’t call them ‘mocks’ or ’stubs’ - say things like ‘we need to isolate this class’
  • Unit Testing has a very high learning curve, and all the tools are making that learning curve higher
  • Try to avoid record/replay style testing
  • Don’t advocate ‘one true way’ to do unit testing.  Accept other approaches that are different from your preferred approach.

I suggest you read the whole thing.

Developer Testing and Continuous Integration and Tutorial and Agile and /Duvall10 Sep 2008 09:43 am

In the last two articles, “UML Diagrams within Javadocs” and “Visual Documentation of Ant Dependencies in 3 Simple Steps” we saw how easy and valuable it was to automate technical documentation. By using open source tools, we were easily able to provide good technical documentation within a few minutes, and at no cost at all. We were also able to keep this up-to date by adding additional tasks to our Ant build files, and run them from our CI Server(Hudson in our case) on commit and nightly builds, and also publish the results.

In this article, I will be showing you how to use yet another tool called Dxoygen for generating technical documentation based on your source code. We all have used Javadoc and have been using it for a long time, right? So, you may ask what’s the need to have another tool which produces the same HTML documentation? Doxygen has a slight edge over Javadoc and here are a few reasons why you should consider using the same:

1. With Javadoc you have to remember all the HTML tags, you need to embed within your code comments. However, with Doxygen code comments are much more concise and polished, without the need for any HTML.

2. Doxygen can also generate a variety of diagrams, we will take a look at some of them later.

3. Doxygen also provides a structured view on the source code. As I mentioned in 2 above in the form of various diagrams, cross-referenced and syntax highlighted code.

4. You get all the above benefits even if the code does not have any comments at all.

5. Last but not the least, Doxygen is a documentation system not for just Java but also for various other languages like C++, C, Java, Objective-C, Python, IDL (Corba and Microsoft flavors), Fortran, VHDL, PHP, C#.

So, without wasting further time, lets see what we need to get started with Doxygen.

Step 1. Download, Install Doxygen

Download the binary distribution for Doxygen for the operating system you are using. I downloaded the binary distribution for Mac OS X called Doxygen-1.5.6.dmg. Installation is very simple, just drag the doxygen icon from this folder to the Applications folder, or wherever you want to keep it; as shown below. I dropped it within my Applications folder. Just be sure to remember where you dragged it. To uninstall, just delete the file. It is completely self-contained.
doxygen-setup

Step 2: Configure Doxygen.
To generate documentation using Doxygen, you will need a configuration file called the Doxyfile. You can generate this file in two ways; either by using the Doxygen wizard or by using the command line option. Lets see how to use both these options to generate the configuration file:

a. Command line.
Open a command window and type the following as shown below:
doxygen-console

You should be able to locate the configuration file created within your default user folder. The file looks like this:

# Doxyfile 1.5.6

# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project
#
# All text after a hash (#) is considered a comment and will be ignored
# The format is:
# TAG = value [value, …]
# For lists items can also be appended using:
# TAG += value [value, …]
# Values that contain spaces should be placed between quotes (” “)

#—————————————————————————
# Project related configuration options
#—————————————————————————

# This tag specifies the encoding used for all characters in the config file
# that follow. The default is UTF-8 which is also the encoding used for all
# text before the first occurrence of this tag. Doxygen uses libiconv (or the
# iconv built into libc) for the transcoding. See
# http://www.gnu.org/software/libiconv for the list of possible encodings.

DOXYFILE_ENCODING = UTF-8

# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
# by quotes) that should identify the project.

PROJECT_NAME =

# The PROJECT_NUMBER tag can be used to enter a project or revision number.
# This could be handy for archiving the generated documentation or
# if some version control system is used.

PROJECT_NUMBER =

b. Wizard Option.
Launch the Doxygen application, and you should be able to create the configuration file using the wizard approach as shown below.
doxygen-wizard
The user interface is quite intuitive so I am going to skip explaining this in detail.
The wizard approach was the one I used to get the initial settings for the configuration file, which you can always modify later.

A few options in my Doxygen configuration file are as follows:

# Doxyfile 1.5.6

#—————————————————————————
# Project related configuration options
#—————————————————————————
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = PetStore
PROJECT_NUMBER = 1.0
#—————————————————————————
# Build related configuration options
#—————————————————————————
EXTRACT_ALL = NO
EXTRACT_PRIVATE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = YES
#—————————————————————————
# configuration options related to the HTML output
#—————————————————————————
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
GENERATE_TREEVIEW = YES

Step 3. Doxygen and Ant.

In order to use Doxygen, we need an Ant task. There is already an Ant task written for Doxygen which you can download from here.
As always, since using Mac, when I downloaded the binaries and tried to use them, I got the ever famous error message :

java.lang.UnsupportedClassVersionError: Bad version number in .class file

So, had to do download the source, compile, and jar it up. Copy this library to your projects folder. So, lets start making changes to our build file.

3.a: Lets define the Doxygen task:

<taskdef name="doxygen" classname="org.doxygen.tools.DoxygenTask" classpath="lib/ant_doxygen.jar" />

3.b: To generate HTML documentation:

<target name="generate-doxygen-docs">
<taskdef name="doxygen" classname="org.doxygen.tools.DoxygenTask"
classpath="lib/ant_doxygen.jar" />
<doxygen configFilename="reports/Doxyfile">
<property name="INPUT" value="${srcdir}" />
<property name="RECURSIVE" value="yes" />
</doxygen>
</target>

3.c: Lets combine them in a target and run the same:

[doxygen] Exec: /Applications/Doxygen.app reports/Doxyfile

BUILD FAILED
/CodeMetricsProject/build.xml:91: Doxygen not found on the PATH.

Total time: 7 seconds

3.d: So, to launch Doxygen not in the path, we make changes to the doxygen task as shown below:

<doxygen doxygenPath="/Applications/Doxygen.app/Contents/Resources/doxygen" configFilename="reports/Doxyfile">

Lets run the target again and see if it fixed things. Yes indeed.

generate-doxygen-docs:
[doxygen] Exec: /Applications/Doxygen.app/Contents/Resources/doxygen reports/Doxyfile

BUILD SUCCESSFUL
Total time: 8 seconds

4. Integrate with Hudson.

4.a Hudson Job and Ant Target.
Once you have an Ant target working, calling this from your CI server is trivial. Within Hudson, select your Job, click on configure and add this new target to be called when running the build.
hudson-ant

4.b Publish the Reports.
hudson-reports

4. c: Sample Reports.

Force a build, and take a detailed look at the reports generated by Doxygen as shown below:

main-page

Report-Page1

Report-Page2

I have given you a brief overview of Doxygen in this article, how to configure the same, and use it effectively to generate technical documentation on a continuous basis; either on commit builds or nightly builds. The Doxygen web site has lots of information on how to use it with other programming languages and also has tutorials in languages other than English as well.

As always, if you are having trouble getting Doxygen to work, leave a comment or check out the Doxygen web site.

Developer Testing and Continuous Integration and Code Metrics and Agile and /Duvall29 Aug 2008 11:40 am

One of the primary goals of every developer should be to prevent or drastically limit the number of bugs or defects from being introduced in their source code. It is also our responsibility to write good, extensible, testable, and maintainable code. This however seems like a herculean task to many.

John Smart, has very well said in his latest and greatest "Java Power Tools" book:

When used well, software metrics can provide valuable feedback on the quality of the code being written, and allow the development team to learn and progress. To be successful, software metrics should be considered a team sport.

So, lets automate the task of finding defects early by using open source tools which can look at your source code and in most cases find, if not all, at least some potential defects. There are numerous open source tools like:

1. CheckStyle - is a development tool to help programmers write Java code that adheres to a coding standard.

2. JDepend - traverses Java class file directories and generates design quality metrics for each Java package.

3. JavaNCSS - cyclomatic complexity tool.

4. Simian - identifies duplication in Java. Not open source.

5. Emma - Code coverage tool.

There are several other open source tools as well, like PMD, Cobertura, FindBugs and many more. All these tools are highly configurable as well. I mentioned the above five for a reason. I will get to it soon.

Imagine how much work it is to setup, configure, and run these metric tools as part of your continuous integration. It really is a huge task doing it for each and every project you have.

However, there is just one tool which you need to download: Panopticode. Panopticode includes all the above mentioned tools preconfigured. If you have read Neal Ford’s "The Productive Programmer", chapter 7: Static Analysis" page 113, the author talks about "Generating Metrics with Panopticode". That’s how I got to know about this amazing tool. There is no detailed instructions in the book on how to get this up and running, the web site does have.

So, I decided to give it a try and here are the steps I followed.

Rather than creating a new project, I re-used the PetStore project which I have been using for a long time for all the articles I write.

Follow these steps to get Panopticode up and running:

1. Download Panopticode from here.

2. Unzip and copy to your project folder.

The folder structure will look like this:

panopticode-in-project

3. Make changes to the build.xml file.

In the Panopticode web site, there are 4 steps listed which you can follow. However, rather than copying the entire build file, I modified my existing build file, and ran the new target metrics within the Hudson(Continuous Integration Server) Job .

Add the following lines from the panopticode/build-example.xml to your build file.

3.a

<import file="panopticode/panopticode-imports.xml"></import>

3.b

<target name="metrics" depends="clean">
		<panopticode projectdir="${basedir}" projectname="${ant.project.name}"
                           projectversion="${version}" srcdir="${srcdir}"></panopticode>
	                           </target>
             

In the above target, specify the path to your source directory.

3.c Modify your target which compiles and runs your unit tests to include the following lines:

<panopticode-junit unitTestClasspathId="unittest.path"
	                           outputDir="target">
	            <batchtest todir="target/rawmetrics/xml/junit">
	                <fileset dir="target/classes" includes="**/*Test.class" />
	            </batchtest>
	       

Make changes to the unitTestClasspathId to include the libraries required to run your tests. In my case, I included the JEE libraries required for my EJB application.

4. Run the metrics Ant target.

Run the metrics target either from the command line. You should see an output like this:

[junit] Testcase: validNumberOfLifecycleAnnotations took 0.008 sec
[report] processing input files …
[report] 2 file(s) read and merged in 4 ms
[report] writing [xml] report to [../CodeMetricsProject/target/rawmetrics/xml/emma.xml] …
[report] writing [html] report to [../CodeMetricsProject/target/rawmetrics/html/emma/emma-coverage.html] …
[emmaPanopticode] Loading panopticode structure: panopticode.xml
[emmaPanopticode] Loading supplement: org.panopticode.supplement.emma.EmmaSupplement
[emmaPanopticode] Writing back to panopticode structure: panopticode.xml
[mkdir] Created dir: ../CodeMetricsProject/target/reports/svg
[echo] Building Static Reports
[echo] Building Interactive Reports
BUILD SUCCESSFUL
Total time: 8 seconds

5. Force a Build.
Now that we have all the xml files generated for the metrics tool, we need to make sure run the above target metrics from the Hudson Job, and force a build. You should be able to see the following xml as well as HTML files generated:
reports

6. Configure the XML files.
Finally, configure all these xml files within the Post-Build actions of the Hudson Job, and you should be able to force a build and see the reports in your dashboard. See screen shots below for various metrics:

a. Hudson Dashboard:

Hudson_dashboard

b. Emma Coverage Trend:

emma-coverage-trend

c. Check Style

check-style

d. JavaNCSS

JavaNCSS

7. Troubleshooting.
A few problems I found getting this up and running:

If you see the build failed with the following exception, copy the JDepend library to your ANT_HOME/lib folder.

compile:
    [mkdir] Created dir: /Users/meerasubbarao/Development/ci-jobs/jobs/CodeMetricsProject/workspace/CodeMetricsProject/target/classes
    [javac] Compiling 22 source files to /Users/meerasubbarao/Development/ci-jobs/jobs/CodeMetricsProject/workspace/CodeMetricsProject/target/classes
    [javac] Note: Some input files use unchecked or unsafe operations.
    [javac] Note: Recompile with -Xlint:unchecked for details.
     [echo] Panopticode - Using JDepend for OO metrics
     [echo] If you get an error stating 'Could not create task or type of type: jdepend' then you need to copy the jdepend-2.9.1.jar file to your ANT_HOME/lib directory.

BUILD FAILED
/Users/meerasubbarao/Development/ci-jobs/jobs/CodeMetricsProject/workspace/CodeMetricsProject/build.xml:54: The following error occurred while executing this line:
/Users/meerasubbarao/Development/ci-jobs/jobs/CodeMetricsProject/workspace/CodeMetricsProject/panopticode/panopticode-imports.xml:125: The following error occurred while executing this line:
/Users/meerasubbarao/Development/ci-jobs/jobs/CodeMetricsProject/workspace/CodeMetricsProject/panopticode/supplements/jdepend/jdepend-imports.xml:38: Problem: failed to create task or type jdepend
Cause: the class org.apache.tools.ant.taskdefs.optional.jdepend.JDependTask was not found.
        This looks like one of Ant's optional components.
Action: Check that the appropriate optional JAR exists in
        -/usr/share/ant/lib
        -/Users/meerasubbarao/.ant/lib
        -a directory added on the command line with the -lib argument

Do not panic, this is a common problem.
The commonest cause is a missing JAR.

This is not a bug; it is a configuration problem

Total time: 5 seconds
Publishing Javadoc
Recording Emma reports CodeMetricsProject/reports/emma.xml
finished: FAILURE

In the Panopticode-imports.xml file, you see the following comments:

    <!--
        Panopticode supports multiple competing code coverage tools.  You can switch which tool you use at will and your
        build files will not change.  You must choose exactly one though.  If you do not want to collect coverage data
        then choose the 'nocoverage' import.  You choose your coverage tool by using exactly one of the following import
        statements:

            <import file="plugins/emma/emma-imports.xml" />
            <import file="plugins/cobertura/cobertura-imports.xml" />
            <import file="plugins/nocoverage-imports.xml" />

        The default is Emma.  Try them all to see which one you prefer.
    -->
	<import file="supplements/emma/emma-imports.xml" />

However, if you try to comment the import for emma and use cobertura import definition, you get an error as shown below:

Buildfile: ../CodeMetricsProject/build.xml

BUILD FAILED
../CodeMetricsProject/build.xml:3: The following error occurred while executing this line:
../CodeMetricsProject/panopticode/panopticode-imports.xml:42: Cannot find plugins/cobertura/cobertura-imports.xml imported from ../CodeMetricsProject/panopticode/panopticode-imports.xml

Total time: 223 milliseconds

Now, if I go back and change it to the directory where I found the cobertura-imports.xml file (supplements), I get an exception like this:

[cobertura-report] Report time: 263ms
     [move] Moving 1 file to /Users/meerasubbarao/Development/ci-jobs/jobs/CodeMetricsProject/workspace/CodeMetricsProject/target/rawmetrics/xml
   [delete] Deleting directory /Users/meerasubbarao/Development/ci-jobs/jobs/CodeMetricsProject/workspace/CodeMetricsProject/target/rawmetrics/xml/cobertura
   [delete] Deleting: /Users/meerasubbarao/Development/ci-jobs/jobs/CodeMetricsProject/workspace/CodeMetricsProject/cobertura.ser

BUILD FAILED
../CodeMetricsProject/build.xml:54: The following error occurred while executing this line:
../CodeMetricsProject/panopticode/panopticode-imports.xml:145: emmaFile emma.xml does not exist

Total time: 7 seconds

Next, I changed the report file to cobertura.xml, and the build complained about:

[cobertura-report] Report time: 264ms
     [move] Moving 1 file to ../CodeMetricsProject/target/rawmetrics/xml
   [delete] Deleting directory ../CodeMetricsProject/target/rawmetrics/xml/cobertura
   [delete] Deleting: ../CodeMetricsProject/cobertura.ser
[emmaPanopticode] Loading panopticode structure: panopticode.xml
[emmaPanopticode] Loading supplement: org.panopticode.supplement.emma.EmmaSupplement

BUILD FAILED
../CodeMetricsProject/panopticode/panopticode-imports.xml:145: null

Total time: 8 seconds

Finally, I downloaded the source code to see the classname for this taskdef, couldn’t find one and just gave up at this point.
You should be able to generate coverage report for Emma with no problems at all.

As you can see from this article, it is just a few minutes to setup and start using Panopticode. As I mentioned earlier also, there are many open source tools available, that can improve the quality of your code and also keep track of the same if they are automated and are part of your continuous integration. I am sure once you have these open source tools integrated, you will keep wondering how you developed code without them.

Next Page »