Tuesday, August 28, 2007

Developer-friendly JAXB code generation with JAXB Commons and binding file

In my previous post "Defining service/component interfaces in WSDLs", I mentioned that "Not only are no-argument constructors and all public getter and setter methods generated for complex types, but also other useful methods, such as valued constructors, builder methods, hashCode, equals and toString methods can be implemented using XJC extensions." This post is about how to do this.

Our project uses XFire's WsGenTask Ant task to generate service interfaces, DTO classes and exceptions from WSDL file and the referenced XSD files. WsGenTask delegates the generation of DTO classes to JAXB's XJC compiler. However, these DTO classes generated by JAXB XJC's default are not particularly developer-friendly, in the following aspects:
  1. They have only one default constructor. This is quite inconvenient when you need to instantiate a DTO to hold some values:

    • You need to declare a local variable, which may otherwise be unnecessary.

    • You need to call the constructor to instantiate a new instance, then you need to invoke the setter methods for each property value you would like to it to hold.

    • To re-use the code and get rid of the local variable declaration, you need to create a factory class with one or more overloading create methods for each DTO class, which essentially are value-taking constructors moved to a factory class.

  2. They do not override the hashCode(), equals(Object) and toString() methods of the Object class. DTOs are value objects and no identity. Two instances holding exactly the same data should be considered interchangeable. Thus, overriding hashCode() and equals(Object) is essential for DTO classes. Moreover, not overriding toString() implementation makes it inconvenient in unit testing:

    • You cannot invoke assertEquals(Object, Object) directly. You have to rely on a static method to determine whether two objects are equal in values. And if the assertion fails, you need to invoke another static method to have a useful string representation of both the expected and actual objects.

  3. Default values are not honoured in the generated classes, that means you have to set the value explicitly even if you are using a default value in most cases.

  4. If you are not the owner of the schemas being used, the class and property names generated may not be following the Java's camel-case conventions.
  5. There is no setter method for collections. You need to invoke the getter method to retrieve the collection and invoke the addAll(Collection) method to add all elements of the prepared collection.

  6. If an element has a maxOccurs attribute value greater than one, the getter method generated is not using plural by default.

  7. Date, time and dateTime are generated as XMLGregorianCalendar, which requires constant conversion to and from the java.util.Date and java.util.Calendar values you use in your domain models.

Fortunately, XJC has an extension option that allows third-party extensions. A whole bunch of XJC plugins have been developed to iron out most of these isses in the open source community, and many of them are under the JAXB 2.0 Commons project hosted by java.net.

Many of the these plugins are very useful:
  1. The Value Constructor plugin generates a constructor that takes values for all properties besides the default no-argument constructor.

  2. If you have many properties in a DTO class, or some of the properties are optional, you can use the Fluent API plugin, which generates builder-styled methods, which essentially provides named-parameter constructor, which is not provided by Java.

  3. The jakarta-commons-lang plugin generates overriding hashCode(), equals(Object) and toString() methods using jakarta commons lang's HashCodeBuilder, EqualsBuilder and ToStringBuilder classes, which in turn uses reflection.

  4. The Default Value plugin honours the default values specified in the schemas.

  5. The CamelCase Always plugin generates class and property names following the camel-case convention.

  6. The Collection Setter Injection plugin generates setter methods for collections.


Unfortunately, at the time of this writing, XFire's WsGen does not pass parameters to JAXB's XJC, as tracked by this XFIRE-1038 JIRA. The way to get around it is to call the XJCTask Ant task after the WsGenTask call and overwrite all DTOs generated by WsGenTask.

Note that some of the plugins required JAXB 2.1 to work. If you intend to use JAXB 2.0 in runtime environment, it is fine: you can generate the classes using JAXB 2.1 with the target specified as "2.0" to avoid generating annotations introduced in JAXB 2.1.

To generate a plural form for collections, use a simple JAXB binding file with XJCTask.

If you would like to work with java.util.Date or java.util.Calendar instead of XMLGregorianCalendar, you can provide your own parseMethod and printMethod and specify them in your JAXB binding file used by XJCTask, as detailed by Sun's engineer Kohsuke's blog entry.

Follwing are extracted from the ant build file to illustrate how to generate developer-friendly DTO classes using JAXB:

