Search This Blog

Wednesday, July 4, 2007

Code review

During a code review I stumbled accross the following code:
SomeObject someObject; 
if(o instanceof SomeObject) {
someObject = (SomeObject)o;
} else {
throw new ClassCastException("Cannot cast=[" + o.getClass() + "] to expected class=["+ SomeObject.class + "]");
}

Obviously the throwing of the ClassCastException is redundant. You can replace the above code with the following statement:
SomeObject someObject = (SomeObject)o; 

This statement doas semantically the exact same thing! At runtime a ClassCastException is thrown when object o cannot be cast to SomeObject. By looking at the stacktrace you can figure out where in your code things go wrong.

Moral of this story: use code reviews to improve the quality of your code.

Wednesday, June 27, 2007

Using Spring elements and attributes in your custom namespace

With Spring 2 it is possible to define your own namespace and have your own custom elements which you can use in the application context. Sometimes, allthough I do not promote this, you want to use Spring elements and attributes on your custom elements. For example: suppose I have a custom element named "foo:myCustomFooElement" with one attribute named "text". By default, you can't write something like this:

< foo:mycustomfooelement text="test" abstract="true">
< property name="property" value="value">
< /foo:myCustomFooElement>

This is because the property element and abstract attribute are not defined in your xsd which describes your custom element. Following is the source of a sample application I wrote to demonstrate the use of Spring properties and attributes on custom elements. The reason I do not promote this, is because you will loose the encapsulation of implementation details which your custom element hides. So use it with care.

public class Foo {
// This property gets injected by our custom FooParser
private String text;

// This property gets set by using Spring's < property> element
private Bar bar;

// getters and setters omitted

}

We will write a custom element for the Foo class.
public class Bar {
private int count;

// getter and setters omitted
}

Bar is just a regular class that gets injected in Foo. Below is the xsd I wrote to define myCustomFooElement:
< ?xml version="1.0" encoding="UTF-8"?>
< xsd:schema xmlns="http://www.mynamespace.com/foo"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:beans="http://www.springframework.org/schema/beans"
targetNamespace="http://www.mynamespace.com/foo"
elementFormDefault="qualified" attributeFormDefault="unqualified">

< xsd:import
schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
namespace="http://www.springframework.org/schema/beans" />

< xsd:element name="myCustomFooElement">
< xsd:complextype>
< xsd:complexcontent>
< xsd:extension base="beans:identifiedType">
<!-- Here we re-use Spring elements and attributes -->
< xsd:group ref="beans:beanElements">
< xsd:attributegroup ref="beans:beanAttributes">
< xsd:attribute name="text" type="xsd:string"
use="required" />
< /xsd:extension>
< /xsd:complexContent>
< /xsd:complexType>
< /xsd:element>
< /xsd:schema>

The XML file containing the bean definitions looks like this:
< beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:foo="http://www.mynamespace.com/foo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.mynamespace.com/foo http://www.mynamespace.com/foo/foo.xsd">

< foo:mycustomfooelement id="foo" text="test" init="true">
<!-- Here we use a Spring property element inside our custom element -->
< property name="bar">
< bean class="nl.sample.customnamespace.Bar">
< property name="count" value="100">
< /bean>
< /property>
< /foo:myCustomFooElement>
< /beans>

To parse the myCustomFooElement we must create a namespacehandler and register a beandefinition parser like this:
public class FooNameSpaceHandler extends NamespaceHandlerSupport {
private static final String NAME_CUSTOM_FOO_ELEMENT = "myCustomFooElement";

public void init() {
registerBeanDefinitionParser(NAME_CUSTOM_FOO_ELEMENT, new FooParser());
}

class FooParser extends AbstractBeanDefinitionParser {
@Override
protected AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
// Here we parse the Spring elements such as < property>
BeanDefinitionHolder holder = parserContext.getDelegate().parseBeanDefinitionElement(element);
BeanDefinition bd = holder.getBeanDefinition();
bd.setBeanClassName(Foo.class.getName());

// Here we parse our custom attributes
String text = element.getAttribute("text");
bd.getPropertyValues().addPropertyValue("text", text);
parserContext.getRegistry().registerBeanDefinition(NAME_CUSTOM_FOO_ELEMENT, bd);
return (AbstractBeanDefinition) bd;
}
}
}

Don't forget to register the namespacehandler in a file called spring.handlers in the META-INF directory. The contents of de spring.handlers file looks like this:
http\://www.mynamespace.com/foo=nl.sample.customnamespace.FooNameSpaceHandler

Also, specify in the META-INF/spring.schemas file where Spring can find the foo.xsd:
http\://www.mynamespace.com/foo/foo.xsd=nl/sample/customnamespace/foo.xsd

Write a class to verify everything works:
public class Driver {
public static void main(String[] args) {
ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext("classpath:nl/sample/customnamespace/customelements.xml");
Foo foo = (Foo) appContext.getBean("foo");
System.out.println("foo.text = " + foo.getText());
System.out.println("foo.bar.count = " + foo.getBar().getCount());
}
}

Extensive documentation about extensible XML authoring can be found in the reference manual. Eriks Wiersma has also written an excellent piece on his [URL="http://erik.jteam.nl/?p=23"]blog[/URL] about implementing custom namespaces.

Tuesday, March 6, 2007

Comparing two XML documents

When writing unit tests involving XML you often want to compare two XML documents. This can easily be done using a simple String compare as in:

expectedXML.equals(responseXML);

