{"id":231,"date":"2005-10-31T21:54:10","date_gmt":"2005-10-31T20:54:10","guid":{"rendered":"http:\/\/thekua.com\/rant\/?p=231"},"modified":"2012-03-10T15:00:59","modified_gmt":"2012-03-10T15:00:59","slug":"evolving-an-agile-architecture","status":"publish","type":"post","link":"https:\/\/thekua.com\/rant\/2005\/10\/evolving-an-agile-architecture\/","title":{"rendered":"Evolving An Agile Architecture"},"content":{"rendered":"<p>Last week I heard that the project I just rolled off was a huge success, both for our UK office (in terms of significant wins and growth), as well as the development team (for the freedom of both process and technology choices). When I started work on the project, I was working with Joe Walnes, and one of the project&#8217;s foundation principles was about making technology and process decisions that helped to reduce the build time (and therefore delivery time). I have been on, and heard about, many other projects that end up with several staged builds, leading to the average developer build of around an hour. When I left, we had a sub-minute build (including end to end testing) and a deployable application with a dependency on only Java 5 and Ant (but okay, it&#8217;s not a huge system yet). <\/p>\n<p>I&#8217;m posting this entry so that somewhere I hope that someone learns something which they apply in optimising their own build (or even sharing their strategies) to make their projects even more agile. What follows is a list of some of the more significant decisions we made, and more importantly, why we made them. <!--more--><\/p>\n<p><strong>Persistence<\/strong><br \/>\nI think that for the most part, the only decent Object Relational Mapping (ORM) tool in Java today is <a href=\"http:\/\/www.hibernate.org\">Hibernate<\/a>. For Hibernate versions 3.0 and earlier, you generally wrote XML for configuration which we started with. We thought about using <a href=\"http:\/\/xdoclet.sourceforge.net\/\">XDoclet<\/a>, and although it keeps it close to the code, we thought it would be faster to write our own files. After about two days of writing XML for our domain objects, we decided to replace the XML configuration files with Hibernate Annotations (3.1 beta) which not only kept all the code close together, but probably improved Hibernate&#8217;s load time since there was no XML parsing. Moving to Annotations, or even just writing XML by hand (with enough smaller-grained functional tests) should be enough to shave several minutes off any build with a decently sized domain model.<\/p>\n<p><strong>Testing<\/strong><br \/>\nLessons learned from colleagues indicate that you end up with a staged build after a while, and my personal experience shows that it is much harder to change things with confidence if you only have unit tests, or made slower if you only have integration tests. Starting off, we decided to have three staged builds, one with just unit tests, one with just functional (unit integration) tests and then finally the acceptance (end-to-end) tests.<\/p>\n<p>Our definition for unit tests included anything that was pretty much independent of external resources and could be run on a scale of hundreds a second. The bulk of our functional tests included hibernate integration tests (ensuring that our objects would save to a DB and that retrieval queries would translate into the appropriate SQL). Our acceptance tests were basically web tests that were the driving force for all the code. <\/p>\n<p>A common pattern I have seen for hibernate functional tests is one in which all the objects are saved in a test, and the objects are deleted on <code>tearDown()<\/code> or <code>setUp()<\/code> to restore the DB to a clean state. The same thing can be achieved if your test fixture starts a transaction on <code>setUp()<\/code>, and on <code>tearDown()<\/code> rolls it back. To ensure that your tests generate SQL (what you&#8217;re trying to test) on persistence make sure they call <code>session.flush()<\/code>, or if querying, first empty the domain level caches with a <code>session.clear()<\/code> call. This rollback transaction pattern also has great potential for running functional tests on concurrent build machines without running into the issues you would if sharing a common database.<\/p>\n<p><strong>Database<\/strong><br \/>\nFor ease of setup, we originally started off with a local <a href=\"http:\/\/www.mysql.com\/\">MySQL<\/a> database (the Hibernate Generate Schema Tool helped us set up our tests databases). Soon after this, we moved to <a href=\"http:\/\/hsqldb.org\/\">HSQLDB<\/a> to improve the speed of functional tests even more (with an in memory DB), and then a file based HSQLDB for acceptance tests (since scenario data had to be loaded). There are a few caveats in applying this technique as there can be several differences (case sensitivity, default return order, date format, etc) between a proper production database and one such as HSQLDB, but is still useful nevertheless.<\/p>\n<p><strong>Templating Language<\/strong><br \/>\nWe used WebWork for our web application framework and were originally using the WebWork tags in JSPs to start with. We found that this choice was not ideal for agile acceptance testing because of the precompilation stage each JSP had to go through (either programmatically or on first hit). We had the choice out of <a href=\"http:\/\/jakarta.apache.org\/velocity\/\">Velocity<\/a> or <a href=\"http:\/\/freemarker.sourceforge.net\/\">Freemarker<\/a>, deciding to go with Freemarker (with no other real reason other than we hadn&#8217;t used it before), and our acceptance tests (as well as individual edit-browse cycles) improved. <\/p>\n<p><strong>Source Control<\/strong><br \/>\nWe used <a href=\"http:\/\/subversion.tigris.org\/\">Subversion<\/a> over <a href=\"http:\/\/www.nongnu.org\/cvs\/\">CVS<\/a>. We didn&#8217;t pick this explicitly because of its speed, but I do think that it has helped to improve local developer builds (as you don&#8217;t need to connect to a remote server for Subversion adds or rollbacks).<\/p>\n<p><strong>Future Optimisation Points<\/strong><br \/>\nThings we were talking about changing before I left included:<\/p>\n<ul>\n<li><strong>Build Tool<\/strong> &#8211; Ant is good, but some of the ant tasks (and Java) can be slow. We were considering using alternatives (<a href=\"http:\/\/rake.rubyforge.org\/\">Rake<\/a> anyone?) instead.<\/li>\n<li><strong>Schema Generation<\/strong> &#8211; As your domain model continues to grow, running Hibernate&#8217;s Schema Generator probably adds less value. When configured properly HSQLDB dumps all of its contents into a simple SQL file, which we were thinking of using (and updating) as an alternative.\n<\/li>\n<li><strong>Acceptance Test Scenario Loading<\/strong> &#8211; We use HLoader (a tool for loading Hibernate-bound objects via an XML configuration) to load up acceptance data. We use Hloader because it is less fiddly than dealing with multiple CSV files but gives us the flexibility of more complex structures without writing lots of java code. Like above, we were thinking of using the HSQLDB dumps to replace its contents.\n<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Last week I heard that the project I just rolled off was a huge success, both for our UK office (in terms of significant wins and growth), as well as the development team (for the freedom of both process and technology choices). When I started work on the project, I was working with Joe Walnes, [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11,3],"tags":[67,39],"class_list":["post-231","post","type-post","status-publish","format-standard","hentry","category-agile","category-technical","tag-agile","tag-work-related"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Evolving An Agile Architecture - thekua.com@rest<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/thekua.com\/rant\/2005\/10\/evolving-an-agile-architecture\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Evolving An Agile Architecture - thekua.com@rest\" \/>\n<meta property=\"og:description\" content=\"Last week I heard that the project I just rolled off was a huge success, both for our UK office (in terms of significant wins and growth), as well as the development team (for the freedom of both process and technology choices). When I started work on the project, I was working with Joe Walnes, [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/thekua.com\/rant\/2005\/10\/evolving-an-agile-architecture\/\" \/>\n<meta property=\"og:site_name\" content=\"thekua.com@rest\" \/>\n<meta property=\"article:published_time\" content=\"2005-10-31T20:54:10+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2012-03-10T15:00:59+00:00\" \/>\n<meta name=\"author\" content=\"Patrick\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Patrick\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/thekua.com\\\/rant\\\/2005\\\/10\\\/evolving-an-agile-architecture\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/thekua.com\\\/rant\\\/2005\\\/10\\\/evolving-an-agile-architecture\\\/\"},\"author\":{\"name\":\"Patrick\",\"@id\":\"https:\\\/\\\/thekua.com\\\/rant\\\/#\\\/schema\\\/person\\\/6de103b28f96be3f1f4dc25db357c6ae\"},\"headline\":\"Evolving An Agile Architecture\",\"datePublished\":\"2005-10-31T20:54:10+00:00\",\"dateModified\":\"2012-03-10T15:00:59+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/thekua.com\\\/rant\\\/2005\\\/10\\\/evolving-an-agile-architecture\\\/\"},\"wordCount\":983,\"commentCount\":4,\"publisher\":{\"@id\":\"https:\\\/\\\/thekua.com\\\/rant\\\/#\\\/schema\\\/person\\\/6de103b28f96be3f1f4dc25db357c6ae\"},\"keywords\":[\"Agile\",\"Work-Related\"],\"articleSection\":[\"Agile\",\"Work Related\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/thekua.com\\\/rant\\\/2005\\\/10\\\/evolving-an-agile-architecture\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/thekua.com\\\/rant\\\/2005\\\/10\\\/evolving-an-agile-architecture\\\/\",\"url\":\"https:\\\/\\\/thekua.com\\\/rant\\\/2005\\\/10\\\/evolving-an-agile-architecture\\\/\",\"name\":\"Evolving An Agile Architecture - thekua.com@rest\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/thekua.com\\\/rant\\\/#website\"},\"datePublished\":\"2005-10-31T20:54:10+00:00\",\"dateModified\":\"2012-03-10T15:00:59+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/thekua.com\\\/rant\\\/2005\\\/10\\\/evolving-an-agile-architecture\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/thekua.com\\\/rant\\\/2005\\\/10\\\/evolving-an-agile-architecture\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/thekua.com\\\/rant\\\/2005\\\/10\\\/evolving-an-agile-architecture\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/thekua.com\\\/rant\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Evolving An Agile Architecture\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/thekua.com\\\/rant\\\/#website\",\"url\":\"https:\\\/\\\/thekua.com\\\/rant\\\/\",\"name\":\"thekua.com@rest\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/thekua.com\\\/rant\\\/#\\\/schema\\\/person\\\/6de103b28f96be3f1f4dc25db357c6ae\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/thekua.com\\\/rant\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\\\/\\\/thekua.com\\\/rant\\\/#\\\/schema\\\/person\\\/6de103b28f96be3f1f4dc25db357c6ae\",\"name\":\"Patrick\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/thekua.com\\\/rant\\\/wp-content\\\/uploads\\\/2025\\\/12\\\/pat-kua-head.png\",\"url\":\"https:\\\/\\\/thekua.com\\\/rant\\\/wp-content\\\/uploads\\\/2025\\\/12\\\/pat-kua-head.png\",\"contentUrl\":\"https:\\\/\\\/thekua.com\\\/rant\\\/wp-content\\\/uploads\\\/2025\\\/12\\\/pat-kua-head.png\",\"width\":400,\"height\":400,\"caption\":\"Patrick\"},\"logo\":{\"@id\":\"https:\\\/\\\/thekua.com\\\/rant\\\/wp-content\\\/uploads\\\/2025\\\/12\\\/pat-kua-head.png\"},\"sameAs\":[\"http:\\\/\\\/www.thekua.com\"],\"url\":\"https:\\\/\\\/thekua.com\\\/rant\\\/author\\\/patrick\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Evolving An Agile Architecture - thekua.com@rest","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/thekua.com\/rant\/2005\/10\/evolving-an-agile-architecture\/","og_locale":"en_US","og_type":"article","og_title":"Evolving An Agile Architecture - thekua.com@rest","og_description":"Last week I heard that the project I just rolled off was a huge success, both for our UK office (in terms of significant wins and growth), as well as the development team (for the freedom of both process and technology choices). When I started work on the project, I was working with Joe Walnes, [&hellip;]","og_url":"https:\/\/thekua.com\/rant\/2005\/10\/evolving-an-agile-architecture\/","og_site_name":"thekua.com@rest","article_published_time":"2005-10-31T20:54:10+00:00","article_modified_time":"2012-03-10T15:00:59+00:00","author":"Patrick","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Patrick","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/thekua.com\/rant\/2005\/10\/evolving-an-agile-architecture\/#article","isPartOf":{"@id":"https:\/\/thekua.com\/rant\/2005\/10\/evolving-an-agile-architecture\/"},"author":{"name":"Patrick","@id":"https:\/\/thekua.com\/rant\/#\/schema\/person\/6de103b28f96be3f1f4dc25db357c6ae"},"headline":"Evolving An Agile Architecture","datePublished":"2005-10-31T20:54:10+00:00","dateModified":"2012-03-10T15:00:59+00:00","mainEntityOfPage":{"@id":"https:\/\/thekua.com\/rant\/2005\/10\/evolving-an-agile-architecture\/"},"wordCount":983,"commentCount":4,"publisher":{"@id":"https:\/\/thekua.com\/rant\/#\/schema\/person\/6de103b28f96be3f1f4dc25db357c6ae"},"keywords":["Agile","Work-Related"],"articleSection":["Agile","Work Related"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/thekua.com\/rant\/2005\/10\/evolving-an-agile-architecture\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/thekua.com\/rant\/2005\/10\/evolving-an-agile-architecture\/","url":"https:\/\/thekua.com\/rant\/2005\/10\/evolving-an-agile-architecture\/","name":"Evolving An Agile Architecture - thekua.com@rest","isPartOf":{"@id":"https:\/\/thekua.com\/rant\/#website"},"datePublished":"2005-10-31T20:54:10+00:00","dateModified":"2012-03-10T15:00:59+00:00","breadcrumb":{"@id":"https:\/\/thekua.com\/rant\/2005\/10\/evolving-an-agile-architecture\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/thekua.com\/rant\/2005\/10\/evolving-an-agile-architecture\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/thekua.com\/rant\/2005\/10\/evolving-an-agile-architecture\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/thekua.com\/rant\/"},{"@type":"ListItem","position":2,"name":"Evolving An Agile Architecture"}]},{"@type":"WebSite","@id":"https:\/\/thekua.com\/rant\/#website","url":"https:\/\/thekua.com\/rant\/","name":"thekua.com@rest","description":"","publisher":{"@id":"https:\/\/thekua.com\/rant\/#\/schema\/person\/6de103b28f96be3f1f4dc25db357c6ae"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/thekua.com\/rant\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/thekua.com\/rant\/#\/schema\/person\/6de103b28f96be3f1f4dc25db357c6ae","name":"Patrick","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/thekua.com\/rant\/wp-content\/uploads\/2025\/12\/pat-kua-head.png","url":"https:\/\/thekua.com\/rant\/wp-content\/uploads\/2025\/12\/pat-kua-head.png","contentUrl":"https:\/\/thekua.com\/rant\/wp-content\/uploads\/2025\/12\/pat-kua-head.png","width":400,"height":400,"caption":"Patrick"},"logo":{"@id":"https:\/\/thekua.com\/rant\/wp-content\/uploads\/2025\/12\/pat-kua-head.png"},"sameAs":["http:\/\/www.thekua.com"],"url":"https:\/\/thekua.com\/rant\/author\/patrick\/"}]}},"_links":{"self":[{"href":"https:\/\/thekua.com\/rant\/wp-json\/wp\/v2\/posts\/231","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/thekua.com\/rant\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/thekua.com\/rant\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/thekua.com\/rant\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/thekua.com\/rant\/wp-json\/wp\/v2\/comments?post=231"}],"version-history":[{"count":1,"href":"https:\/\/thekua.com\/rant\/wp-json\/wp\/v2\/posts\/231\/revisions"}],"predecessor-version":[{"id":2810,"href":"https:\/\/thekua.com\/rant\/wp-json\/wp\/v2\/posts\/231\/revisions\/2810"}],"wp:attachment":[{"href":"https:\/\/thekua.com\/rant\/wp-json\/wp\/v2\/media?parent=231"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/thekua.com\/rant\/wp-json\/wp\/v2\/categories?post=231"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/thekua.com\/rant\/wp-json\/wp\/v2\/tags?post=231"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}