<!-- This task will autogenerate the code from the XSD specification -->
<taskdef name="xjc" classname="com.sun.tools.xjc.XJCTask" >
<classpath>
<pathelement path="${jaxb1-impl-2.1.3.jar}:${jaxb-api-2.1.3.jar}:${jaxb-impl-2.1.3.jar}:${jaxb-xjc-2.1.3.jar}" />
<pathelement path="${jaxb2-commons-commons-lang-plugin.jar}"/>
<pathelement path="${jaxb2-commons-value-constructor.jar}"/>
<pathelement path="${jaxb2-commons-fluent-api.jar}"/>
<pathelement path="${jaxb2-commons-default-value-plugin.jar}"/>
<pathelement path="${jaxb2-commons-collection-setter-injector.jar}"/>
<pathelement path="${component.classpath}" />
</classpath>
</taskdef>

<!-- This task will autogenerate the code from the WSDL specification -->
<taskdef name="wsgen" classname="org.codehaus.xfire.gen.WsGenTask" >
<classpath>
<pathelement path="${component.classpath}" />
</classpath>
</taskdef>

<!-- Auto generate classes based on the XSD definitions using JAXB bindings -->
<target name="xjc_gen">
<mkdir dir="${component.autogen_src}"/>
<delete>
<fileset dir="${component.autogen_src}"
excludes="**/service/**/*.java"/>
</delete>
<xjc destdir="${component.autogen_src}" target="2.0" extension="true">
<arg value="-Xcommons-lang"/>
<arg value="-Xvalue-constructor"/>
<arg value="-Xfluent-api"/>
<arg value="-Xcollection-setter-injector"/>
<arg value="-Xdefault-value"/>
<schema dir="${component.home}/src/conf/wsdl" includes="*.xsd"/>
<binding file="${component.home}/src/conf/wsdl/simple.xjb"/>
</xjc>
</target>

<!-- Auto generate interfaces and classes based on the WSDL definitions using JAXB bindings -->
<target name="wsdl_gen">
<mkdir dir="${component.autogen_src}"/>
<wsgen outputDirectory="${component.autogen_src}"
wsdl="${component.home}/src/conf/wsdl/service-foo.wsdl"
package="com.blogspot.ozgwei.service.foo"
overwrite="true"
binding="jaxb"
externalBindings="${component.home}/src/conf/wsdl/simple.xjb"
/>
<wsgen outputDirectory="${component.autogen_src}"
wsdl="${component.home}/src/conf/wsdl/service-bar.wsdl"
package="com.blogspot.ozgwei.service.bar"
overwrite="true"
binding="jaxb"
externalBindings="${component.home}/src/conf/wsdl/simple.xjb"
/>
</target>

<!-- Build all user, autogenerated and test code -->
<target name="compile" depends="wsdl_gen, xjc_gen">
...
</target>


The next is the content of the simple.xjb file for JAXB Binding, which use java.util.Calendar:

<!--
This enables the simple binding mode in JAXB.
See http://weblogs.java.net/blog/kohsuke/archive/2006/03/simple_and_bett.html
-->
<jaxb:bindings jaxb:version="2.0" jaxb:extensionBindingPrefixes="xjc"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jaxb:globalBindings>
<xjc:simple/>
<jaxb:javaType name="java.util.Calendar" xmlType="xs:date"
parseMethod="javax.xml.bind.DatatypeConverter.parseDate"
printMethod="javax.xml.bind.DatatypeConverter.printDate"/>
<jaxb:javaType name="java.util.Calendar" xmlType="xs:time"
parseMethod="javax.xml.bind.DatatypeConverter.parseTime"
printMethod="javax.xml.bind.DatatypeConverter.printTime"/>
<jaxb:javaType name="java.util.Calendar" xmlType="xs:dateTime"
parseMethod="javax.xml.bind.DatatypeConverter.parseDateTime"
printMethod="javax.xml.bind.DatatypeConverter.printDateTime"/>
</jaxb:globalBindings>
</jaxb:bindings>


If you prefer to use java.util.Date instead of java.util.Calendar, define the following class and change the binding file accordingly:

package com.blogspot.ozgwei.jaxb

import java.util.Date;
import javax.xml.bind.DatatypeConverter;

public class DateConverter {

public static Date parseDate(String s) {
return DatatypeConverter.parseDate(s).getTime();
}

public static Date parseTime(String s) {
return DatatypeConverter.parseTime(s).getTime();
}

public static Date parseDateTime(String s) {
return DatatypeConverter.parseDateTime(s).getTime();
}

public static String printDate(Date dt) {
Calendar cal = new GregorianCalendar();
cal.setTime(dt);
return DatatypeConverter.printDate(cal);
}

public static String printTime(Date dt) {
Calendar cal = new GregorianCalendar();
cal.setTime(dt);
return DatatypeConverter.printTime(cal);
}

public static String printDateTime(Date dt) {
Calendar cal = new GregorianCalendar();
cal.setTime(dt);
return DatatypeConverter.printDateTime(cal);
}

}