Where ‘expectedXML’ is the XML we expect to get back and ‘responseXML’ is the actual XML that is given as a response.

The problem with this approach is that it not only compares the actual XML but also any unimportant whitespace, tabs etc. This is not the desired behavior because it breaks our test when, for example, whitespaces are added in de reponseXML.

One solution to this problem is to use a handy utility class named DocumentComparator, which is part of the JIBX distribution. The javadoc of the DocumentComparator says the following:

XML document comparator. This uses XMLPull parsers to read a pair of documents in parallel, comparing the streams of components seen from the two documents. The comparison ignores differences in whitespace separating elements, but treats whitespace as significant within elements with only character data content.

This is exactly the functionality we need. With this class we can write the following code to compare two XML documents:

ByteArrayOutputStream out = new ByteArrayOutputStream();
DocumentComparator comp = new DocumentComparator(new PrintStream(out));
boolean result =comp.compare(new StringReader(responseXml), new StringReader(expectedXml));
assertEquals(out.toString(), true, result);

The DocumentComparator class uses the PrintStream to report any differences found when comparing the two documents.

Monday, February 26, 2007

Core Spring training experience

The training was given by Arjen Poutsma. Arjen works for Interface21 and is the lead developer of the Spring-WS sub project.

Day 1, 20 february 2007

Day 1 is all about the core concepts of the Spring framework like Inversion of Control and Dependency Injection. IOC and DI are essential parts to understanding Spring's architecture. Besides some basic subjects about IOC and DI there were also advanced concepts that were given attention: autowiring, life cycle callbacks, property editors, factory beans, post processors etc. The Lab's in day 1 were all about configuring application contexts. However there was also a bonus section which programmatically used AOP via ProxyFactory(s) with dynamic TargetSource(s).

If you already know Spring than the subjects in day 1 are familiar.

Day 2, 21 february 2007

Day 2 was all about effective middle tier architecture with Spring. Subjects that got attention were:

  • Persistence with Spring JDBC and ORM tools
  • Data Access Objects with Spring
  • Brief introduction about transaction management
  • Test Driven Development with Spring
  • Introduction to AOP
  • Advanced data access concepts such as: batch updates, blob handling and stored procedures.

The labs were about using Spring in conjunction with Hibernate and using Spring utilities for creating integration tests.

Day 3, 22 february 2007

After a brief introduction about transaction management in day 2, this day continued with the more advanced topics about transaction management. Specifically:

  • local versus global transactions
  • declarative versus programmatic
  • transaction propagation
  • isolation levels

The rest of the day was about Spring-MVC including several labs covering handler mappings, input forms and interceptors.

The last subject for this day was an introduction about Acegi security system for Spring.

Day 4, 23 february 2007

For me, day 4 was most interesting. This was mainly because AOP got in depth-attention. Arjen focused on Spring 2's support for AOP with Spring and AspectJ. Some advanced concepts such as introductions also got attention.

The remainder of the day was used to tell something about Spring's support for JMX and remoting. Arjens's project Spring-WS got little attention. The main point about Spring-WS is that it promotes contract-first development.

Things to remember

  • Spring 2.1 will not be compatible anymore with JDK 1.3
  • The upcoming new version of Spring IDE will support dependency listing for aspects build with Spring-AOP. With this feature you can view all aspects that are applied to a particular class.
  • Migrating from Spring-AOP to AspectJ is easier when using the @Aspect annotations in Java classes rather than using XML to configure aspects. This is because AspectJ understands these annotations.

Conclusion

Although I had experience with Spring before taking this training, I am glad I took it. A lot of concepts used in Spring were covered in detail. I can recommend this training to anyone who would like to gain more in depth knowledge of the Spring framework.

When taking this training, I found it very helpful to have knowledge about enterprise application patterns, transactions, J2EE, TDD, DDD, Hibernate etc.

Monday, February 19, 2007

Core Spring training

This week I am happy to attend the Core Spring training in Amsterdam given by Interface21. The Core Spring training is a full 4 day training covering all aspects on Spring from IOC and dependency injection to Spring MVC and testing with Spring. This week I will post my day-to-day experiences on this training. More information on this training can be found at: www.interface21.com.

Friday, February 16, 2007

Service contracts

XML is a common format for message exchange in Service Oriented Architectures. One of the most important things is to formalize the messages exchanged between systems. This can be done using XML schema definitions. XML schema defines the rules to which a XML message must conform when it is constructed. A well defined schema brings the following advantages:
  1. Validate messages when they are constructed and thus before they are sent.
  2. Generate Java classes from the XML schema for use in XML binding frameworks.
  3. Easily construct mock XML messages with a tool like XMLSpy for use in (unit)tests or mock implementations of services.

With “well defined schema” I mean a schema definition which is constructed before the actual service is implemented so every element in the schema is well thought out. Another example: when some element’s value is an enumeration of some values, define this in the schema definition and not in a separate document (I,ve seen it happen). This way you restrict the values an element can contain and it becomes much easier to construct mock XML messages for testing purposes.

The bottom line is: invest in the construction of well thought out service contracts.

A good reference for designing XML schema definitions can be found here.

Starting up...

Finally created my Blog today to post my ideas, thoughts and experiences about Enterprise Java development. Although Java is the primary field of interest, it is not the only field of interest. For example, I will also post my latest experiences with Adobe Flex to build highly interactive user interfaces on top of Java backends. I Already can say that I am very impressed. But more on that in one of my next posts.

The only thing for now I would like to say is: Happy reading!