Home | About Us | Stelligent  

TestEarly Weblog
Build Management and Continuous Integration and Publications11 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 Testing24 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 Testing23 Sep 2008 02:39 pm

http://wondermark.com/d/445.html

Developer Testing and Build Management and Tutorial and Agile23 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 Testing22 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 Agile10 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 Agile29 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.

Developer Testing and Continuous Integration and Agile21 Aug 2008 11:09 am

I have been on several teams where we studiously designed UML diagrams at the beginning of the project. As the project progressed, and deadlines approached, the UML diagrams were left somewhere behind, not to be updated in months. When a new developer joined the team, we showcased the old UML diagrams, and kept telling ” Oh, we never had time to update them, please see the source code to get an idea. And, don’t hesitate to ask if you have any doubt’s”. I am sure, you all have gone through the same scenario.
However, we don’t have to keep making up stories anymore, since this article shows how easy and simple it is to include UML diagrams within your Javadoc and also keep them updated with every change in the source code repository. We can do these in less than a few minutes, and in a few simple steps.

Getting started with UmlGraph takes five steps:

1. Download the source code for UMlGraph.
2. Download and install Graphviz.
3. Make changes to your Ant build file.
4. Run the Ant target.
5. Add this target to your CI job.

Step 1: Download the source code for UMLGraph here. Unzip the contents. To compile the Java doclet from the source code run ant on the build.xml file. Copy the UmlGraph.jar file to your projects library. If there is a version mismatch between the different versions of JDK you are using you get an exception like this:

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

Make sure you recompile the UMLGraph source code, and copy the library to your project.

compile-umlgraph

Step 2 : Download and install Graphviz from here. The dot file needs to be post-processed with Graphviz to produce the actual UML diagram. Running the UmlGraph doclet will generate a Graphviz diagram specification that can be automatically processed to create png drawings. You can also generate other formats using Graphviz as well. If Graphviz isn’t installed you will get an exception as shown below:

BUILD FAILED
/Users/meerasubbarao/Development/webservices-samples/build.xml:107:
Execute failed: java.io.IOException: dot: not found
Total time: 269 milliseconds

Step 3. Changes to your build.xml file.
Assuming you already have a working project, with Ant build file. Add the following target to your build.xml file as shown below:

	<target name="javadocs" depends="build" description="generates javadoc and also UML Diagram">
		<mkdir dir="${reports.dir}/javadoc"/>
	        <javadoc sourcepath="${src.dir}" packagenames="com.stelligent.*" destdir="${reports.dir}/javadoc"
	        	classpathref="java.classpath" private="true">
	        	   <doclet name="org.umlgraph.doclet.UmlGraphDoc"
	        		  path="lib/UMLGraph.jar">
	        	        <param name="-attributes" />
	        	        <param name="-operations" />
	        	        <param name="-qualify" />
	        	        <param name="-types" />
	        	        <param name="-visibility" />
	        	    </doclet>
	        	  </javadoc>
		  <apply executable="dot" dest="${reports.dir}" parallel="false">
		    <arg value="-Tpng"/>
		    <arg value="-o"/>
		     <targetfile/>
		     <srcfile/>
		     <fileset dir="${reports.dir}" includes="*.dot"/>
		     <mapper type="glob" from="*.dot" to="*.png"/>
		  </apply>
	</target>

A number of options control the operation of UMLGraph class diagram generator. These can be specified as parameters within your build file as shown above.

Details about a few options are:

-output
Specify the output file (default graph.dot).
-d
Specify the output directory (defaults to the current directory).
-qualify
Produce fully-qualified class names.
-horizontal
Layout the graph in the horizontal direction.
-attributes
Show class attributes (Java fields)
-operations
Show class operations (Java methods)
-constructors
Show a class's constructors
-visibility
Adorn class elements according to their visibility (private, public, protected, package)
-types
Add type information to attributes and operations
-enumerations
Show enumarations as separate stereotyped primitive types.
-enumconstants
When showing enumerations, also show the values they can take.
-all
Same as -attributes -operations -visibility -types -enumerations -enumconstants

Step 4. Run the ant target:
Open a command window and run the ant target: ant javadocs and you should see output as such in your console window:

meera-subbaraos-macbook-9:webservices-samples meerasubbarao$ ant javadocs
Buildfile: build.xml

init:

cleanGenerated:

build:
    [javac] Compiling 22 source files to /Users/meerasubbarao/Development/ci-jobs/jobs/PetStore_Nightly/workspace/webservices-samples/classes
    [javac] Note: Some input files use unchecked or unsafe operations.
    [javac] Note: Recompile with -Xlint:unchecked for details.