The simple.xjb will be changed to:

<jaxb:bindings jaxb:version="2.0" jaxb:extensionBindingPrefixes="xjc"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jaxb:globalBindings>
<xjc:simple/>
<jaxb:javaType name="java.util.Date" xmlType="xs:date"
parseMethod="com.blogspot.ozgwei.jaxb.DateConverter.parseDate"
printMethod="com.blogspot.ozgwei.jaxb.DateConverter.printDate"/>
<jaxb:javaType name="java.util.Date" xmlType="xs:time"
parseMethod="com.blogspot.ozgwei.jaxb.DateConverter.parseTime"
printMethod="com.blogspot.ozgwei.jaxb.DateConverter.printTime"/>
<jaxb:javaType name="java.util.Date" xmlType="xs:dateTime"
parseMethod="com.blogspot.ozgwei.jaxb.DateConverter.parseDateTime"
printMethod="com.blogspot.ozgwei.jaxb.DateConverter.printDateTime"/>
</jaxb:globalBindings>
</jaxb:bindings>

Tuesday, August 21, 2007

Defining service/component interfaces in WSDLs

We have just completed an iteration of the project we have been working on for the past few months. Now it's a good time to summarise the experiences we have gained so far.

Probably the most significant one is defining all service/component interfaces in WSDLs.

The project started with the interfaces of a few services being defined in WSDLs because they are invoked by the web tier as web services call. Since the JAXB-generated Java classes of some complex types defined in the XML schema are reused in some other service interfaces that are not originally intended to be invoked via web services, we finally decided to define all service interfaces in WSDLs, regardless whether they are intended to be invoked as web services or not. And this brought us unexpected benefits and productivity.

So what are the benefits of defining all service interfaces in WSDLs?

First of all, it takes away most of the tedious work of implementing Data Transfer Objects (DTOs), resulting in higher productivity. If you wonder why DTOs are still in use when domain model objects persisted by Hibernate and JPA can be passed back to service clients directly, please read my previoug blog entry: DTOs are a necessary devil in building SOA enterprise applications.

So, how does defining service interfaces in WSDLs take away the boring implementation of DTOs? In a WSDL file, each operation has input messages, output messages and/or fault messages, which in turn are defined as elements in an external or embedded XML schema. And each element is declared in an XML type. The XJC compiler from JAXB can be used to generate corresponding Java classes of any complex types and some restricted simple types. These classes are data holders with absolutely no behaviours; in other words, they are DTOs. Code generation of DTOs has other benefits: no behaviours can be added to the DTOs without subclassing and defining new operations; and these DTOs won't accidentally reference any domain model objects, which is always a concern for hand-coded DTOs.

XML schema allows very rich type definitions, such as abstract types and type inheritance, which has corresponding concepts in object-oriented languages, such as Java, making it a perfect choice to generate Java classes from XML data types.

Not only are no-argument constructors and all public getter and setter methods generated for complex types, but also other useful methods, such as valued constructors, builder methods, hashCode, equals and toString methods can be implemented using XJC extensions. These are to be blogged in a follow-up post.

Moreover, defining service/component interfaces in WSDLs can partially enforce the "contract" using schema validation, promoting the best practice of "Design by Contract" (DBC).

Java, by itself, does not provide native support to DBC. Any acceptable input values, return values and exceptions are only documented using javadoc in the interfaces. The implementation classes have to do all the hard work to validate input values, such as making sure a mandatory parameter is not null, an amount is greater than zero and less than a preset limit, etc.

Meanwhile, XML schema provides a rich basic data types, such as positive integers. It can also specify whether an element is mandatory or not using the "minOccur" attribute. Furthermore, it allows you to add restrictions to simple types, such as the maximum length of a string and regular expression patterns that must be matched by a string. Thus, XML schema validation can catch many simple field validation errors. More complex validations, such as cross-field validations and business rule validations cannot be done by schema validation. However, they can still be documented using annotations, which are generated as Java comments in the generated Java classes.

