<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:yt="http://gdata.youtube.com/schemas/2007" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
   <channel>
      <title>CITCON Blog Aggregator</title>
      <description>Aggregates the blogs from various CITCON participants, and filters out the dupes amongst them. Filters out posts not related to CI &amp; Testing.</description>
      <link>http://pipes.yahoo.com/pipes/pipe.info?_id=b787fd1ec5db6b74feb6129e9d55dfe8</link>
      <pubDate>Fri, 10 Jul 2009 00:07:29 -0700</pubDate>
      <generator>http://pipes.yahoo.com/pipes/</generator>
      <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/CitconBlogs" type="application/rss+xml" /><item>
         <title>Sonar at the Haus</title>
         <link>http://feedproxy.google.com/~r/CitconBlogs/~3/aVmZeov3XWw/</link>
         <description>We mentioned it already in a previous post : Codehaus aka the Haus is probably the best forge available for business friendly open source projects; they have a very pragmatic approach to software development which leads them to choose and provide the best collaborative tools available on the market.
Since a couple of weeks, to make [...]</description>
         <author>Olivier Gaudin</author>
         <guid isPermaLink="false">http://sonar.codehaus.org/?p=1392</guid>
         <pubDate>Thu, 09 Jul 2009 01:06:24 -0700</pubDate>
         <content:encoded><![CDATA[<p>We mentioned it already in a previous post : <a rel="nofollow" target="_blank" href="http://www.codehaus.org">Codehaus</a> aka the Haus is probably the best forge available for business friendly open source projects; they have a very pragmatic approach to software development which leads them to choose and provide the best collaborative tools available on the market.<br/><br />
Since a couple of weeks, to make the service even better, the Haus has decided to offer Sonar as a service. This was <a rel="nofollow" target="_blank" href="http://support.codehaus.org/2009/06/21/sonar-at-the-haus/">announced on the Haus blog</a> (inaugurated at that occasion !). The principle is very simple : projects must simply use Bambo hosted at Codehaus and create a job that runs mvn sonar:sonar.<br/><br />
After <a rel="nofollow" target="_blank" href="http://nemo.sonarsource.org">Nemo</a>, the public instance of Sonar that can be used as a SaaS by open source projects, this is an important step toward mass adoption of code quality management tools.</p>
<img src="http://feeds.feedburner.com/~r/Sonar/~4/nX9vO3dd-vI" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/CitconBlogs/~4/aVmZeov3XWw" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://feedproxy.google.com/~r/Sonar/~3/nX9vO3dd-vI/</feedburner:origLink></item>
      <item>
         <title>Testable software is good software – video is online</title>
         <link>http://feedproxy.google.com/~r/CitconBlogs/~3/iDuncpWgX7Y/</link>
         <description>The video from last month&amp;#8217;s agile testing evening at skills matter in London is now online. Dave Evans and Mike Scott from SQS talked on the subject of &amp;#8220;Testable software is good software&amp;#8221;. They discuss the effect architectural decisions have on application testability, assert that a testable architecture is inherently a better architecture, and demonstrate [...]</description>
         <author>gojko</author>
         <guid isPermaLink="false">http://gojko.net/2009/07/05/testable-software-is-good-software-video-is-online/</guid>
         <pubDate>Sun, 05 Jul 2009 15:55:58 -0700</pubDate>
         <content:encoded><![CDATA[<p>The video from last month&#8217;s agile testing evening at skills matter in London is now online. Dave Evans and Mike Scott from SQS talked on the subject of &#8220;Testable software is good software&#8221;. They discuss the effect architectural decisions have on application testability, assert that a testable architecture is inherently a better architecture, and demonstrate how testability in itself is an essential dimension in any architecture because of its relationship to good architectural patterns and practices. To see the video, point your browser to <a rel="nofollow" target="_blank" href="http://skillsmatter.com/podcast/agile-testing/testable-software">http://skillsmatter.com/podcast/agile-testing/testable-software</a>.</p>
<p>This month, Nathan Bain and Anand Ramdeo share their experiences of working as Test Engineers within Agile development environments. They will pass on some tips they have learned along the way, discussing how they used tools such as Selenium and FitNesse. The talk is on the 22nd July, starting at 6:30 at Skills Matter. It&#8217;s free, but you have to sign up in advance for capacity planning. See <a rel="nofollow" target="_blank" href="http://skillsmatter.com/event/agile-testing/agile-testing-tools-and-approaches">http://skillsmatter.com/event/agile-testing/agile-testing-tools-and-approaches</a> for more information.</p><img src="http://feeds.feedburner.com/~r/CitconBlogs/~4/iDuncpWgX7Y" height="1" width="1"/>]]></content:encoded>
         <category>articles</category>
      <feedburner:origLink>http://gojko.net/2009/07/05/testable-software-is-good-software-video-is-online/</feedburner:origLink></item>
      <item>
         <title>Spec Workshops at the UK Test Management Forum</title>
         <link>http://feedproxy.google.com/~r/CitconBlogs/~3/CiUBDHWA4O8/</link>
         <description>I&amp;#8217;ll be speaking about specification workshops at the 23rd UK Test Management forum, which will take place on Wednesday 29th July at the conference centre at Balls&amp;#8217;s Brothers, Minster Pavement. For more information, see http://uktmf.com/index.php?q=node/189.</description>
         <author>gojko</author>
         <guid isPermaLink="false">http://gojko.net/?p=1004</guid>
         <pubDate>Fri, 03 Jul 2009 18:11:33 -0700</pubDate>
         <content:encoded><![CDATA[<p>I&#8217;ll be speaking about specification workshops at the 23rd UK Test Management forum, which will take place on Wednesday 29th July at the conference centre at Balls&#8217;s Brothers, Minster Pavement. For more information, see <a rel="nofollow" target="_blank" href="http://uktmf.com/index.php?q=node/189">http://uktmf.com/index.php?q=node/189</a>.</p><img src="http://feeds.feedburner.com/~r/CitconBlogs/~4/CiUBDHWA4O8" height="1" width="1"/>]]></content:encoded>
         <category>presentations</category>
      <feedburner:origLink>http://gojko.net/2009/07/04/spec-workshops-at-the-uk-test-management-forum/</feedburner:origLink></item>
      <item>
         <title>Story: Daniel’s Continuous Integration System</title>
         <link>http://feedproxy.google.com/~r/CitconBlogs/~3/VjonZVT-rTU/continuous-integration</link>
         <description>Daniel Spiewak gave us this great story for the Atlassian Giveaway. He&amp;#8217;s earned a t-shirt. Have a good weekend, where-ever you are. It was a dark and stormy night. No, actually it was a plesant summer day, but daylight lacks a certain dramatic flare which is so necessary for a good story, especially [...]&lt;div class="feedflare"&gt;
&lt;a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/TheBuildDoctor?a=DFUVPGd1OKE:v0cdYzxeSKA:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheBuildDoctor?d=yIl2AUoC8zA" border="0"&gt;&lt;/a&gt; &lt;a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/TheBuildDoctor?a=DFUVPGd1OKE:v0cdYzxeSKA:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheBuildDoctor?i=DFUVPGd1OKE:v0cdYzxeSKA:F7zBnMyn0Lo" border="0"&gt;&lt;/a&gt; &lt;a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/TheBuildDoctor?a=DFUVPGd1OKE:v0cdYzxeSKA:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheBuildDoctor?i=DFUVPGd1OKE:v0cdYzxeSKA:V_sGLiPBpWU" border="0"&gt;&lt;/a&gt; &lt;a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/TheBuildDoctor?a=DFUVPGd1OKE:v0cdYzxeSKA:ZWQ2tSG2k2o"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheBuildDoctor?d=ZWQ2tSG2k2o" border="0"&gt;&lt;/a&gt; &lt;a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/TheBuildDoctor?a=DFUVPGd1OKE:v0cdYzxeSKA:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheBuildDoctor?d=I9og5sOYxJI" border="0"&gt;&lt;/a&gt; &lt;a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/TheBuildDoctor?a=DFUVPGd1OKE:v0cdYzxeSKA:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheBuildDoctor?i=DFUVPGd1OKE:v0cdYzxeSKA:gIN9vFwOqvQ" border="0"&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CitconBlogs/~4/VjonZVT-rTU" height="1" width="1"/&gt;</description>
         <author>simpsonjulian</author>
         <guid isPermaLink="false">http://www.build-doctor.com/?p=810</guid>
         <pubDate>Fri, 03 Jul 2009 05:35:11 -0700</pubDate>
         <category>Uncategorized</category>
      <feedburner:origLink>http://feedproxy.google.com/~r/TheBuildDoctor/~3/DFUVPGd1OKE/continuous-integration</feedburner:origLink></item>
      <item>
         <title>Euler was groovy too</title>
         <link>http://feedproxy.google.com/~r/CitconBlogs/~3/eKvKaF9-FKc/</link>
         <description>I recently stumbled across Project Euler, which is a hip website containing quite a few different math challenges. The idea being that people can attempt to solve any particular challenge which ever way they can (that is, in any language and with any algorithm) &amp;#8212; the site doesn&amp;#8217;t provide answers either &amp;#8212; you must create [...]</description>
         <author>Andy</author>
         <guid isPermaLink="false">http://thediscoblog.com/?p=643</guid>
         <pubDate>Wed, 01 Jul 2009 12:03:18 -0700</pubDate>
         <content:encoded><![CDATA[<p>
I recently stumbled across <a rel="nofollow" target="_blank" href="http://projecteuler.net">Project Euler</a>, which is a hip website containing quite a few different math challenges. The idea being that people can attempt to solve any particular challenge which ever way they can (that is, in any language and with any algorithm) &#8212; the site doesn&#8217;t provide answers either &#8212; you must create an account and submit your answer. Project Euler will then check your answer and issue a response &#8212; correct or incorrect. If it&#8217;s your bag and you Google the project, you&#8217;ll find some interesting posts solving various problems in various languages ranging from F# to Scala to C (and everything in between). What&#8217;s also interesting is that each post for a problem usually is different in some way or another, which of course provides some interesting learning opportunities.
</p>
<p>
<a rel="nofollow" target="_blank" HREF="http://projecteuler.net/index.php?section=problems&#038;id=1">Problem 1</a> entails figuring out the sum of numbers divisible by 3 and 5: </p>
<blockquote><p>
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.<br />
Find the sum of all the multiples of 3 or 5 below 1000.
</p></blockquote>
<p>
I thought it would be interesting to see if I could solve this in <a rel="nofollow" target="_blank" HREF="http://groovy.codehaus.org">Groovy</a> as the solution clearly deals with iterating over a series of numbers &#8212; and as everyone who has played with <a rel="nofollow" target="_blank" HREF="http://thediscoblog.com/category/dynamic-languages/groovy/">Groovy</a> (or some other dynamic language for that matter) knows, <a rel="nofollow" target="_blank" HREF="http://thediscoblog.com/2008/11/27/ranges-in-groovy-are-hip/">iteration is a blast</a>, baby!
</p>
<p>
Accordingly, my first pass yielded the following code: </p>
<pre><code>def sum = 0
(1..&lt;1000).each{ if((it % 5 == 0) || (it % 3 == 0)){ sum += it }
}
assert sum == /* do it yourself, baby! */</code></pre>

<p>Note that I&#8217;m using Groovy&#8217;s <a rel="nofollow" target="_blank" HREF="http://groovy.codehaus.org/Collections">exclusive range feature</a> to easily iterate over all numbers less than 1000. I then proceed to use Groovy&#8217;s <code>it</code> variable, which represents the current value in the iteration (i.e. 1, 2, 3, etc) and test the instance with Java&#8217;s <a rel="nofollow" target="_blank" HREF="http://www.cafeaulait.org/course/week2/15.html">modulo operator</a> (that is, modulo returns the remainder of division &#8212; 10 modulo 5 is 0, but 11 modulo 5 is 1). If there is a match, I add it to the <code>sum</code> variable. This is programming 101 and brought me back to the Age of Aquarius, baby!!
</p>
<p>
That was easy enough; however, I wanted to see if I could do away with the <code>sum</code> variable by using one of Groovy&#8217;s many hip magic methods <a rel="nofollow" target="_blank" HREF="http://groovy.codehaus.org/JN1015-Collections">attached to collections</a>. Thus, my second attempt leverages Groovy&#8217;s <code>findAll</code> method, which permits putting a condition in the resulting <a rel="nofollow" target="_blank" HREF="http://thediscoblog.com/2009/02/09/leveraging-closures/">closure</a>, which then returns a collection meeting that criteria. Accordingly, with the returned collection of numbers meeting my criteria (that is, any number that is divisible by 5 or 3), I then have to issue the <code>sum</code> method like so:</p>
<pre><code>def val = (1..&lt;1000).findAll{(it % 5 == 0) || (it % 3 == 0)}
assert val.sum() == /* you gotta figure it out yourself, man! */</code></pre>

<p>Groovy&#8217;s <code>sum</code> method is straight forward &#8212; it takes all the values in a collection (presumably <a rel="nofollow" target="_blank" HREF="http://www.ibm.com/developerworks/java/library/j-pg10255.html">add-able</a>) and adds them up! </p>
<p>
Admittedly, the second example is a bit harder to read (at first glance, that is) but it sure is a bit more aesthetic than the first brute force bogue example, isn&#8217;t it?</p> <p><center>You can now follow <a rel="nofollow" target="_blank" href="http://twitter.com/thediscoblog">The Disco Blog on Twitter</a>, baby!</center></p><img src="http://feeds.feedburner.com/~r/CitconBlogs/~4/eKvKaF9-FKc" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://thediscoblog.com/2009/07/01/euler-was-groovy-too/</feedburner:origLink></item>
      <item>
         <title>Reviewing code quality of Apache Sling using Sonar</title>
         <link>http://feedproxy.google.com/~r/CitconBlogs/~3/1kcjk0RRqNg/</link>
         <description>A few weeks ago Michael Marth, who runs dev.day.com (Day&amp;#8217;s developer portal), asked us if we could put together our impressions on the code quality of Apache Sling using Sonar. We thought it would be valuable to share the result of this exercise with the community.
Apache Sling in a few words &amp;#8220;Apache Sling is an innovative [...]</description>
         <author>Freddy Mallet</author>
         <guid isPermaLink="false">http://sonar.codehaus.org/?p=1410</guid>
         <pubDate>Wed, 01 Jul 2009 05:55:29 -0700</pubDate>
         <content:encoded><![CDATA[<p>A few weeks ago Michael Marth, who runs <a rel="nofollow" target="_blank" href="http://dev.day.com">dev.day.com</a> (Day&#8217;s developer portal), asked us if we could put together our impressions on the code quality of <a rel="nofollow" target="_blank" href="http://incubator.apache.org/sling/">Apache Sling</a> using Sonar. We thought it would be valuable to share the result of this exercise with the community.<br/></p>
<h2>Apache Sling in a few words</h2>
<blockquote><p>
&#8220;Apache Sling is an innovative web framework that is intended to bring back the fun to web development. It uses all those nice cool and new technologies that make up a state-of-the-art framework. This is Apache Sling in five bullets:</p>
<ul>
<li>REST based web framework</li>
<li>Content-driven, using a JCR content repository</li>
<li>Powered by OSGi</li>
<li>Scripting inside, multiple languages</li>
<li>Apache Open Source project</li>
</ul>
</blockquote>
<p><span id="more-1410"></span></p>
<h2>Some size indications of the project</h2>
<ul>
<li>40 Maven modules</li>
<li>70,707 lines of code</li>
<li>731 Java classes</li>
<li>and 23,043 lines of Javadoc</li>
</ul>
<h2>The strengths in terms of quality</h2>
<ul>
<li>A project that you get and compile with no difficulty by running two commands :<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1. svn checkout https://svn.apache.org/repos/asf/sling/trunk/<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2. mvn clean install<br />
This sounds like an evidence but is not always the case :-)</li>
<li>Amongst 130,172 physical lines, only 0.9% are involved in a duplication</li>
<li>46.4% of public API are commented with a Javadoc block</li>
</ul>
<h2>The weaknesses</h2>
<ul>
<li>Only 9% of the source code is covered by 338 unit tests</li>
<li>Average cyclomatic complexity by method (excluding getters and setters) is greater than 3 (3.2).<br />
That is kind of a warning saying &#8220;your methods are taking too much responsibilities and should be re-factored&#8221;. This warning is confirmed by others metrics : 394 methods have a complexity greater than 7 and 86 methods have more than 50 statements. What is true at method level gets also partially confirmed at class level as 60 classes have a Fan Out Complexity greater than 20 (The number of other classes referenced by a class)</li>
</ul>
<h2>Bad programming practices that should be improved</h2>
<ul>
<li>198 times, method parameters are reassigned in the core of the method</li>
<li>68 times, local variables are defined and hide class fields</li>
<li>28 times, NullPointerException are thrown when an IllegalParameterException would be more suitable</li>
</ul>
<h2>Potential bugs that should be quickly analyzed</h2>
<ul>
<li>Correctness - An apparent infinite recursive loop : there is an apparent infinite recursive loop in org.apache.sling.scripting.jsp.jasper.runtime.<a rel="nofollow" target="_blank" href="http://nemo.sonarsource.org/drilldown/rules/107290?rule_id=341&#038;viewer_plugin_key=org.sonar.plugins.core.violationssourceviewer.GwtViolationsSourceViewer&#038;viewer_resource_key=org.apache.sling:org.apache.sling.scripting.jsp:org.apache.sling.scripting.jsp.jasper.runtime.JspContextWrapper">JspContextWrapper</a>.include(String, boolean)</li>
<li>Multithreaded correctness - Unsynchronized get method, synchronized set method : org.apache.sling.scripting.jsp.jasper.compiler.<a rel="nofollow" target="_blank" href="http://nemo.sonarsource.org/drilldown/rules/107290?rule_id=450&#038;viewer_plugin_key=org.sonar.plugins.core.violationssourceviewer.GwtViolationsSourceViewer&#038;viewer_resource_key=org.apache.sling:org.apache.sling.scripting.jsp:org.apache.sling.scripting.jsp.jasper.compiler.JspRuntimeContext">JspRuntimeContext</a>.getJspReloadCount() is unsynchronized, org.apache.sling.scripting.jsp.jasper.compiler.JspRuntimeContext.setJspReloadCount(int) is synchronized</li>
<li>Multithreaded correctness - Method calls Thread.sleep() with a lock held : org.apache.sling.event.impl.<a rel="nofollow" target="_blank" href="http://nemo.sonarsource.org/drilldown/rules/107290?rule_id=655&#038;viewer_plugin_key=org.sonar.plugins.core.violationssourceviewer.GwtViolationsSourceViewer&#038;viewer_resource_key=org.apache.sling:org.apache.sling.event:org.apache.sling.event.impl.JobEventHandler">JobEventHandle</a>r.runJobQueue(String, JobBlockingQueue) calls Thread.sleep() with a lock held</li>
<li>Malicious code vulnerability - Field is a mutable array : org.apache.sling.jcr.webdav.impl.servlets.<a rel="nofollow" target="_blank" href="http://nemo.sonarsource.org/drilldown/rules/107290?rule_id=463&#038;viewer_plugin_key=org.sonar.plugins.core.violationssourceviewer.GwtViolationsSourceViewer&#038;viewer_resource_key=org.apache.sling:org.apache.sling.jcr.webdav:org.apache.sling.jcr.webdav.impl.servlets.SlingWebDavServlet">SlingWebDavServlet</a>.COLLECTION_TYPES_DEFAULT is a mutable array</li>
</ul>
<p>This analysis was done with the intention of giving a synthetic overview of the current state of the project. Where should you start from if tomorrow you wake up with a single idea in mind : &#8220;Improving quality of the Apache Sling project !&#8221; ?</p>
<ul>
<li>With respectively a cyclomatic complexity of 428, 385 and 343, classes Generator, Parser and XMLEndoginDetector should be first refactored. With no surprise, the Generator.java file has the greatest number of duplicated lines (154) and rules violations (109)</li>
<li>With its 43 cyclomatic complexity and no unit tests, the method ModifyAceServlet.handleOperation(..) is what we call &#8220;a <a rel="nofollow" target="_blank" href="http://www.crap4j.org/">crappy</a> method&#8221; :-)</li>
</ul>
<p>More information on the code quality of the project is available on <a rel="nofollow" target="_blank" href="http://nemo.sonarsource.org/project/index/org.apache.sling:sling-builder">Nemo</a>. </p>
<img src="http://feeds.feedburner.com/~r/Sonar/~4/x5emIwOlbrE" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/CitconBlogs/~4/1kcjk0RRqNg" height="1" width="1"/>]]></content:encoded>
         <category>blog</category>
      <feedburner:origLink>http://feedproxy.google.com/~r/Sonar/~3/x5emIwOlbrE/</feedburner:origLink></item>
      <item>
         <title>Upcoming OSC appearances</title>
         <link>http://feedproxy.google.com/~r/CitconBlogs/~3/b-BiyBwA-Ic/</link>
         <description>In prepping for tomorrow&amp;#8217;s presentation on Social Media for the Shenandoah Ruby Users Group, Jennifer Till asked me where else we were going to be appearing at. I feel like a concert promoter who&amp;#8217;s failed to promote his band&amp;#8217;s concerts. We have several upcoming appearances; here are a few of them! (...)</description>
         <author>Jason Hull</author>
         <guid isPermaLink="false">http://www.opensourceconnections.com/?p=438</guid>
         <pubDate>Mon, 29 Jun 2009 10:02:33 -0700</pubDate>
         <content:encoded><![CDATA[<p>In prepping for tomorrow&#8217;s presentation on Social Media for the <a rel="nofollow" title="ShRUG Social Media Presentation" target="_blank" href="http://ruby.meetup.com/128/calendar/10498497/">Shenandoah Ruby Users Group</a>, <a rel="nofollow" title="The Bridge, Ltd." target="_blank" href="http://www.redballbridge.com/">Jennifer Till</a> asked me where else we were going to be appearing at. I feel like a concert promoter who&#8217;s failed to promote his band&#8217;s concerts. We have several upcoming appearances; here are a few of them!</p>
<p>June 30, Harrisonburg, VA: <a rel="nofollow" title="ShRUG Social Media Presentation" target="_blank" href="http://ruby.meetup.com/128/calendar/10498497/">Shenandoah Ruby Users Group</a>, Social Media 201 (Jason Hull)</p>
<p>July 23, Las Vegas, NV: <a rel="nofollow" title="National Veterans Conference" target="_blank" href="http://nationalveteransconference.com/agenda.html">National Veterans Conference</a>, Leveraging Web 2.0 Applications for Productivity (Jason Hull)</p>
<p>August 27, Chicago, IL: <a rel="nofollow" title="Agile2009" target="_blank" href="http://agile2009.agilealliance.org/node/2869">Agile2009</a>, How to Sell a Traditional Client on an Agile Project Plan (Arin Sime)</p>
<p>October 21, Cambridge, MA: <a rel="nofollow" title="Software Test &amp; Performance Conference" target="_blank" href="http://www.stpcon.com/program-test-automation-course.html#day-3-afternoon">Software Test &amp; Performance Conference</a>, Setup and Testing with Continuous Integration (Eric Pugh)</p>
<p>If you&#8217;re going to be at any of these conferences or meetings, give us a shout! We&#8217;d love to meet up with you!</p><img src="http://feeds.feedburner.com/~r/CitconBlogs/~4/b-BiyBwA-Ic" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://www.opensourceconnections.com/2009/06/29/upcoming-osc-appearances/</feedburner:origLink></item>
      <item>
         <title>Atlassian Giveaway Winners!</title>
         <link>http://feedproxy.google.com/~r/CitconBlogs/~3/o3i13rUUQ1c/atlassian-giveaway-winners</link>
         <description>Thanks to everyone who wrote a story for the Atlassian Giveaway. The entries are in, the judging is complete, and here&amp;#8217;s the results!
First prize goes to John Martin, who wrote a story of despair and hope around Continuous Integration. John&amp;#8217;s an Atlassian user already, with two other products, so he&amp;#8217;s happy to make the hat [...]&lt;div class="feedflare"&gt;
&lt;a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/TheBuildDoctor?a=uPpOx22pNPM:KGcj9HN3MzQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheBuildDoctor?d=yIl2AUoC8zA" border="0"&gt;&lt;/a&gt; &lt;a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/TheBuildDoctor?a=uPpOx22pNPM:KGcj9HN3MzQ:F7zBnMyn0Lo"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheBuildDoctor?i=uPpOx22pNPM:KGcj9HN3MzQ:F7zBnMyn0Lo" border="0"&gt;&lt;/a&gt; &lt;a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/TheBuildDoctor?a=uPpOx22pNPM:KGcj9HN3MzQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheBuildDoctor?i=uPpOx22pNPM:KGcj9HN3MzQ:V_sGLiPBpWU" border="0"&gt;&lt;/a&gt; &lt;a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/TheBuildDoctor?a=uPpOx22pNPM:KGcj9HN3MzQ:ZWQ2tSG2k2o"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheBuildDoctor?d=ZWQ2tSG2k2o" border="0"&gt;&lt;/a&gt; &lt;a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/TheBuildDoctor?a=uPpOx22pNPM:KGcj9HN3MzQ:I9og5sOYxJI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheBuildDoctor?d=I9og5sOYxJI" border="0"&gt;&lt;/a&gt; &lt;a rel="nofollow" target="_blank" href="http://feeds.feedburner.com/~ff/TheBuildDoctor?a=uPpOx22pNPM:KGcj9HN3MzQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/TheBuildDoctor?i=uPpOx22pNPM:KGcj9HN3MzQ:gIN9vFwOqvQ" border="0"&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/CitconBlogs/~4/o3i13rUUQ1c" height="1" width="1"/&gt;</description>
         <author>simpsonjulian</author>
         <guid isPermaLink="false">http://www.build-doctor.com/?p=795</guid>
         <pubDate>Mon, 29 Jun 2009 03:00:52 -0700</pubDate>
      <feedburner:origLink>http://feedproxy.google.com/~r/TheBuildDoctor/~3/uPpOx22pNPM/atlassian-giveaway-winners</feedburner:origLink></item>
      <item>
         <title>Agile testing: a whole team approach</title>
         <link>http://feedproxy.google.com/~r/CitconBlogs/~3/V23smOjwyn0/</link>
         <description>Agile testing is about two things: a whole life-cycle and whole team approach to testing. The whole life-cycle aspect stresses leveraging testing throughout a hip process as opposed to a distinct period. Likewise, a whole team approach welcomes all parties to the quality table as everyone (yes, that means all stakeholders) accepts responsibility for building [...]</description>
         <author>Andy</author>
         <guid isPermaLink="false">http://thediscoblog.com/?p=629</guid>
         <pubDate>Thu, 25 Jun 2009 16:15:04 -0700</pubDate>
         <content:encoded><![CDATA[<p><a rel="nofollow" target="_blank" href="http://thediscoblog.com/2009/06/11/agile-testing-what-it-is/">Agile testing</a> is about two things: a <a rel="nofollow" target="_blank" href="http://thediscoblog.com/2009/06/17/agile-testing-a-whole-life-cycle-approach/">whole life-cycle</a> and whole team approach to testing. The whole life-cycle aspect stresses leveraging testing throughout a hip process as opposed to a distinct period. Likewise, a whole team approach welcomes all parties to the quality table as everyone (yes, that means all stakeholders) accepts responsibility for <em>building in</em> quality. </p>
<p><img style="PADDING-LEFT:0.0em;PADDING-RIGHT:1.0em;PADDING-TOP:0.0em;FLOAT:LEFT;PADDING-BOTTOM:0.5em;" src="http://thediscoblog.com/images/2009/Happybusinesssm.jpg" alt="development 2.0: high costs!" width="357" height="252"/>While <a rel="nofollow" target="_blank" href="http://thediscoblog.com/2009/06/04/agile-testing-what-its-not/">traditional software methodologies</a> have the tendency to segment groups into logical units of responsibility, <a rel="nofollow" target="_blank" href="http://www.amazon.com/gp/product/0321534468?ie=UTF8&#038;tag=thdibl-20&#038;linkCode=as2&#038;camp=1789&#038;creative=9325&#038;creativeASIN=0321534468">agile teams</a><img src="http://www.assoc-amazon.com/e/ir?t=thdibl-20&#038;l=as2&#038;o=1&#038;a=0321534468" width="1" height="1" border="0" alt="" style="border:none !important;margin:0px !important;"/> favor a more collaborative approach that facilitates working along side various people and groups containing differing skill sets and expectations. That is, for example, the client begins to take responsibility for elaborating expectations through a working effort to understand how the process unfolds. What&#8217;s more, by working closely with a client, a team can better understand what is needed <em>and why</em>. As opposed to a test document fashioned from a bogue requirements document (often times done by various teams working separately), leveraging a <a rel="nofollow" target="_blank" href="http://thediscoblog.com/2008/10/16/lost-in-translation-stop-using-different-languages/">story in a collaborative manner</a> ensures all parties are effectively on the same page. Thus, the customer (or some proxy there of), development, and QA are working together in the process of constructing stories and indeed leverage the same stories for all related assets.</p>
<p>Because it&#8217;s their bag, when Agile teams embrace stories as a fundamental means as to conveying requirements (i.e. features) along with a means for validating them, a natural tendency is for all parties to begin to own quality. That is, since everyone is aware of how to validate a feature, everyone begins to practice validating such features. In essence, a story facilitates leveraging both <a rel="nofollow" target="_blank" href="http://www.amazon.com/gp/product/0321146530?ie=UTF8&#038;tag=thdibl-20&#038;linkCode=as2&#038;camp=1789&#038;creative=9325&#038;creativeASIN=0321146530">TDD</a><img src="http://www.assoc-amazon.com/e/ir?t=thdibl-20&#038;l=as2&#038;o=1&#038;a=0321146530" width="1" height="1" border="0" alt="" style="border:none !important;margin:0px !important;"/> and functional testing (which are also both automated and exercised via <a rel="nofollow" target="_blank" href="http://www.amazon.com/gp/product/0321336380?ie=UTF8&#038;tag=thdibl-20&#038;linkCode=as2&#038;camp=1789&#038;creative=9325&#038;creativeASIN=0321336380">CI</a><img src="http://www.assoc-amazon.com/e/ir?t=thdibl-20&#038;l=as2&#038;o=1&#038;a=0321336380" width="1" height="1" border="0" alt="" style="border:none !important;margin:0px !important;"/>) .</p>
<p>What&#8217;s more, when the whole team both works together off of the same artifacts that are continuously verified, everyone can better understand the meaning of &#8220;done&#8221; &#8212; that being the question &#8220;is feature x finished and ready for the client (or clients) to have?&#8221; Of course, if everyone has utilized the same artifact (i.e. a <a rel="nofollow" target="_blank" href="http://www.amazon.com/gp/product/0321205685?ie=UTF8&#038;tag=thdibl-20&#038;linkCode=as2&#038;camp=1789&#038;creative=9325&#038;creativeASIN=0321205685">story</a><img src="http://www.assoc-amazon.com/e/ir?t=thdibl-20&#038;l=as2&#038;o=1&#038;a=0321205685" width="1" height="1" border="0" alt="" style="border:none !important;margin:0px !important;"/>!) for both building and verifying a client&#8217;s expectations, then it is quite easy to check if the feature is done. </p>
<p>Thus, the whole team approach that leverages stories:</p>
<ul>
<li>ensures all hip parties see and understand the &#8220;big picture&#8221; of a particular project
<ul>
<li> that is, why someone wants an application (and its related features) built, which in turn further facilitates whole team ownership (along with more effective testing!)</li>
</ul>
</li>
<li>helps teams figure out the definition of done</li>
</ul>
<p>Obtaining these benefits is a matter of providing a means for all parties on a team to collaborate, which is often found in leveraging a story. Plus, visibility into overall team progress as facilitated via CI and automation. The whole team approach also meets the original goal of software testing &#8212; that being the assurance that high quality code is delivered to interested parties. Teaming also reduces the tendency to throw up barriers that often plague efficiency.</p>
<p>Agile testing boils down to two fundamental changes, baby, that differentiate it from traditional software testing &#8212; both the notion that testing isn&#8217;t a phase but a whole life-cycle approach and that the entire team works together towards shared goals. Agile testing complements a highly efficient software development life-cycle and ultimately produces <em>better software faster</em>. </p> <p><center>You can now follow <a rel="nofollow" target="_blank" href="http://twitter.com/thediscoblog">The Disco Blog on Twitter</a>, baby!</center></p><img src="http://feeds.feedburner.com/~r/CitconBlogs/~4/V23smOjwyn0" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://thediscoblog.com/2009/06/25/agile-testing-a-whole-team-approach/</feedburner:origLink></item>
      <item>
         <title>Beyond the tool, Sonar is a platform to manage code quality</title>
         <link>http://feedproxy.google.com/~r/CitconBlogs/~3/xJFggd468iE/</link>
         <description>You already know Sonar as an enterprise tool to analyze and manage code quality of a projects portfolio. We claim, for very good reasons obviously :-), that it is easy to install and easy to use. Currently, it covers Java and PL/SQL languages.
As a tool, Sonar is more and more often compared to commercial products [...]</description>
         <author>Freddy Mallet</author>
         <guid isPermaLink="false">http://sonar.codehaus.org/?p=1298</guid>
         <pubDate>Thu, 25 Jun 2009 14:00:39 -0700</pubDate>
         <content:encoded><![CDATA[<p>You already know Sonar as an enterprise tool to analyze and manage code quality of a projects portfolio. We claim, for very good reasons obviously :-), that it is easy to install and easy to use. Currently, it covers Java and <a rel="nofollow" target="_blank" href="http://www.sonarsource.com/plugins/">PL/SQL</a> languages.<br/><br />
As a tool, Sonar is more and more often compared to commercial products such as Cast Software or Metrixware for instance. Having said that, if I had the choice, I&#8217;d prefer Sonar to be compared to <a rel="nofollow" target="_blank" href="http://www.kalistick.com">Kalistik</a> (commercial product) that better fits the market evolution and needs.<br/><br />
All this is great, but as you might have realized already, Sonar is more than a simple out-of-the-box product : <b>it is an open source (LGPL) platform to manage code quality</b>, i.e. the foundations on which the community has already started to build new floors. Our aim is that Sonar becomes to quality management what TCP is today to network applications : the central component to go further and faster. That&#8217;s our new dream since the command &#8220;<a rel="nofollow">mvn sonar:sonar</a>&#8221; is available :-).<br/><br />
Here are real life examples that support the idea of Sonar being a platform:</p>
<ul>
<li>Let&#8217;s say you have built a commercial tool (<a rel="nofollow" target="_blank" href="http://www.gimpel.com/">PC-Lint</a>, <a rel="nofollow" target="_blank" href="http://www.redhillconsulting.com.au/products/simian/">Simian</a>, <a rel="nofollow" target="_blank" href="https://www.sdn.sap.com/irj/scn/wiki?path=/display/ABAP/Code+Inspector">SAP ABAP Code Inspector</a> &#8230; ) or an open source one (<a rel="nofollow" target="_blank" href="http://www.testabilityexplorer.org/">Testability Explorer</a>, <a rel="nofollow" target="_blank" href="http://www.crap4j.org/">Crap4j</a>, <a rel="nofollow" target="_blank" href="http://clang-analyzer.llvm.org/">Clang Static Analyzer</a>&#8230;) or let&#8217;s say that you think a new axis of quality analysis would be more pertinent. By developing a plugin in Sonar, you kill two birds with one stone : you immediately have access to a large community of users and you benefit from the built-in functionality (TimeMachine, trends, consolidation&#8230;)</li>
<li>You manage a consulting company and are building a package around quality. By building this package around Sonar, your client gets basically the tool for free and what they are going to pay for is what you have to sell : your expertise on quality </li>
</ul>
<p>I believe that code quality management is going to become a commodity in the medium term as is continuous integration today; and I do hope that Sonar is going to play a central role in this democratization move.</p>
<img src="http://feeds.feedburner.com/~r/Sonar/~4/y_7wTIECOnU" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/CitconBlogs/~4/xJFggd468iE" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://feedproxy.google.com/~r/Sonar/~3/y_7wTIECOnU/</feedburner:origLink></item>
      <item>
         <title>Ready to Test: Maven + TestNG + Hamcrest + Mockito</title>
         <link>http://feedproxy.google.com/~r/CitconBlogs/~3/iGU3k-2DlZM/</link>
         <description>I&amp;#8217;m no Maven fanboy, but for a new, small Java project the ultra-fast setup time is compelling. So, for my latest little application, I decided to give it a go. Sadly, the default Maven archetype lumped my project with JUnit 3.8.1. Boo. And although the TestNG website mentions an alternative archetype, [...]</description>
         <author>Jason</author>
         <guid isPermaLink="false">http://www.alittlemadness.com/?p=249</guid>
         <pubDate>Wed, 24 Jun 2009 16:12:49 -0700</pubDate>
         <content:encoded><![CDATA[<p>I&#8217;m no <a rel="nofollow" target="_blank" href="http://maven.apache.org">Maven</a> fanboy, but for a new, small Java project the ultra-fast setup time is compelling. So, for my latest little application, I decided to give it a go. Sadly, the default Maven archetype lumped my project with <a rel="nofollow" target="_blank" href="http://junit.org/">JUnit</a> 3.8.1. Boo. And although the TestNG website mentions an alternative archetype, it appears to have disappeared off the face of the internet.</p>
<p>Luckily, dragging my project into the present wasn&#8217;t difficult. Along the way I also added my essential testing libraries: <a rel="nofollow" target="_blank" href="http://code.google.com/p/hamcrest/">Hamcrest</a> for matchers and <a rel="nofollow" target="_blank" href="http://code.google.com/p/mockito/">Mockito</a> for mocking (well, stubbing, but that&#8217;s another story). For posterity&#8217;s sake, and for others that share my testing tastes, here&#8217;s how it&#8217;s done.</p>
<h2>Requirements</h2>
<p>I&#8217;m assuming that you have Maven 2 installed already. If not, it&#8217;s trivial to:</p>
<ol>
<li><a rel="nofollow" target="_blank" href="http://maven.apache.org/download.html">Download</a> the latest (2.1.0 at time of writing); and</li>
<li>Install it according to the <a rel="nofollow" target="_blank" href="http://maven.apache.org/download.html#Installation">instructions</a> provided.
</ol>
<p>You can check if you have Maven ready to go by running:</p>
<div class="codesnip-container">$ mvn &#8211;version<br />
Apache Maven 2.1.0 (r755702; 2009-03-18 19:10:27+0000)<br />
Java version: 1.6.0_12<br />
Java home: /usr/local/java/jdk1.6.0_12/jre<br />
Default locale: en_AU, platform encoding: UTF-8<br />
OS name: &#8220;linux&#8221; version: &#8220;2.6.28-11-generic&#8221; arch: &#8220;amd64&#8243; Family: &#8220;unix&#8221;</div>
<h2>Bootstrap</h2>
<p>With the lack of an available alternative, I found it easiest to start with the default archetype. To create a new project, run something like:</p>
<div class="codesnip-container">$ mvn archetype:create -DgroupId=com.mycompany.app -DartifactId=my-app</div>
<p>Remember that if you&#8217;ve just installed Maven it will take this opportunity to <a rel="nofollow" target="_blank" href="http://fishbowl.pastiche.org/2007/12/20/maven_broken_by_design/">download the internet</a>. Be patient. If you&#8217;re new to Maven, you might also want to check out the <a rel="nofollow" target="_blank" href="http://maven.apache.org/guides/getting-started/maven-in-five-minutes.html">5 minute guide</a> which walks through this in more detail.</p>
<p>Check that your bare application has been created:</p>
<div class="codesnip-container">$ cd my-app<br />
$ find . -type f<br />
./src/main/java/com/mycompany/app/App.java<br />
./src/test/java/com/mycompany/app/AppTest.java<br />
./pom.xml<br />
$ mvn package<br />
&#8230;<br />
$ java -cp target/my-app-1.0-SNAPSHOT.jar com.mycompany.app.App<br />
Hello World!</div>
<h2>Add the Dependencies</h2>
<p>Next you need to update the project POM to add the testing libraries as dependencies to your build. This involves three changes:</p>
<ol>
<li>Removing the default dependency on JUnit.</li>
<li>Adding new dependencies for TestNG, Hamcrest and Mockito to the &#8220;test&#8221; scope.</li>
<li>Configuring the compiler to accept Java 5 source.</li>
</ol>
<p>The last step is necessary as the Maven default setting assumes Java 1.3 source, which apart from being ancient doesn&#8217;t support goodies such as annotations that are required for the new testing libraries. Your updated pom.xml file should look something like:</p>
<div class="codesnip-container">
<div class="codesnip"><span class="sc3"><span class="re1">&lt;project</span> <span class="re0">xmlns</span>=<span class="st0">&#8220;http://maven.apache.org/POM/4.0.0&#8243;</span> xmlns:<span class="re0">xsi</span>=<span class="st0">&#8220;http://www.w3.org/2001/XMLSchema-instance&#8221;</span><br />
&nbsp; xsi:<span class="re0">schemaLocation</span>=<span class="st0">&#8220;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&#8221;</span><span class="re2">&gt;</span></span><br />
&nbsp; <span class="sc3"><span class="re1">&lt;modelVersion<span class="re2">&gt;</span></span></span>4.0.0<span class="sc3"><span class="re1">&lt;/modelVersion<span class="re2">&gt;</span></span></span><br />
&nbsp; <span class="sc3"><span class="re1">&lt;groupId<span class="re2">&gt;</span></span></span>com.mycompany.app<span class="sc3"><span class="re1">&lt;/groupId<span class="re2">&gt;</span></span></span><br />
&nbsp; <span class="sc3"><span class="re1">&lt;artifactId<span class="re2">&gt;</span></span></span>my-app<span class="sc3"><span class="re1">&lt;/artifactId<span class="re2">&gt;</span></span></span><br />
&nbsp; <span class="sc3"><span class="re1">&lt;packaging<span class="re2">&gt;</span></span></span>jar<span class="sc3"><span class="re1">&lt;/packaging<span class="re2">&gt;</span></span></span><br />
&nbsp; <span class="sc3"><span class="re1">&lt;version<span class="re2">&gt;</span></span></span>1.0-SNAPSHOT<span class="sc3"><span class="re1">&lt;/version<span class="re2">&gt;</span></span></span><br />
&nbsp; <span class="sc3"><span class="re1">&lt;name<span class="re2">&gt;</span></span></span>my-app<span class="sc3"><span class="re1">&lt;/name<span class="re2">&gt;</span></span></span><br />
&nbsp; <span class="sc3"><span class="re1">&lt;url<span class="re2">&gt;</span></span></span>http://maven.apache.org<span class="sc3"><span class="re1">&lt;/url<span class="re2">&gt;</span></span></span><br />
&nbsp; <span class="sc3"><span class="re1">&lt;dependencies<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;dependency<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;groupId<span class="re2">&gt;</span></span></span>org.testng<span class="sc3"><span class="re1">&lt;/groupId<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;artifactId<span class="re2">&gt;</span></span></span>testng<span class="sc3"><span class="re1">&lt;/artifactId<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;version<span class="re2">&gt;</span></span></span>5.8<span class="sc3"><span class="re1">&lt;/version<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;scope<span class="re2">&gt;</span></span></span>test<span class="sc3"><span class="re1">&lt;/scope<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;classifier<span class="re2">&gt;</span></span></span>jdk15<span class="sc3"><span class="re1">&lt;/classifier<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/dependency<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;dependency<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;groupId<span class="re2">&gt;</span></span></span>org.mockito<span class="sc3"><span class="re1">&lt;/groupId<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;artifactId<span class="re2">&gt;</span></span></span>mockito-all<span class="sc3"><span class="re1">&lt;/artifactId<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;version<span class="re2">&gt;</span></span></span>1.8.0-rc2<span class="sc3"><span class="re1">&lt;/version<span class="re2">&gt;</span></span></span> <br />
&nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;scope<span class="re2">&gt;</span></span></span>test<span class="sc3"><span class="re1">&lt;/scope<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/dependency<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;dependency<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;groupId<span class="re2">&gt;</span></span></span>org.hamcrest<span class="sc3"><span class="re1">&lt;/groupId<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;artifactId<span class="re2">&gt;</span></span></span>hamcrest-all<span class="sc3"><span class="re1">&lt;/artifactId<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;version<span class="re2">&gt;</span></span></span>1.1<span class="sc3"><span class="re1">&lt;/version<span class="re2">&gt;</span></span></span> <br />
&nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;scope<span class="re2">&gt;</span></span></span>test<span class="sc3"><span class="re1">&lt;/scope<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/dependency<span class="re2">&gt;</span></span></span><br />
&nbsp; <span class="sc3"><span class="re1">&lt;/dependencies<span class="re2">&gt;</span></span></span><br />
&nbsp; <span class="sc3"><span class="re1">&lt;build<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;plugins<span class="re2">&gt;</span></span></span>&nbsp; <br />
&nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;plugin<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;artifactId<span class="re2">&gt;</span></span></span>maven-compiler-plugin<span class="sc3"><span class="re1">&lt;/artifactId<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;configuration<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;source<span class="re2">&gt;</span></span></span>1.5<span class="sc3"><span class="re1">&lt;/source<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;target<span class="re2">&gt;</span></span></span>1.5<span class="sc3"><span class="re1">&lt;/target<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/configuration<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/plugin<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/plugins<span class="re2">&gt;</span></span></span><br />
&nbsp; <span class="sc3"><span class="re1">&lt;/build<span class="re2">&gt;</span></span></span><br />
<span class="sc3"><span class="re1">&lt;/project<span class="re2">&gt;</span></span></span></div>
</div>
<p>I&#8217;ve used the latest available versions of each of the libraries in this example &#8212; tweak them to suit your current reality.</p>
<h2>Update the Sample Test</h2>
<p>Now you&#8217;re ready to try updating the sample test case to use the trinity of TestNG, Hamcrest and Mockito. The easiest way to do this is to get Maven to generate a project for your IDE, e.g.</p>
<div class="codesnip-container">$ mvn eclipse:eclipse</div>
<p>or:</p>
<div class="codesnip-container">$ mvn idea:idea</div>
<p>Fire up your chosen IDE, open the AppTest class, and edit it to exercise all of the dependencies:</p>
<div class="codesnip-container">
<div class="codesnip">package com.<span class="me1">mycompany</span>.<span class="me1">app</span>;
<p><span class="co2">import static org.hamcrest.MatcherAssert.assertThat;</span><br />
<span class="co2">import static org.hamcrest.Matchers.equalTo;</span><br />
<span class="co2">import static org.mockito.Mockito.mock;</span><br />
<span class="co2">import static org.mockito.Mockito.when;</span><br />
<span class="co2">import org.testng.annotations.Test;</span></p>
<p><span class="co2">import java.util.Random;</span></p>
<p><span class="kw2">public</span> <span class="kw2">class</span> AppTest <br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; @Test<br />
&nbsp; &nbsp; <span class="kw2">public</span> <span class="kw4">void</span> testApp<span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <a rel="nofollow" target="_blank" href="http://www.google.com/search?q=allinurl%3ARandom+java.sun.com&#038;bntl=1"><span class="kw3">Random</span></a> mockRandom = mock<span class="br0">&#40;</span><a rel="nofollow" target="_blank" href="http://www.google.com/search?q=allinurl%3ARandom+java.sun.com&#038;bntl=1"><span class="kw3">Random</span></a>.<span class="kw2">class</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; when<span class="br0">&#40;</span>mockRandom.<span class="me1">nextInt</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span>.<span class="me1">thenReturn</span><span class="br0">&#40;</span><span class="nu0">42</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; assertThat<span class="br0">&#40;</span>mockRandom.<span class="me1">nextInt</span><span class="br0">&#40;</span><span class="br0">&#41;</span>, equalTo<span class="br0">&#40;</span><span class="nu0">42</span><span class="br0">&#41;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
</div>
<p>What are you waiting for? Try it out:</p>
<div class="codesnip-container">$ mvn test<br />
&#8230;<br />
Results :
<p>Tests run: 1, Failures: 0, Errors: 0, Skipped: 0</p>
<p>[INFO] &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
[INFO] BUILD SUCCESSFUL<br />
[INFO] &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
[INFO] Total time: 18 seconds<br />
[INFO] Finished at: Wed Jun 24 16:11:48 BST 2009<br />
[INFO] Final Memory: 20M/100M<br />
[INFO] &#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p></div>
<p>If you got this far, then everything you need is in place. Now you just have to &#8230; implement your project!</p>
<h2>Extra Credit</h2>
<p>If you poke about a bit, you will also find that the maven surefire plugin, which manages the tests, generates some reports by default. Along with HTML output, it also produces a JUnit-like XML report at:</p>
<div class="codesnip-container">target/surefire-reports/TEST-TestSuite.xml</div>
<p>This report is ideal for integration with a continuous integration server (in my case <a rel="nofollow" target="_blank" href="http://zutubi.com/products/pulse/">Pulse</a>, naturally, but many will support it).</p>
<p>Happy testing! </p><img src="http://feeds.feedburner.com/~r/CitconBlogs/~4/iGU3k-2DlZM" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://www.alittlemadness.com/2009/06/25/ready-to-test-maven-testng-hamcrest-mockito/</feedburner:origLink></item>
      <item>
         <title>Sonar PDF Plugin: code quality information in a PDF report</title>
         <link>http://feedproxy.google.com/~r/CitconBlogs/~3/wNrc9jcyoRQ/</link>
         <description>When dealing with source code quality information within a company, Sonar is the perfect reporting tool as it is accessible to everybody and centralizes the information through its web server . However, in some cases, this information can be at the destination of third party organizations. This situation is common in an enterprise environment, for [...]</description>
         <author>Antonio Manuel Muñiz</author>
         <guid isPermaLink="false">http://sonar.codehaus.org/?p=1300</guid>
         <pubDate>Wed, 24 Jun 2009 01:28:46 -0700</pubDate>
         <content:encoded><![CDATA[<p>When dealing with source code quality information within a company, Sonar is the perfect reporting tool as it is accessible to everybody and centralizes the information through its web server . However, in some cases, this information can be at the destination of third party organizations. This situation is common in an enterprise environment, for instance on quality audit projects or outsourced projects. In both cases, a quality measurement deliverable is required. This is the aim of the <a rel="nofollow" target="_blank" href="http://docs.codehaus.org/display/SONAR/Sonar+PDF+Plugin">Sonar PDF Plugin</a>.<br/><br />
As described in a <a rel="nofollow" target="_blank" href="http://sonar.codehaus.org/the-sonar-plugins-forge-is-up-and-running/">previous article</a>, a Sonar plugin is a simple jar that must be copied to the /extensions/plugins directory of the Sonar web server in order to be loaded at next start. That is not the case for Sonar PDF as it is a maven plugin. The plugin uses Sonar extension points, especially the web services API, so all the data used by this plugin is retrieved through WS API.<br />
<center><img src="http://docs.codehaus.org/download/attachments/116359257/sonar-pdf-plugin-2.png" alt="PDF Report" title="PDF Report" class="aligncenter size-full"/></center><br />
The plugin, version 0.2, is currently able to report on :</p>
<ul>
<li>Global dashboard</li>
<li>Violations by categories</li>
<li>Hotspots</li>
</ul>
<p>A full example of the report is available <a rel="nofollow" target="_blank" href="http://docs.codehaus.org/download/attachments/116359257/sonar.pdf?version=1">here</a>.<br/><br />
What about the future? The future is Team Workbook Report, the second report type that will include most deep data as violations per class and line, graphics and more.<br/><br />
<b>The author</b> : Antonio Manuel Muñiz, <a rel="nofollow" target="_blank" href="http://www.gmv.com">www.gmv.com</a> (<a rel="nofollow" target="_blank" href="http://amunizmartin.wordpress.com">Blog</a>, <a rel="nofollow" target="_blank" href="mailto:ammuniz@gmv.com">email</a>)</p>
<img src="http://feeds.feedburner.com/~r/Sonar/~4/Bsv5VXYzAaM" height="1" width="1"/><img src="http://feeds.feedburner.com/~r/CitconBlogs/~4/wNrc9jcyoRQ" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://feedproxy.google.com/~r/Sonar/~3/Bsv5VXYzAaM/</feedburner:origLink></item>
      <item>
         <title>Using Scrum on grad school projects</title>
         <link>http://feedproxy.google.com/~r/CitconBlogs/~3/ogM-DyRyEAo/</link>
         <description>Last week I finished Module 1 of the UVa McIntire School of Commerce grad school program I&amp;#8217;m in, for an MS in Management of Information Technology. It was a great 2 weeks, and a lot of fun and hard work. (...)</description>
         <author>Arin Sime</author>
         <guid isPermaLink="false">http://www.opensourceconnections.com/?p=437</guid>
         <pubDate>Tue, 23 Jun 2009 13:02:17 -0700</pubDate>
         <content:encoded><![CDATA[<p>Last week I finished Module 1 of the UVa McIntire School of Commerce grad school program I&#8217;m in, for an MS in Management of Information Technology. It was a great 2 weeks, and a lot of fun and hard work.</p>
<p><a rel="nofollow" target="_blank" href="http://www.flickr.com/photos/27517504@N05/3655134468/" title="MSMIT banner by opensourceconnections, on Flickr"><img src="http://farm3.static.flickr.com/2096/3655134468_9ae272ab58.jpg" width="500" height="64" alt="MSMIT banner"/></a><br />
<br clear="left"/></p>
<p>The <a rel="nofollow" target="_blank" href="http://www.commerce.virginia.edu/grad/msmit/">MSMIT program at McIntire is a 12</a> month program for working professionals, where we typically meet for 3 long days a month, with group work, projects, and lots of reading and research in between the monthly sessions. Module One (or Mod1 as we call it) is different however. This is our full time 2 week residency at UVa, where we study various foundational IT topics in class for 8 or 9 hours. Topics like: Database design, Data network design, UML modeling, the Zachman framework, Business strategy, Web 2.0, Datawarehousing, IT security, and more.</p>
<p><a rel="nofollow" target="_blank" href="http://www.flickr.com/photos/27517504@N05/3654984964/" title="Team 11 hard at work"><img src="http://farm3.static.flickr.com/2463/3654984964_38ee0b897a.jpg" width="500" height="375" alt="Team 11 hard at work"/></a><br />
<br clear="left"/></p>
<p>But that&#8217;s just during the day. At night we work on a group project, in addition to some homework assignments, guest lecturers (we had some great speakers visit), and social events to network with our classmates.</p>
<p>The group project for Mod1 was to come up with a Web 2.0 initiative for a health insurance company, design the product, research and estimate its business value, and prepare a presentation for the class. At the end of the two weeks, we had two things to deliver. First, we had to turn in a complete Zachman framework design of the product. Second, we gave a presentation to our classmates as if they were the Board of Directors of the health insurance company and try to convince them to fund our project.</p>
<p><a rel="nofollow" target="_blank" href="http://www.flickr.com/photos/27517504@N05/3654985016/" title="Team 11 Adil by opensourceconnections, on Flickr"><img src="http://farm3.static.flickr.com/2465/3654985016_4592f0a5c1.jpg" width="500" height="375" alt="Team 11 - Adil standing next to the backlog (behind him)"/></a><br />
<br clear="left"/></p>
<p>I had the pleasure of being on a great team. At the beginning of Mod1, each group had to complete some team building exercises, where we decided what the ground rules for our group would be, what our group and individual goals were, and how we wanted to operate as a group. I found this to be a more valuable experience then I expected, and I plan to use it more often in projects at work.</p>
<p>One important decision that our group made right from the start was to use a lightweight version of <a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/Scrum_(development)">Scrum</a> to organize our team. Our team&#8217;s goals were to be very efficient, and to focus on the quality of our work, not the quantity of time we spent on it. Since two of our team members had previously used Scrum, and a third is a rugby player (Tim), using Scrum was a natural fit.</p>
<p>We ran 1 day sprints over the two weeks. We didn&#8217;t keep a <a rel="nofollow" target="_blank" href="http://www.controlchaos.com/about/burndown.php">burndown</a> chart, since that would be too much overhead. Our planning sessions basically were to update a list on the wall with everything we were going to do that night, and then go around the team and let everyone pick their own tasks until all tasks had been assigned. We didn&#8217;t bother with estimates on those tasks since the granularity of the sprint was already down to just one day.</p>
<p><img style="vertical-align:text-bottom;" src="http://farm4.static.flickr.com/3653/3654184969_822c323686.jpg" alt="Tim running a stand up"/><br />
<br clear="left"/></p>
<p>At our next meeting, we would do a quick stand up to update the team on where we stood on our assigned tasks, and then we usually did a demo of our tasks. This &#8220;lightweight Scrum&#8221; helped keep us very focused on our work and the tasks assigned to each of us. <a rel="nofollow" target="_blank" href="http://www.opensourceconnections.com/2008/10/21/azimuth-treasure-hunt-app-release-the-hounds/">At OpenSource Connections, we did a similar thing for the Rails Rumble last year</a>, which is a 48 hour coding competition. During the Rails Rumble, we would plan sprints of 2 or 3 hours each, at the end of which we would demo our progress to each other. It was lightweight enough to work in a very tight timeframe while still keeping just enough process that we all stayed focused on the job at hand.</p>
<p>The other efficiency thing we did was to <a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/Time_boxing">&#8220;time box&#8221;</a> every discussion we had. Many parts of the group work involved design discussions about what we wanted to do for our projects, debating the pros and cons of it, reviewing each other&#8217;s work, etc. To keep these discussions from going on all night, or wasting our time debating things in detail that might not even end up in the project, we would put a time limit on everything. </p>
<p>Every day we tried to rotate a facilitator role, and that person&#8217;s job was to keep the discussions going smoothly, and they were usually the person who would pipe up with &#8220;how long do we want to spend on this topic?&#8221; We might set a time limit like 15 or 30 minutes, and then Adil would set the timer on his iPhone. When the timer went off, we would cease debate on the topic and try to make a decision. If necessary, we would extend the time, but the goal was always to stay within in a timebox so we wouldn&#8217;t be up all night and could get some rest (or at least head over to the bar!).</p>
<p>We had a lot of different personalities on our team, and lots of different perspectives. But we got along great as a team and I think the agreement on ground rules and the use of Scrum helped out a lot with that.</p>
<p>I think the way we came up with ideas worked pretty well too. We started by encouraging everyone to write any idea they had on yellow post-it notes, and stick it up in one corner of the wall (you can see Adil pointing at the post-it notes in the photo below). It didn&#8217;t matter if it was a good or bad idea, the point was to generate as many as possible and get them on the wall. Similar to the way people propose sessions at an <a rel="nofollow" target="_blank" href="http://www.mindviewinc.com/Conferences/OpenSpaces.html">open spaces conference</a>, each person would read their idea as they posted it to the wall. No criticism or debate was allowed at that point.</p>
<p><a rel="nofollow" target="_blank" href="http://www.flickr.com/photos/27517504@N05/3655040332/" title="Team 11 Brainstorming by opensourceconnections, on Flickr"><img src="http://farm4.static.flickr.com/3407/3655040332_7d1866b437.jpg" width="320" height="240" alt="Team 11 Brainstorming"/></a></p>
<p>The next day we grouped the post-it notes together by ideas that were similar or could be easily combined together into the same project. It was clear that we had a lot of ideas around mash-ups, since that was the largest number of post-it notes. But we didn&#8217;t choose the idea based on quantity.</p>
<p>Arash had drawn a map on one whiteboard of the goals, strategies, and problems at the health insurance company (see pic below), and we began to move the post it notes onto the whiteboard, lining them up with what goals/problems they addressed.</p>
<p><a rel="nofollow" target="_blank" href="http://www.flickr.com/photos/27517504@N05/3654311197/" title="Adil pointing at the project goals map by opensourceconnections, on Flickr"><img src="http://farm3.static.flickr.com/2465/3654311197_8e8f7e60d4.jpg" width="320" height="240" alt="Adil pointing at the project goals map"/></a></p>
<p>At that point we finally started voting on what idea to go with. Everybody picked their 3 favorite ideas, and the three with the most votes were the finalists. We debated those three ideas in more depth, bounced ideas off Prof. Grazioli, and then picked our project idea.</p>
<p>Although it sounds a little complex, I liked this process because it encouraged us to all be creative, to consider all ideas, to map those ideas to the goals of the project, and ultimately to create a consensus around the final idea. I have a tendency to push for my favorite ideas, and this process helped make sure I didn&#8217;t force my ideas on the team, and ensured that we carefully and creatively considered all the ideas.</p>
<p>In the end, our team ended up proposing an incentives program based in part on an iPhone app that would record your exercise and upload that data to the health insurance company, which would then convert that data into &#8220;health points&#8221; for use in contests with fellow employees to encourage healthy lifestyle changes.</p>
<p><a rel="nofollow" target="_blank" href="http://www.flickr.com/photos/27517504@N05/3655112662/" title="Team 11 Project Overview Slide by opensourceconnections, on Flickr"><img src="http://farm4.static.flickr.com/3411/3655112662_d1d13952c4.jpg" width="500" height="409" alt="Team 11 Project Overview Slide"/></a><br />
<br clear="left"/></p>
<p>All the presentations were given on Friday, and the professors split the class into three different classrooms of 4 or 5 teams each (there were 13 teams total). Each team presented to their classroom, and then the room would pick which team should &#8220;advance&#8221; and be one of only three teams to present to the whole class in the afternoon.</p>
<p>Our team was really honored to be picked as one of the final three teams to present to the whole class. It was a lot of fun. I have to also tip my hat to the other two final teams since their presentations were not only excellent, but I was also very impressed with the depth of financial analysis they incorporated. (I&#8217;m looking forward to future modules where I&#8217;ll learn the finance skills to be able to do the same since finance is not my background).</p>
<p><a rel="nofollow" target="_blank" href="http://www.youtube.com/watch?v=ksEu9l28Eus">We kicked off our presentation with a video to illustrate the idea of our product</a>. We had a lot of fun producing it, and I think our classmates enjoyed it too. You&#8217;ll have to pardon the poor resolution - it was my first time using iMovie and a flip camera, and I didn&#8217;t get the conversion right.</p>
<p><iframe class="embeddedvideo" type="application/x-shockwave-flash" width="425" height="344" src="http://www.youtube.com/v/ksEu9l28Eus&amp;hl=en&amp;fs=1&amp;"></iframe></p> 
<p>Just for fun, I also took a few clips from our filming and made an <a rel="nofollow" target="_blank" href="http://www.youtube.com/watch?v=MzCda-BYX8g">&#8220;out takes&#8221; video</a>. We got to show the outtakes to the whole class too after our presentation, which I hope added a little playful humor to the end of Mod1. (<a rel="nofollow" target="_blank" href="http://www.commerce.virginia.edu/newsletter/2009_02/grazioli.html">Prof. Grazioli</a> showed some very funny retrospective slide shows that were the real hit of the afternoon however!)<br />
<iframe class="embeddedvideo" type="application/x-shockwave-flash" width="560" height="340" src="http://www.youtube.com/v/MzCda-BYX8g&amp;hl=en&amp;fs=1&amp;"></iframe></p> 
<p>Mod1 was a great experience. I advanced my IT skills, teamwork and leadership skills, but perhaps most of all made some great friends through the shared experience of great professors, very interesting classmates, and of course sleep deprivation. I&#8217;m looking forward to Mod 2!</p>
<p><em>Team 11 was: Tim Bucher (Booz Allen Hamilton), Adil Qazi (Freddie Mac), Arash Sadati (International Monetary Fund), Arin Sime (OpenSource Connections) and Mark Widener (Virginia Air National Guard).</em></p><img src="http://feeds.feedburner.com/~r/CitconBlogs/~4/ogM-DyRyEAo" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://www.opensourceconnections.com/2009/06/23/using-scrum-on-grad-school-projects/</feedburner:origLink></item>
      <item>
         <title>Improving performance and scalability with DDD</title>
         <link>http://feedproxy.google.com/~r/CitconBlogs/~3/U3AsAvjlyNk/</link>
         <description>Distributed systems are not typically a place where domain driven design is applied. Distributed processing projects often start with an overall architecture vision and an idea about a processing model which basically drives the whole thing, including object design if it exists at all. Elaborate object designs are thought of as something that just gets [...]</description>
         <author>gojko</author>
         <guid isPermaLink="false">http://gojko.net/?p=987</guid>
         <pubDate>Tue, 23 Jun 2009 06:23:12 -0700</pubDate>
         <content:encoded><![CDATA[<p>Distributed systems are not typically a place where domain driven design is applied. Distributed processing projects often start with an overall architecture vision and an idea about a processing model which basically drives the whole thing, including object design if it exists at all. Elaborate object designs are thought of as something that just gets in the way of distribution and performance, so the idea of spending time to apply DDD principles gets rejected in favour of raw throughput and processing power. However, from my experience, some more advanced DDD concepts can significantly improve performance, scalability and throughput of distributed systems when applied correctly. <span id="more-987"></span></p>
<p><i>This is a summary of my presentation titled &#8220;DDD in a distributed world&#8221; at the <a rel="nofollow" target="_blank" href="http://skillsmatter.com/event/design-architecture/ddd-exchange">DDD Exchange 09</a> in London. You can also <a rel="nofollow">download the slides accompanying this presentation</a>.</i></p>
<p>One of the most important building blocks of DDD that can help in distributed systems are aggregates. Unfortunately, at least judging by the discussions that I&#8217;ve had with client teams over the last few years, aggregates seem to be one of the most underrated and underused building blocks of DDD. I&#8217;m probably as guilty as anyone else of misusing aggregates and it took me quite a while to grasp the full potential of that concept. But from this perspective I think that getting aggregates just right is key to making a distributed system work and perform as expected.</p>
<h2>Aggregates are about units of consistency &#8211; not about pointers</h2>
<p>Most folks think about aggregates in terms of pointers, such as that objects outside of an aggregate should only reference an aggregate root and not any objects inside the aggregate. Although very useful in general, this rule is not the whole story of aggregates, but that is where most discussions end. Aggregates are also perceived as very technical in nature, almost something that should be left out of the discussion with business experts, similar to repositories or factories. I think that this is a mistake. Aggregates represent a very clear business domain aspect that should definitely be discussed with domain experts. I found it much more important to focus on the fact that an aggregate is a <i>unit of consistency</i> from a business perspective.</p>
<p>We can look at an aggregate from a business perspective as a units of consistency in our problem domain. Something that in a business sense always needs to be perfectly coordinated and consistent, something that is only complete as a whole. Eric Evans calls this a “meaningful whole”, suggesting that an aggregate itself has a meaning separate from the meaning of its parts. As such, it is a genuine business domain concept, not just a technical guideline about references. And in order to find correct aggregate boundaries we shouldn&#8217;t be concerned that much about referencing code and class encapsulation. This is more an exercise of identifying business requirements for consistency.</p>
<p>From that perspective, aggregates have a clear impact on processing models and implementation of the system. An aggregate is a natural unit of distribution because we probably need all the information in an aggregate to meaningfully process it. Whenever we send information down the wire, the whole aggregate needs to go. It also means that we need to ensure that all changes to a single aggregate are saved correctly as part of a single transaction. Once we have done it, we genuinely have a meaningful piece of work done. This potentially gives us freedom to work on different aggregates in parallel or in separate transactions. </p>
<p>When these forces are aligned, we&#8217;ll get a very nice distributed system design and an implementation that performs nicely. When these forces are in conflict, we should stop and analyse the system instead of just ploughing away with the code. The conflict may come from either the technical or the business perspective but having these concepts explicitly defined gives us a good framework to spot something smelling dirty and fix the problem before it becomes too big. That is why aggregate models provide some great hints about distributed processing. </p>
<h2>Hint #1: If you don&#8217;t aggregate enough, even the fastest computers will spin their wheels in vain</h2>
<p>Latency is one of those classical problems of distributed systems. It is a very elusive concepts that an average programmer just ignores, because it seems as a networking issue that should be solved by networking people. I remember a guy who was building his own messaging solution and proudly boasted about its performance, demonstrating it by running both the server and the clients on his machine. When we deployed it properly and put one system in the UK and another one in the States, the whole thing fell over almost instantly. </p>
<p><img style="width:350px;border:1px solid black;margin:5px 5px 5px 5px;" align="right"/> Think of it this way: to send an page by post you need to find an envelope, put a stamp on that and put it into a post box. There&#8217;s also one less visible step there that most people don&#8217;t take into account – walking out of the house and going to the post box. Walking outside to a post box is where the latency kicks in. It&#8217;s not something people see integral to the process, but it nevertheless exists. Say you wanted to post a contract that has twenty pages. Doing the whole routine for every single page would instinctively feel wrong and no sane person would do that – we would just put all the pages in a large envelope and stick a single stamp on that, then take all that the post box at once. Yet I find people doing the equivalent of posting each page separately in software over and over again, making the system walk to the post box twenty times instead of once and paying for twenty virtual postage stamps. And this is where aggregates start to kick in. The whole twenty page contract is an aggregate and that very fact that is an aggregate should suggest that it should be shipped together. It is a meaningful whole so whoever needs a page probably needs the entire thing.</p>
<p>So I suggest the first rule to help distributed systems with aggregates: <i>Ship entire aggregates straight away to avoid latency</i>.</p>
<h2>Hint #2: If you aggregate too much, baggage becomes a problem</h2>
<p><img style="width:200px;border:1px solid black;margin:5px 5px 5px 5px;" align="left"/> The second classic problem of distributed systems is serialization performance. Serialization and deserialization are often among the biggest performance hogs in a system as they rely on reflection, IO and traversing complicated object graphs. This is again where aggregates can help, but the issue is a bit more subtle. </p>
<p>We need to keep an eye out for conflicts between the intended processing model and the business view of aggregates. For example, in a classic account system with accounts and transaction histories, it seems perfectly logical to have the account history as part of the account aggregate. </p>
<p>Say we wanted to process transactions for an account on different machines. Sending huge object graphs over the wire all the time makes no sense technically, so shipping the whole history when we send the account would kill the system performance. There we have a conflict between a business view of an aggregate. </p>
<p>Instead of just ploughing away with the code and breaking the aggregate apart for this one occasion (which would lead to the corruption of the design eventually), I suggest pausing and thinking a bit more about this conflict. This is a very subtle trap. First of all, there are no universal models and the model along with the aggregate structure only works within a particular set of scenarios, so stuffing the account history to be part of the account aggregate may or may not make sense depending on how we are going to use the accounts. When there is a conflict between the processing model that we wanted to implement and the aggregate model suggested by the business, that might point to better ways to design the system.</p>
<p>The rule that the whole aggregate gets shipped together would make us ship the whole history each time we send out account information and makes absolutely no sense. On the other hand, being able to meaningfully operate on just a few pieces of information conflicts with the business definition of the aggregate. </p>
<p>An option would be that the history is not really be part of the account aggregate – maybe it is just a list of domain events that record what happened, or maybe they form part of another statement aggregate. In that case, the model gives us a real argument to talk to the business about statements being something that can now get updated asynchronously as it is not part of the main account aggregate. This is why you get the correct balance but not all the statements on in internet banking applications. Inserting a new transaction record might require locking the sequence generator or a table in some database systems, so it costs a lot. If the transactions can be asynchronously updated then we can significantly reduce locking and improve the system performance. This model gives us distributed processing but clearly points out that the history is not going to be 100% consistent with the balance all the time. It would require a recognition from the domain experts that the history does not belong to the unit of consistency of an account. </p>
<p>On the other hand, if we don&#8217;t get the confirmation from the business about that, the fact that all of it has to be part of the same aggregate tells us that distributed processing of a single account is not where we want to go. We need to find a different solution, possibly a distributed master-worker with worker machines owning accounts and the master routing tasks to be processed on the appropriate machine. </p>
<p>So the second rule I&#8217;d like to suggest is: <i>If you don&#8217;t need it all, it is probably not an aggregate and you can improve performance with asynchronous updates.</i></p>
<h2>Hint #3: If you don&#8217;t aggregate enough, things are going to be broken just when you need them</h2>
<p><img style="width:350px;border:1px solid black;margin:5px 5px 5px 5px;" align="left"/>This relationship between synchronous atomic updates and aggregates works both ways. Without properly defined aggregate boundaries in the model, we might actually be breaking up transactions into pieces that do not make sense individually. If there are no aggregate boundaries, there is nothing to tell us what actually is a consistent update from a domain perspective and we’ll probably form transactions around requests. This might lead to a lot of unnecessary code to handle technical “edge cases” which aren&#8217;t really business exceptions at all.</p>
<p>For example, a trading system might require customer&#8217;s credit card details for any meaningful operation. Because of web design constraints, the registration process for customers on the web site might be divided into several steps, where they would first fill in the personal details and then put in the payment details on a separate screen. </p>
<p>If we don&#8217;t capture the fact that the payment information are actually part of the customer aggregate then the normal way to implement this would be to form the transactions around requests – posting after each screen. That would allow the system to create customers with no payment information (when they close the browser or just don&#8217;t complete the registration). These strange cases will start popping up in reports and we&#8217;d have to implement workflows to handle these customers, preventing them from accessing functionality that requires payments etc. </p>
<p>If we do consider both parts a single aggregate, the rule that we should ship entire aggregates (even from the web site to create the customer account), leads to the conclusion that the data should be collected from both screens first and sent at once, instead of sent after each individual screen and processed in the database. </p>
<p>Because aggregates are units of consistency, in order for them to stay consistent we need to keep all steps in an update of an aggregate together. Aggregate updates need to obey the samurai principle: either return successfully or not return at all. Without this, we are opening the doors for data corruption &#8211; not in the disk failure sense but in the business sense. The technical edge cases that don&#8217;t exist in the business simply go away, so we don&#8217;t have to handle them or maintain code to work around them. </p>
<p>Atomicity of transactions fits into aggregates really nicely and this is where transactions also come in. If we think of aggregates as units of consistency, that allows us to design the transactions in our system to work on a single machine as we can ensure that all the information that should be processed synchronously within a transaction resides in a single place. Aggregates are natural atomic parts of transactions.</p>
<p>The third rule I suggest for improving distributed systems is: <i>We should form our transactions around business units of consistency rather than technical requests to avoid data corruption and simplify processing.</i> The entire aggregate should be processed synchronously within a transaction. </p>
<h2>Hint #4: If you aggregate the wrong things, deadlocks galore</h2>
<p><img style="width:350px;border:1px solid black;margin:5px 5px 5px 5px;" align="right"/> Locking resources in distributed systems is also one of those invisible issues that can just kill you if you don&#8217;t get it right. Distributed systems are typically built to process more than a single machine can – to increase the overall system throughput. Yet if critical resources are locked too much and processes often have to wait for other processes to release those locks, spanning to multiple machines might actually give you worse performance. </p>
<p>One example that we had in <a rel="nofollow" target="_blank" href="http://skillsmatter.com/course/design-architecture/domain-model">a recent DDD Immersion workshop</a>, changed a bit to protect the innocent, is a scheduling system that involves event organisers and events. The unit of consistency in a business sense was an event organiser, so that was the aggregate by design. At some point, the system was integrated with an external notification source with messages about changes to events. A message might contain updates for hundreds of events for different organisers, postponing, rescheduling etc. The business wanted a notification message to be processed within a single transaction, regardless of what it contains. After the change, the system performance seriously deteriorated as a single notification message was locking hundreds of organiser objects. </p>
<p><img style="width:350px;border:1px solid black;margin:5px 5px 5px 5px;" align="right"/> </p>
<p>This is another example of the processing model conflicting with the business model of aggregates. If the organiser and its events are units of consistency, then we should be able to update one organiser entirely and not update the others and the system would still be consistent. If this is confirmed by the business (which is more likely than not), then we have a good case against the requirement to process the entire message in a single transaction. We can take the message, store it and commit, then break it apart into chunks related to individual organisers in another transaction and commit that, and then process individual chunks in separate transactions. This model also allows us to process individual organisers in parallel so the business will probably see the final effect sooner than with a single transaction anyway. </p>
<p>The fourth rule coming out of this is : <i>When locking, lock aggregate roots. Challenge requests to lock more than one at the same time.</i> </p>
<h2>Reinforcing ideas</h2>
<p>Aggregates are a curious pattern as they clearly have both a business domain and a technical side. These two sides of aggregates confirm and reinforce each-other. That is what makes them so useful for modelling and designing distributed systems. Once we know what makes a conceptual unit of consistency, we have defined the clusters that need to travel down the wire or be processed as a single unit. If the required processing model contradicts that, then we need to revisit the aggregate definitions or the processing model.</p>
<p>Once we draw the lines of the aggregates and think of them primarily as units of consistency we can have a meaningful discussion on what implementation model suits our required set of scenarios. Aggregates are natural choices for some of the most tricky issues of distributed systems, including locks, transactions, asynchronous processing, serialization and latency. </p>
<p>If we want one but not the other that probably means that we don&#8217;t have the correct aggregates boundary, or that we have unrealistic expectations. And spotting this early on is one of the greatest powers of aggregates as a concept – we don&#8217;t have to burn our fingers by spending months developing something that simply is not going to perform or satisfy requirements. </p>
<p><i>I took notes during other presentations and will post them soon. See <a rel="nofollow">earlier DDD exchange posts</a> and subscribe to the <a rel="nofollow">RSS feed</a> to get notified when the new ones come online.</i></p><img src="http://feeds.feedburner.com/~r/CitconBlogs/~4/U3AsAvjlyNk" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://gojko.net/2009/06/23/improving-performance-and-scalability-with-ddd/</feedburner:origLink></item>
      <item>
         <title>Flux2 competition: not your average CSS editor</title>
         <link>http://feedproxy.google.com/~r/CitconBlogs/~3/62sATJhlY_M/</link>
         <description>Last night I got a twitter message from mac stories, telling me about their contest win a Flux license. Normally I don&amp;#8217;t go for this kind of stuff. But something must have triggered me. Probably the fact that I have to create a website for our bed and breakfast with some non trial css involved.
I [...]</description>
         <author>Patrick Debois</author>
         <guid isPermaLink="false">http://www.jedi.be/blog/?p=755</guid>
         <pubDate>Tue, 23 Jun 2009 00:24:43 -0700</pubDate>
         <content:encoded><![CDATA[<p>Last night I got a twitter message from mac stories, telling me <a rel="nofollow" target="_blank" href="http://www.macstories.net/news/giveaway-contest-win-5-copies-of-flux/">about their contest win a Flux license</a>. Normally I don&#8217;t go for this kind of stuff. But something must have triggered me. Probably the fact that I have to create a website for our <a rel="nofollow" target="_blank" href="http://www.buitengewooon.be">bed and breakfast</a> with some non trial css involved.</p>
<p>I downloaded <a rel="nofollow" target="_blank" href="http://www.theescapers.com/flux2/index.html">flux2/beta</a> from <a rel="nofollow" target="_blank" href="http://theescapers.com/">http://theescapers.com/</a> and I must say, nice toolset. It has a very developed plugin set, including roundcorners, jquery, mootools and can also be used for rails developments.</p>
<p>So to summarize: it looks every bit promising, so why not enter the competition. Here&#8217;s how I see it:</p>
<p><a rel="nofollow" target="_blank" href="http://www.jedi.be/blog/wp-content/uploads/2009/06/flux-flatline.png"><img class="aligncenter size-full wp-image-756" title="flux-flatline" src="http://www.jedi.be/blog/wp-content/uploads/2009/06/flux-flatline.png" alt="flux-flatline Flux2 competition: not your average CSS editor" width="500" height="265"/></a></p>
<p class="addtoany_share_save_container"> <a rel="nofollow" class="a2a_dd addtoany_share_save" target="_blank" href="http://www.addtoany.com/share_save?sitename=JEDI%3A%20Just%20Enough%20Developed%20Infrastructure&amp;siteurl=http%3A%2F%2Fwww.jedi.be%2Fblog%2F&amp;linkname=Flux2%20competition%3A%20not%20your%20average%20CSS%20editor&amp;linkurl=http%3A%2F%2Fwww.jedi.be%2Fblog%2F2009%2F06%2F23%2Fflux2-competition-not-your-average-css-editor%2F"><img src="http://www.jedi.be/blog/wp-content/plugins/add-to-any/share_save_120_16.gif" width="120" height="16" alt="Share/Save/Bookmark"/></a> </p><img src="http://feeds.feedburner.com/~r/CitconBlogs/~4/62sATJhlY_M" height="1" width="1"/>]]></content:encoded>
      <feedburner:origLink>http://feedproxy.google.com/~r/jedi/IZwx/~3/05IMijcYs88/</feedburner:origLink></item>
   </channel>
</rss><!-- fe3.pipes.re3.yahoo.com uncompressed Fri Jul 10 00:07:29 PDT 2009 -->