javadocs:
  [javadoc] Generating Javadoc
  [javadoc] Javadoc execution
  [javadoc] Loading source files for package com.stelligent.biz.ws...
  [javadoc] Loading source files for package com.stelligent.ent.jpa...
  [javadoc] Constructing Javadoc information...
  [javadoc] UmlGraphDoc version 5.0, running the standard doclet
  [javadoc] Standard Doclet version 1.5.0_13
  [javadoc] Building tree for all the packages and classes...
  [javadoc] Building index for all the packages and classes...
  [javadoc] Building index for all classes...
  [javadoc] Generating /Users/meerasubbarao/Development/ci-jobs/jobs/PetStore_Nightly/workspace/webservices-samples/reports/javadoc/stylesheet.css...
  [javadoc] UmlGraphDoc version 5.0, altering javadocs
  [javadoc] Building Package view for package com.stelligent.biz.ws
  [javadoc] Building Package view for package com.stelligent.ent.jpa
  [javadoc] Building Context view for class com.stelligent.biz.ws.SupplierManagerBean
  [javadoc] Building Context view for class com.stelligent.biz.ws.SupplierManager
  [javadoc] Building Context view for class com.stelligent.biz.ws.SignonManagerBean
  [javadoc] Building Context view for class com.stelligent.biz.ws.SignonManager
.....

BUILD SUCCESSFUL
Total time: 8 seconds
meera-subbaraos-macbook-9:webservices-samples meerasubbarao$ 

The javadoc generated is pretty neat with UML diagrams on the top:

uml-diagram

Step 5: Add this target to your CI Job.
If you already have a CI server like Hudson up and running, which runs commit builds and nightly builds, adding this new target is a one step process. In my case, I already have a nightly job running as shown below. I have added this ant target to my default target as shown below:

<target name="all" depends="cleanAndDeployForCoverage, javadocs" />

Next, force a build on the Hudson job, publish the javadocs, and you can see the results on the hudson dashboard.

Hudson-Job

The Javadoc displayed from within the Hudson dashboard:

nightly-job

Now that we have UML diagram integrated within our build file and also our CI job, we can ensure that our code base and the UML diagrams are always in sync. We saw how to include these ant targets in our commit builds or nightly builds of our CI jobs, and also published these artifacts as part of our post build process.

Resources:

Developer Testing and Book Review20 Aug 2008 09:51 am

book-imageSpring Recipes covers Spring 2.5 from basic to advanced, and introduces several common Spring projects that will bring significant value to your application development. The books is divided into 19 chapters; and these chapters are organized into 3 parts. The author starts off by discussing the Spring IoC container, Spring AOP and AspectJ, Spring data access support, Spring transaction management, Spring Web and Portlet MVC, Spring testing support, Spring support for remoting, EJB, JMS, JMX, E–mail, scheduling, and ends the book with scripting languages. This book also introduces several common Spring Portfolio projects that will bring significant value to your application development, including Spring Security, Spring Web Flow, and Spring Web Services.

Who should read this book:
The intended audience for Spring Recipes is a Java programmer with no prior knowledge of Spring. The only other prerequisite with Spring as we all know, is working experience with XML.
Reader with experience in enterprise applications will find it valuable in understanding the benefits of Spring.This book is for Java developers who would like to get hands-on experience using the Spring framework. Basic knowledge of Java, web and database concepts is needed to gain more from this book.

How This Book Is Oragnized:
The Spring Recipes book covers a significant number of technologies. I liked the way the author has organized the book. Each chapter of this book discusses a Spring topic; each topic has multiple problem-solution recipes as shown below:
problem-solution

Part 1: Core: This part focuses on the core concepts and mechanisms of the Spring framework. The chapters in this part aim to familiarize you with Spring’s core. The most important contribution to programming world by Spring is its implementation of IoC design principal. For those who haven’t been introduced to IoC, the author does a very detailed job of explaining how an IoC container operates. If you are using Spring for the first time, chapters 1-4 are a must read. Chapter 1-4 are dedicated to IoC, and also introduces basic bean configuration which is required for reading the subsequent chapters, Chapters 5 and 6, explains why you need AOP, AOP usage, and some advanced AOP topics, including how to integrate the AspectJ framework within your Spring applications.

Part 2 : Fundamentals: The topics covered in this part are most commonly used in developing any enterprise application. The first two chapters in this part, chapter 7, 8 and 9 show how to use Spring to simplify data access (with JDBC, Hibernate, and JPA) and manage transactions programmatically and declaratively and also explains transaction attributes in detail. Next, in chapter 10 the author discusses web-based application development using the Spring MVC framework; you get to learn Spring MVC using both the traditional approach and the new annotation-based approach.

If you don’t want to use Spring MVC, you don’t have to, you still can use Spring with any other popular web application framework out there, and that;s exactly what is covered in chapter 11:Integrating Spring with Other Web Frameworks. On finishing this chapter, you should be able to integrate Spring into web applications implemented with Servlet/JSP and other frameworks such as Struts, JSF and DWR.