Another benefit of defining service/component interfaces in WSDLs is that it promotes the best practice of "contract-first" web service design. Because the service interface is defined in a WSDL file, the service is web service ready, even if it is not intended to be used as a web service at this stage. The opposite of "contract-first" is "code-first". When adopting a "code-first" practice, the service interfaces are defined in Java, potentially without using DTOs. When the service needs to be accessed via web services or remotely, it is not as easy as just exposing the service as a web service by, say, wiring up the Spring application context. A proper service interface using DTOs has to be defined and implemented by delegate calls to the original interface and doing all the transformation between DTOs and domain models. Even if DTOs are used in the original Java interface, exposing the service as a web service is not as simple as adding the JSR-181 annotations to the interface and all DTOs: some common Java types do not have a counterpart in XML, such as java.util.Map. Moreover, the methods defined in your original DTOs may not be suitable for JAXB use. You may not have defined a no-argument constructor; you may not have defined a setter method for each property... So, why go the hard way when defining the interfaces in WSDLs can save you the tedious work of implementing DTOs and, at the same time, provide an elegant way to expose it as a web service when the time calls?

Saturday, August 18, 2007

DTOs are a necessary devil in building SOA enterprise applications

Bringing up the topic of Data Transfer Objects (DTOs), many people's first thought would probably be that it was a reminiscence of the old Enterprise Java Bean (EJB) 2.0.

Hibernate, JDO and JPA have made it possible to eliminate DTOs from web applications. However, DTOs are a necessary devil when building an enterprise application, especially in a Service-Oriented Architecture (SOA).

For each service or component, the underneath domain model that provides the service should be encapsulated and not leaked beyond the boundary of the service's interfaces.

It is often said that the interfaces are the contracts between the client and the provider of the services. However, many new Java developers think that only the interface classes and their method names are the contract without realising that any objects passed in and out of these operations are also part of the contract, such as method parameters, return values and thrown exceptions. And the contractual binding is transitive by reachability, that is, all classes directly or indirectly referenced by these parameters, return values and exceptions are all part of the contract. Therefore, if domain models are passed in and out of any operation defined in the service interfaces, they are leaked, making service clients susceptible to any changes in the domain models, which are the implementation details that are supposed to be encapsulated.

For a web application, this is probably not a big deal, as the presentation tier is typically closely coupled to the service and persistence tiers. However, for any enterprise applications in a Service-Oriented Architecture, the change of interfaces can have a ripple effect.

In order to achieve the encapsulation, DTOs are used as the parameters, returned values and exceptions in operations defined in the interfaces to isolate domain models from the outside world. For this reason, it is not hard to imagine that DTOs are ubiquitous in a SOA world.

Thursday, August 9, 2007

EasyMock Class Extension 2.2 Gotcha

EasyMock mocks interfaces, and the Class Extension mocks classes.

When using the class extension, the EasyMock from the org.easymock.classextension package should be used instead of the same-named class from the original org.easymock package.

When working with more than one mocks with Java 5, we can invoke the replay and verify methods using varargs, such as:
import static org.easymock.classextension.EasyMock.*;
...
replay(mockCustomerRepository, mockCustomer);
...
verify(mockCustomerRepository, mockCustomer);
However, if one of the mocks is mocking a class instead of an interface, I got an IllegalArgumentException: not a proxy instance.

Looking into the stack trace, I can see the EasyMock.replay/verify from the original org.easymock package is used instead of the one from org.easymock.classextension package, as stated in the import statement.

What happened is: org.easymock.classextension.EasyMock extends the org.easymock.EasyMock without providing a vararg version of replay(Object...) and verify(Object...) method. Thus, when the vararg versions are invoked, the control is passed to the vararg version of its super class, which only mocks interfaces using standard Java Proxy.

To get around this, you invoke the single parameter version, such as:
import static org.easymock.classextension.EasyMock.*;
...
replay(mockCustomerRepository);
replay(mockCustomer);
...
verify(mockCustomerRepository);
verify(mockCustomer);
Of course, this gotcha only exists in EasyMock class extension 2.2. The latest 2.2.2 version provides vararg version for these two methods. So a better solution is to upgrade to this latest version.

Tuesday, July 31, 2007

EasyMock2 quirk...

