In the first part of this series of blog entries, we discussed Spring Framework and Hibernate upgrades, and an XDoclet migration, all of which were performed for a recent client to decrease time-to-market, increase maintainability, maximize system lifetime, and maximize framework lifetime. In this second part, we start taking a more detailed look at the implementation details behind this architecture effort.
The following UML diagram is a simplified depiction of the relationships between the Java application built for the client and the open source frameworks under discussion. The Java application directly depended on all three of these frameworks, but additional interrelationships exist between Spring Framework and Hibernate, and Hibernate and XDoclet. These additional dependencies do not necessarily indicate direct JAR dependencies. For example, XDoclet is used to scan the metadata included in Java classes created for use during the Hibernate object/relational mapping process. The XML which is then generated from this scan is used by Hibernate. Similarly, Spring Framework provides the ability to conveniently wire-in Hibernate integration.
In addition to these three main frameworks, other frameworks are being utilized by the Java application, including dozens of lesser supporting frameworks such as those associated with logging facilities. For the sake of this illustration, none of these additional frameworks will be depicted in the diagrams provided here, but instead included where necessary within the discussion. It is also necessary to mention that the original system was built in a Java 1.4 environment, and so annotations were not yet made available for usage within the source code.
Annotations available for JAX-WS v2.1.2 usage require Java 5, but XDoclet v1.2.3 unfortunately cannot handle annotations, so the XML generation cannot occur, even though the environment has since been upgraded to Java 5. An upgrade to XDoclet v2.0.6, offered by Codehaus, provides a resolution to this problem, but after the associated Ant task is added to the build file and executed against this new version of XDoclet, it is readily apparent that it is not 100% backwards-compatible with earlier versions, mainly due to the different metadata that is expected in some circumstances. The following are some examples of some of the more common incompatibilities encountered:
//@hibernate.collection-one-to-many //XDoclet v1.2.3
@hibernate.one-to-many //XDoclet v2.0.6
//@hibernate.collection-key //XDoclet v1.2.3
@hibernate.key //XDoclet v2.0.6
//@hibernate.collection-composite-element //XDoclet v1.2.3
@hibernate.composite-element //XDoclet v2.0.6
//@hibernate.collection-index //XDoclet v1.2.3
@hibernate.index //XDoclet v2.0.6
//@hibernate.collection-element //XDoclet v1.2.3
@hibernate.element //XDoclet v2.0.6
While it is open to debate whether dropping the word collection from these metadata tags clarifies purpose, such a simple change still breaks backwards-compatibility, necessitating changes to the source code so the new version of XDoclet can parse meaning correctly. Of course, if needed changes to the metadata tags were solely limited to dropping the word collection from each occurrence, the result would be just a minor inconvenience. It turns out, however, that there exist other changes in the Codehaus version of XDoclet. For example:
column = “ACCOUNT_ID”
//lazy = “true” //XDoclet v1.2.3; value of “true” not permitted; must be “false”, “proxy”, or “no-proxy”
lazy = “false“ //XDoclet v2.0.6; temporary adjustment
cascade = “none”
outer-join = “false”
class = “…“
Resolutions to incompatibilites such as this do not simply involve search-and-replace efforts across the source code base. But these are minor inconveniences. After such issues are resolved, and following a few tweaks to the Ant build script, the resultant XML output needed for Hibernate is generated. (Well, after class path discrepancies were fixed in the original metadata, since XDoclet v2.0.6 was found to be more sensitive to class path discrepancies than XDoclet v1.2.3.) It turns out that in addition to metadata tags such as @hibernate.id no longer permitting class as a parameter (because in some cases XDoclet v2.0.6 is more intelligent than its previous incarnation), XDoclet v2.0.6 caught errors in the original metadata tags written for usage with XDoclet v1.2.3 that were associated with classpath, resulting in the need for additional modifications to the source code base. In my opinion, this is one of the improvements provided by the Codehaus version of XDoclet.
Now that Hibernate v3.0.5 can utilize our metadata tags again, our need to use the latest release of Apache CXF is revisited in Part III of this discussion.