Part 2 finishes with one more chapter, Spring Testing Support. And in this you will learn the basic concepts and techniques of testing using the two most popular frameworks JUnit and TestNG. You will also learn how to create unit tests and integration tests using both the JUnit 3.8 support and also the Spring TestContext framework.

Part 3: Advanced: If you are an advanced Spring user, this part is definitely for you. Chapter 13, discusses security concepts (authentication, authorization, and access control), and securing web applications using Spring Security 2.0, formerly known as Acegi Security. Chapter 14, introduces portlet application development using Spring Portlet MVC framework, and focusses on the portlet specific features.

The next chapter, focuses on how to use Spring Web Flow to model and manage your web applications UI flows. It covers using Spring Web Flow 2.0 in Spring MVC and JSF.

Remote services are part of any enterprise services. Earlier, EJBs were one of the most common way to implement such services.Spring, on the other hand provides support for various remoting technologies such as RMI, Hessian, Burlap, HTTP Invoker, and Web Services; and all these topics are covered with great detail in Chapter 16: Spring and Remoting and Web Services. I am no big fan of writing the WSDL first, which is the basic requirement for contract-first web services. But, if you are than this chapter also covers developing contract-first web services using Spring Web Services.

I am huge fan of the latest Java EE specification, and Chapter 17: Spring support for EJB and JMS discusses how to develop EJB 2.x and 3.0 components with Spring’s EJB support, and also how to use Spring’s JMS support to simplify sending, receiving, and listening to JMS messages.

Chapter 18: Spring support for JMX, E-mail and Scheduling, the author discusses how to export Spring beans as JMX MBeans by using MBeanExporter. Spring also allows you to define JSR-160 connectors in the IoC container to expose your MBeans for remote access over a specific protocol. You will also see an example of how to annotate your beans with Spring’s JMX annotations, and Spring can detect and export these as MBeans automatically. Spring’s e-mail support makes it trivial for sending e-mail by providing an abstract and implementation-independent API for sending e-mail. Spring comes with utility classes for both JDK Timer and Quartz for you to configure scheduling tasks in the bean configuration file, without programming against the JDK Timer and Quartz APIs and you will see examples of using both these in this chapter.

JRuby, Groovy, and BeanShell are the most popular scripting languages in the Java community and Spring 2.5 supports these three scripting languages. Chapter 19: Scripting in Spring is all about these scripting languages and Spring. You will learn how to use the scripting languages supported by Spring to implement your beans and how to declare them in the Spring IoC container. You will see examples on how specify the location for an external script source file or define an inline script source in the bean configuration file. As the script sources may require frequent and dynamic changes, Spring can detect and refresh changes from the script source files automatically. Finally, you will get to work with an example which shows how to inject property values as well as bean references into your scripts.

Conclusion:
This is the book for developers looking to integrate Spring into their enterprise applications. To be honest, any developer who develops an application using Spring should probably have a copy of this book on their bookshelf. The examples work, and are exceptionally well chosen to present real-world problems and potential solutions. You would hardly want to build a real-world application without carefully consulting this book for samples about “how it’s done”, eaxctly like the author asks us to do here:
author-examples

Developer Testing and Tutorial and Agile14 Aug 2008 08:44 am

This tutorial takes a look at SOAP Message handlers and how easy it is to write handlers using JAX-WS 2.0. JAX-WS 2.0 allows both regular Java classes and stateless EJBs(Session beans) to be exposed as web services. The JAX-WS 2.0 is the core specification that defines the web services standard for Java EE 5 specification. JAX-WS 2.0 is an extension of the Java API for XML-RPC (JAX-RPC) 1.0.

SOAP message handlers are used to intercept the SOAP message as they make their way from the client to the end-point service and vice-versa. These handlers intercept the SOAP message for both the request and response of the Web Service. If you are familiar with EJB interceptors, handlers are similar to EJB interceptors and are defined in an XML file.

A few typical scenarios where you would be using SOAP Message handlers are: for encrypting and decrypting messages, to support logging, caching and in some cases auditing, and in rare cases to provide transaction management as well.

So much for the theory. Lets see the three basic steps to use a simple log handler to intercept and print our SOAP messages (request and response).

In this tutorial, we are going to expose an EJB 3 stateless session bean as a web service which is so simple and can be done by simply adding the @WebService annotation. So, here comes the source code for the interface as well as the implementation class which is self explanatory:

package com.ws;

import javax.ejb.Remote;

/**
 *
 * @author meerasubbarao
 */
@Remote
public interface HelloWebServiceRemote {

    String sayHello(String name);

}
package com.ws;

import javax.ejb.Stateless;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;

/**
 *
 * @author meerasubbarao
 */
