Home | About Us | Stelligent  

TestEarly Weblog

August 2008


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.

Developer Testing and Continuous Integration and Agile and /Duvall21 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 Agile and /Duvall14 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.

Developer Testing and Agile and /Duvall11 Aug 2008 01:17 pm

Jurgen provides some examples of different kinds of burndown charts with additional information. Some of these ideas might be useful on your project(s).

Peter has some other interesting ideas on burndown chart presentation

Developer Testing and Tutorial07 Aug 2008 03:14 pm

Spring 2.0 introduced comprehensive support to use dynamic languages. It supports three different scripting languages; JRuby, Groovy and BeanShell. The scripting language used in this article is Groovy; which I think was designed for Java developers. As Scott Davis says in his book, Groovy Recipes” Groovy is Java at the end of the day”. “Spring Recipes - A Problem -Solution Approach” written by Gary Mak has a complete chapter dedicated to Scripting in Spring. The author covers all the three dynamic languages supported by Spring; JRuby, Groovy and BeanShell.

There are times when in your application you have certain modules that require frequent changes, and based on these changes you need to change the business logic within your modules. If these modules were written in Java, you can imagine what needs to be done at this point; recompile, package, redeploy. This is where modules written in these dynamic languages come in handy, there is no need to recompile, or redeploy for these changes to take effect. In most cases, you want the Spring container to be able to detect these changes and also pick up the new state from the changed script source. Spring allows you to do this as well by setting one simple attribute.

Hello World Example: It is customary to start any tutorial by writing a simple HelloWorld program, right? We are going to use Groovy in this tutorial. This tutorial assumes you have some knowledge of Spring and Groovy. I used Eclipse IDE for this tutorial, and to work with Spring and Groovy in Eclipse, you need the following libraries in your build path.

java-build-path

So, lets begin with the HelloWorld example here.

Step 1: Lets define an interface for our HelloWorld Service:

package com.springandgroovy;

public interface HelloWorldService {

	String sayHello();

}

Step 2 : Implement the interface in Groovy.
Next, we implement this interface in Groovy by creating a simple script within the com.springandgroovy package as such:

import com.springandgroovy.HelloWorldService;

class HelloWorldServiceImpl implements HelloWorldService {

	String name

   String sayHello()
   {
   		"Hello $name. Welcome to Scripting in Groovy."
   }
}

Step 3: Make changes to Spring’s configuration file.
Here comes the Spring’s bean configuration file, in which you have to include the lang schema to use the custom dynamic language tags.

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:lang="http://www.springframework.org/schema/lang"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/lang
        http://www.springframework.org/schema/lang/spring-lang-2.5.xsd">

the bean definition for the Groovy backed HelloWorldService looks like this:

<lang:groovy id="helloWorldService"
			 script-source="classpath:com/springandgroovy/HelloWorldServiceImpl.groovy">
			 <lang:property name="name" value="meera"/>
</lang:groovy>

That’s all you need to use Groovy backed beans in Spring. So, how do we know this works, right? Lets write a simple Main class and test it within our IDE:

Step 4: Run the HelloWorldService.

package com.springandgroovy;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

   public static void main(String[] args) throws Exception {

     ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
     HelloWorldService service = (HelloWorldService) context.getBean("helloWorldService");

     System.out.println(service.sayHello());

    }

}

And you should be able to see output in the console as such:

console-window

Step 5: Refreshable Beans.
As I mentioned earlier also, to turn on this feature we have to specify one simple attribute refresh-check-delay on the element of our bean definition as such:

<lang:groovy id="helloWorldService"
			 script-source="classpath:com/springandgroovy/HelloWorldServiceImpl.groovy"
			 refresh-check-delay="5000">
			 <lang:property name="name" value="meera"/>
</lang:groovy>

Again, how do we know this works when we make changes to our Groovy Script? A small change in our Main class and, and you should be set to test that this works as well:

package com.springandgroovy;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

    public static void main(String[] args) throws Exception {

    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    HelloWorldService service = (HelloWorldService) context.getBean("helloWorldService");
    System.in.read();
    System.out.println(service.sayHello());

    }

}

Now, run the Main class in your IDE, it halts because of the System.in.read line, make a few changes within your script, save it, hit enter in your console window in your IDE. The Spring container read our new changes and prints the results within the console window.

The script change can be as simple as adding a few special characters as such within the sayHello() method:

   String sayHello()
   {
   		"Hello $name!!!. Welcome to Scripting in Groovy."
   }

And the console window reflects these changes:

updated-console-window

Step 6: Inline Scripts
Spring also allows you to embed scripts directly within the Spring bean definitions inside your Spring configuration file. I am no fan of doing this, because it has a drawback; the refresh attribute is not applicable for inline scripts. Lets take a look at this in case you need to use this feature:

Copy the script we wrote in Step 2 and paste it within the lang:inline-script element as such:

   <lang:groovy id="helloWorldService">
        <lang:inline-script>
        <![CDATA[
 import com.springandgroovy.HelloWorldService;
  class HelloWorldServiceImpl implements HelloWorldService {

	String name

   String sayHello()
   {
   		"Hello $name. Welcome to Scripting in Groovy"
   }
}
        ]]>
        </lang:inline-script>
        <lang:property name="name" value="meera" />
    </lang:groovy>

Run the Main class and you should see the same output in your console window.

console-window

In this tutorial we learned how to use Groovy with Spring using an external script source file, how to refresh changes when a script source file is changed, and finally saw an inline script which was embedded within the Spring configuration file.

Additional Resources:

1. JRuby
2. Groovy
3. BeanShell
4. Spring
5. Spring Recipes

Developer Testing04 Aug 2008 01:52 pm

Having used NetBeans for a long long time, I thought I would share my views about some of the helpful aspects this IDE offers, some not so helpful, and finally finish off this post with the most annoying feature of NetBeans I have encountered. I started using NetBeans from version 4 on my windows machine for writing J2EE applications, the IDE took almost several minutes to startup which really annoyed me like it did for many others. I constantly switched back to Eclipse after trying each and every milestone and new release. From the last 4 weeks, I have been using NetBeans exclusively for writing a complex Java EE and a relatively simple Groovy and Grails applications.

So, here are some of the highlights about The Good, the Bad and the Ugly in my opinion:

With the latest 6.5 Milestone 1 version, it takes less than 7 seconds to start the IDE on my Mac laptop. So, the improved performance and faster startup is one of the biggest niceties when compared to the previous versions which drove me away from NetBeans towards Eclipse.

I am using the NetBeans IDE for development with the Java Persistence API(JSR-220), Enterprise JavaBeans(EJB) and web services. The Java EE module for the NetBeans IDE supports Java EE 5 and also the earlier versions of J2EE.

The Database support within the IDE is just awesome. With the wizard approach for creating connections and managing the same, it is very easy to create, update and also query your tables directly from within your IDE. By default, you can connect to Derby, MySQL and PostgreSQL. But, if you need to connect to other databases like MS SQL or Oracle, you just need to register the driver and you are all set as shown below:
driver-support

The IDE has wizards to work with the Java Persistence API. The Wizard enables you to generate entity classes from a database. The IDE looks at the database schema and generates all the necessary code for entity relationships.

driver-tables

However, the wizard here retrieves all the entity relationships(if Include Related Tables is checked) from the schema and there is no way to specify the directionality of the relationships. Lets say I have a relationship between the Customer and Address entity, I would have a relationship method within the Customer entity to retrieve the Address, I wouldn’t want to ask the Address entity who its Customer is? You can always open up the Java Source Editor and make changes, but it would have been really nice to have wizards in which you could manage relationships more efficiently. The NetBeans team should add, in my opinion, additional support to handle relationships well.

In many real life applications, you are most likely to develop read-only entities knowing that the table data changes relatively infrequently. There isn’t any support in any of the wizards to mark an Entity as read-only.

If you are using Java Persistence API in either the EJB module or web module, the IDE does allow you to create a persistence unit. As with all other modules, it does have a wizard approach in which you specify a few details and you have the persistence.xml file generated for you.
persistence-unti

Lets move from the persistence tier to the business logic tier. A wizard approach for generating Session beans as well as Message-Driven beans(MDB). Within the New Session Bean Wizard you can specify the session type(Stateless and Stateful) and also the type of interface you want the IDE to generate(Remote and/or Local). The wizard for the MDB’s is a little bit confusing when you have to choose between the project and server destinations, but the context sensitive help comes to our rescue here.

MDBS

The IDE also assists you with the development of Web Services; it supports a wide variety of web service standards such as the JAX-WS 2.1, JAX-RS (JSR-311), JAX-RPC (JSR-101). I have used the IDE for creating JSR311-compliant RESTful web services from JPA entity classes and SOAP-based web services from Java classes. To top this all, you can test web services using the new soapUI plugin.

NetBeans allows you to register any Java EE compliant server to deploy your applications. It supports all the major vendors out there as seen below:
application-servers

However, each time you want to deploy, run and test on an application server other than the one selected for your project, you would have to go through 3 steps as shown below.
target-server
I would rather have all the servers registered as sub menu items within the Run menu item. Don’t you agree?

I said a lot of things that are good and that need some improvement, so you may ask what is it that I find so ugly within the IDE. If you are writing enterprise Java application, in many cases Ant stands as the universal build platform. NetBeans by default creates all the build files for compiling, testing, deploying, undeploying and running your application. However, even after using Ant for several years now, I had serious trouble using these build files. I did use a tool called Grand and Vizant to generate visual documentation of the build files to understand them better and here is what I was able to get from them. The build files need heavy refactoring for anyone to continue to use within their enterprise applications.
ide-generated-build-file

So, here is my take on The Good, The Bad, & The Ugly I found within the NetBeans IDE for a simple Java EE application I was trying to create. Give it a try, and you will be surprised how far this IDE has come along.

Next Page »