When using EasyMock 2 for testing, typically we need to set up expectations before replay, like this:
expect(mockEmployeeRepository
.findByFirstNameAndLastName("John", "Doe"))
.andReturn(employees);
Sometimes, you don't know exactly what parameter will be used for the expected call, you can instead specify the class of the parameter, such as:
expect(mockEmployeeRepository
.findBySpecification(isA(EmployeeSearchSpecification.class))
.andReturn(employees);
What if you know the exact value of some but not all parameters? I tried the following:
expect(mockEmployeeRepository
.findByDepartmentAndSpecification("HR",
isA(EmployeeSearchSpecification.class))
.andReturn(emplooyees);
Unfortunately, running this test will get the following exception thrown by EasyMock:
java.lang.IllegalStateException: 2 matchers expected, 1 recorded.
The correct way is to wrap the known parameter with an "eq" matcher:
expect(mockEmployeeRepository
.findByDepartmentAndSpecification(eq("HR"),
isA(EmployeeSearchSpecification.class))
.andReturn(employees);
This is a small quirk when using EasyMock 2.2...

Handling referential integrity when doing persistence testing using DbUnit

DbUnit is a great tool when testing database persistence codes.

There are many ways to using DbUnit. Anyhow, my preferred way is to delete all records from the database tables and re-populate with test data before each test. For unit testing, I test against a memory database, such as Hypersonic; for integration testing, I test against a database that mirrors the one in production.

However, this approach sometimes will get you into the trouble of referential integrity violation.

For example, I had some integration tests against the PRODUCT table, and later I developd some integration tests against the ORDER table, which has a foreign key dependency on the PRODUCT table.

After checking in the latest changes, the continuous integration test failed because of data integrity violation. The cause was that the PRODUCT integration tests saved some records in both PRODUCT and ORDER table, with some orders referencing some products. When DbUnit tried to delete all records from the PRODUCT table, the database detected the violation.

How to solve this? It's pretty easy, just add an empty ORDER record to the test data XML file that is used to populate the database. Following is a sample of a FlatXmlDataSet file:

<?xml version='1.0' encoding='UTF-8'?>
<dataset>
<product id="1" desc="abc" price="1.23"/>
<order/>
</dataset>
The trick is that in a FlatXmlDataSet file, the order of the tables defined must follow the dependency, that is, a later defined table can have a dependency on an earlier defined table. When DbUnit deletes records, it will delete records from the last defined table first.

Sunday, July 29, 2007

Springify a "Singleton"-infested application

The singleton pattern has been avidly avoided by most developers since the introduction of Spring, which solved the problem in an elegant way.

However, there have been many applications that were developed before and were infested with the "evil" singleton pattern. Quite often, these singletons are not really singletons; the singleton pattern was just misapplied to a problem that may be more suitable to use Registry to solve.

Every now and then, developers are asked to add Spring to such applications with minimal code changes and refactoring because these applications typically do not have any automated unit tests or do not have a good enough test coverage.

Adding Spring to such applications is rather simple if there is no dependency between the existing codes and the Spring-managed beans.

If Spring-managed beans have a dependency on a "singleton" that is not managed by Spring. We can define the "singleton" as a Spring-managed bean using a "factory-method", such as "getInstance()", to retrieve the "singleton" instance and inject it into other beans.

Things get more complex when you want to use Spring to configure these "singletons".

For example, one of the application that I need to springify used a "singleton" to look up data source from JNDI. In order to add tests that can be run out of container, we need to inject a Spring-configured data source, whether it is registered with JNDI or not, to that "singleton" instance, instead of letting the "singleton" to look up JNDI.

What we did was that we added a new static factory method "createInstance(DataSource)" accepting a pre-configured data source and returning the singleton instance. Then we configure Spring to invoke this new factory method to create a bean, which is stored in the original static variable and returned to caller of the static "getInstance()" method.

I have read on the internet that some call this a "Singleton with a back door" pattern. To me, it is pretty clear that the singleton pattern is misused here. What the original developer really needed was a "Registry" pattern that allows other objects to "find common objects and services" using "a well-known object". Spring creates and configures the common object or service, which is registered so that other objects in the same application can locate it.

In fact, Spring itself uses "Registry" pattern in many places. Some of the significant places include transaction management and JDBC connection management. Spring uses a thread-local scoped registry to hold JDBC connection so that all JDBC operations within the same transaction use the same JDBC connection...

One thing to note when using Spring to configure such "singletons" is that there are typically many implicit dependencies between these "singletons". If Spring instantiates these "singletons" in a wrong order, the application cannot run properly, usually with failure in constructing application context. The solution to this is to use the "depends-on" attribute in bean definition to explicitly specify the dependencies between these "singletons".