@WebService
@Stateless
public class HelloWebServiceBean implements HelloWebServiceRemote {

    @WebMethod(operationName = "sayHello")
    public String sayHello(@WebParam(name = "name") String name) {
        return "Hello " + name;
    }

}

You can package the two source files shown above into a jar, deploy to your application server, and test it as well. I am using GlassFish V2 and SoapUI to test my web services. So, shown below are the request and response from SoapUI:

Now that we know our web services work, lets start writing the message handler, which I said earlier is just 3 steps. So, what are these SOAP message handlers? They are simple Java classes that can easily modify SOAP messages; both request as well as response. These handlers have access to both the SOAP header as well as the body of the message.

soapui-test

Step 1. Implement the SOAPHandler interface.

package com.ws;

import java.io.IOException;
import java.util.Collections;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;

/**
 *
 * @author meerasubbarao
 */
public class LogMessageHandler implements SOAPHandler<SOAPMessageContext> {

    public boolean handleMessage(SOAPMessageContext messageContext) {
         return true;
    }

    public Set<QName> getHeaders() {
        return Collections.EMPTY_SET;
    }

    public boolean handleFault(SOAPMessageContext messageContext) {
        return true;
    }

    public void close(MessageContext context) {
    }

}

The handleMessage method is invoked for both incoming as well as outgoing messages. Lets add a new method called log() and invoke this method from the handleMessage method. Shown below are both the methods:

    private void log(SOAPMessageContext messageContext) {
           SOAPMessage msg = messageContext.getMessage(); //Line 1
        try {
            msg.writeTo(System.out);  //Line 3
        } catch (SOAPException ex) {
            Logger.getLogger(LogMessageHandler.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(LogMessageHandler.class.getName()).log(Level.SEVERE, null, ex);
        }
  }

In line 1, we are retrieving the SOAPMessage from the message context. Line 3 will print the incoming and outgoing messages in our GlassFish console.

Invoke this method from within the handleMessage as shown:

    public boolean handleMessage(SOAPMessageContext messageContext) {
        log(messageContext);
        return true;
    }

Step 2: Create the XML file for the Handler Chain.
Create this XML file in the same package as the web service with the name LogMessage_handler.xml.

<?xml version="1.0" encoding="UTF-8"?>
<handler-chains xmlns="http://java.sun.com/xml/ns/javaee">
  <handler-chain>
    <handler>
      <handler-name>com.ws.LogMessageHandler</handler-name>
      <handler-class>com.ws.LogMessageHandler</handler-class>
    </handler>
  </handler-chain>
</handler-chains>

So, let me explain about the various elements used above:

1. handler-chains is the root element that will contain a list of all handler chains that are defined for the Web Service.
2. The handler-chain child element of the handler-chains element lists all the handlers in the handler chain.
3. Within the handler-chain element is defined the handler, each handler element must in turn specify the name and also the fully qualified name of the Java class that implements the handler. If you have more than one handler, specify each one of them within the handler-chain element.

Step 3: Invoking the Handler
The @HandlerChain annotation is used to define a set of handlers that are invoked in response to a SOAP message. So, within our HelloWebServiceBean implementaion, you need to make a simple change to invoke the Log Handler as shown below:

package com.ws;

import javax.ejb.Stateless;
import javax.jws.HandlerChain;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;

/**
 *
 * @author meerasubbarao
 */
@WebService
@Stateless
@HandlerChain(file = "LogMessage_handler.xml") // Line 1
public class HelloWebServiceBean implements HelloWebServiceRemote {

    @WebMethod(operationName = "sayHello")
    public String sayHello(@WebParam(name = "name") String name) {
        return "Hello " + name;
    }
 }

Now, that we have added the annotation, recompile, package and deploy the application.

Lets invoke the web services and see if it works, if it did, we should be able to see the request and response logged in our GlassFish console window, right?

So, here comes the output:
**RemoteBusinessJndiName: com.ws.CustomerManagerRemote; remoteBusIntf: com.ws.CustomerManagerRemote
LDR5010: All ejb(s) of [EJBWebServices] loaded successfully!
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.com/"><soapenv:Header/><soapenv:Body><ws:sayHello>
<name>Javalobby</name>
</ws:sayHello></soapenv:Body></soapenv:Envelope>
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/"><S:Body><ns2:sayHelloResponse xmlns:ns2="http://ws.com/"><return>Hello Javalobby</return></ns2:sayHelloResponse></S:Body></S:Envelope>

In this article, we saw how simple and easy it was to use SOAP Handlers to intercept request and response of SOAP messages. We implemented the SOAPHandler interface, wrote minimal XML to define the handler chain, and finally one simple annotation to the web service. We also were able to test these web service using SoapUI.

In Part 2 of this series, we will see how to actually parse the SOAP Headers, and also use multiple handlers.

Next Page »