<?xml version="1.0" encoding="iso-8859-1"?>



<rdf:RDF
  xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
  xmlns:admin="http://webns.net/mvcb/"
  xmlns:cc="http://web.resource.org/cc/"
  xmlns="http://purl.org/rss/1.0/">

<channel rdf:about="http://blogs.codehaus.org/people/tirsen/">
<title>jutopia</title>
<link>http://blogs.codehaus.org/people/tirsen/</link>
<description></description>
<dc:language>en-us</dc:language>
<dc:creator></dc:creator>
<dc:date>2005-08-19T06:31:41+00:00</dc:date>
<admin:generatorAgent rdf:resource="http://www.movabletype.org/?v=2.661" />


<items>
<rdf:Seq><rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/001159_joel_is_misunderstanding_xp_and_bduf.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/001155_continuous_integration_with_javascript.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/001154_designs_for_remote_calls_in_ajax.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/001147_superb_presentation_about_dependency_injection.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/001129_london_blasts_im_alive_and_well.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/001125_back_in_london_and_then_sweden.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/001069_tiger_dashboard_widgets_are_just_dhtml.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/001051_git_new_scm_for_the_linux_kernel.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/001049_turning_pages_in_the_iht_website.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/001047_railsfastcgi_vs_j2ee_scaling_take_2.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/001041_ruby_on_rails_and_fastcgi_scaling_using_processes_instead_of_threads.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/001030_i_have_a_life.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000980_ejb_3_interceptors_finally_or.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000979_undo_in_aspectj_revisited.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000960_rich_web_applications.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000896_re_where_to_put_config_files.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000882_managing_test_data_for_functional_tests.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000867_intellij_uses_picocontainer.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000865_how_to_build_maintainable_systems_simple_design.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000859_data_transfer_objects_makes_me_sick.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000748_aop_is_not_just_descatter_detangle.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000747_best_aop_explanation_ever.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000723_i_have_many_alter_egos.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000706_why_i_still_wont_do_ejb.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000690_undo_in_aspectj.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000669_xml_deprecates_binary_packages_in_tcp.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000647_groovy_and_ruby.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000618_confluence_rocks.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000617_happy_birthday_codehaus.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000614_subversion_10_released.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000606_jetbrains_resharper.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000604_a_lesson_about_simplicity.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000595_prevayler_finalist_in_jolt_awards.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000582_tdd_is_about_testing.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000562_using_ruby_to_build_java_systems.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000560_dependency_injection_is_the_first_step_to_a_unified_standard_for_lightweight_containers.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000552_codeguide_debugger_has_step_back.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000550_picocontainer_presentation_from_javapolis_now_also_in_japanese.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000542_dont_be_sad_chiara.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000535_my_humble_predictions_for_2004.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000531_happy_new_year.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000189_hausparty_first_annual_codehaus_conference_in_amsterdam_this_weekend.html" />
<rdf:li rdf:resource="http://blogs.codehaus.org/people/tirsen/archives/000129_new_jutopia.html" />
</rdf:Seq>
</items>

</channel>

<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/001159_joel_is_misunderstanding_xp_and_bduf.html">
<title>Joel is misunderstanding XP and BDUF</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/001159_joel_is_misunderstanding_xp_and_bduf.html</link>
<description><![CDATA[<p>Joel is writing about <a href="http://www.joelonsoftware.com/articles/AardvarkSpec.html">how much he likes BDUF</a> and in doing so reveals exactly how little he understands of XP and what XP-practitioners refer to as Big Up Front Design or in short BDUF.</p>

<p>Downloading and reading through the linked PDF which is the specification for his Project Aardvark or Copilot reveals a functional specification which is a perfectly sound document to have in a "true" XP project. At <a href="http://www.thoughtworks.com">ThoughtWorks</a> very few projects start without a document of at least the same magnitude (disregarding maybe from some smaller details). We split it up into stories, estimate and rate them and run it through some clever Excel spreadsheet employing various statistical analysis. Out comes a pretty good estimate of how long the projects going to take and what it's going to cost. We call it inception and it's a perfectly "acceptable" thing to do at an XP project.</p>

<p>It is the next step after that in a typical waterfall project that we skip and go straight to development. This step is what we refer to as BDUF. Here fancy "designers" and "architects" go through the functional specifications and using various CASE tools start designing every single component in the system. Down to each class and method. This is what we call Big Design Up Front and Joel, honestly, not even you would be so crazy to do that.</p>

<p>We wouldn't say you're doing BDUF Joel, you're doing EDUF, Enough Design Up Front. We XPers like to do that too.</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2005-08-19T06:31:41+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/001155_continuous_integration_with_javascript.html">
<title>Continuous Integration with JavaScript</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/001155_continuous_integration_with_javascript.html</link>
<description><![CDATA[<p>
It was when I for the umptenth time broke another unit test in <a href="http://script.aculo.us">script.aculo.us</a> that I decided that it just had to be enough! We need continuous integration for these buggered <a href="http://mir.aculo.us/articles/2005/08/03/more-automatic-testing-with-javascript">JavaScript unit tests</a>.
</p>

<p>
<a href="http://www.martinfowler.com/articles/rake.html">Rake</a> to the rescue!
</p>

<p>
After some hacking around on <a href="http://www.mekongmart.com/images/SydneyHarbour03.jpg">the ferry to work</a> I had the solution!
<pre>
desc "Runs all the JavaScript unit tests and collects the results"
JavaScriptTestTask.new(:unittest) do |t|
  t.mount("/lib")
  t.mount("/src")
  t.mount("/test")
  
  t.run("/test/unit/unittest_test.html")
  t.run("/test/unit/ajax_inplaceeditor_test.html")
  t.run("/test/unit/string_test.html")
  t.run("/test/unit/builder_test.html")
  
  t.browser(:safari)
  t.browser(:firefox)
end
</pre>
</p>

<p>
This will start a <a href="http://www.webrick.org/">WEBRick server</a> with the specified files mounted, run all the combinations of browsers and tests and report back the results:

<pre>
beatrix:~/Projects/rails/spinoffs/scriptaculous tirsen$ rake unittest
(in /Users/tirsen/Projects/rails/spinoffs/scriptaculous)
/test/unit/unittest_test.html on Safari: FAILURE
/test/unit/ajax_inplaceeditor_test.html on Safari: ERROR
/test/unit/string_test.html on Safari: SUCCESS
/test/unit/builder_test.html on Safari: FAILURE
/test/unit/unittest_test.html on Firefox: SUCCESS
/test/unit/ajax_inplaceeditor_test.html on Firefox: SUCCESS
/test/unit/string_test.html on Firefox: SUCCESS
/test/unit/builder_test.html on Firefox: SUCCESS
</pre>
</p>

<p>
Coming to a script.aculo.us SVN repository near you soon!
</p>

<p>
(Caveat: Only works on the Mac at the moment. Maybe it's time to <a href="http://www.apple.com/switch/">switch</a> like the rest of the world.)
</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2005-08-18T04:14:00+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/001154_designs_for_remote_calls_in_ajax.html">
<title>Designs for remote calls in Ajax</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/001154_designs_for_remote_calls_in_ajax.html</link>
<description><![CDATA[<p>
I’m pleased with how the best practices of doing remoting are emerging in Ajax. Most Ajax libraries have ditched the RPC approach to remoting and are instead using a very specialized form of distributed computing.
</p>

<p>
Please allow me to explain…
</p>

<p>
<b>Simple call, simple return</b>
The simplest form of remote interchange in Ajax can be seen in for example the in place editor of photo titles and descriptions at Flickr (here's a demo of <a href="http://wiki.script.aculo.us/scriptaculous/show/Ajax.InPlaceEditor">an upcoming control</a> in script.aculo.us that implements this, be warned though it still very much pre-release quality). It’s a simple REST style call, a url is constructed with the updated title or description as a simple parameter. Any return value is sent verbatim in the body of the response and used directly by the JavaScript code in the browser. This can be compared to an ordinary RPC call.
</p>

<p>
<b>Simple call, snippet returned</b>
The next step in complexity is when a more complex value needs to be returned (like as a list of values or multiple named values). An example of this is the script.aculo.us <a href="http://script.aculo.us/demos/ajax/autocompleter">auto completing text fields</a>. The text is once again sent in simple REST style with the parameters encoded in the URL. The result of the call is where the interesting bits come in, instead of returning a serialized data structure that needs unmarshalling and interpretation on the client side the server simply returns the HTML snippet of the result pane. All the client needs to do is use the browsers built in HTML parser (the result is in fact already parsed by the XmlHttpRequest) and update the DOM of the result pane. The remote call is completely adapted to the client, which is almost the opposite of CORBA-style remoting or web services where the remote interface is supposed to be completely generic and it is the client responsibility to figure out how to handle the result.
</p>

<p>
<b>Simple call, behaviour returned</b>
The last approach is even more interesting (and could be called agent oriented by the widest stretch of the definition). It’s used a little bit by Gmail and is implemented by the <a href="http://api.rubyonrails.com/classes/ActionView/Helpers/JavaScriptHelper.html#M000400">evaluate_remote_response </a> in Ruby on Rails. This technique also encodes arguments as URL query parameters but the result at this time is neither a simple value nor an HTML snippet, it is a JavaScript snippet which is directly evaluated by the client! The server can return any number of HTML snippets, execute graphical effects, update different cells in a table, navigate to a different page and so on.
</p>

<p>
<b>Is this good?</b>
I can hear some of you protest: “But the client becomes tightly coupled to the server! This is horrendous!” A lot of people feel that there are compelling reasons to make an abstraction layer along the same lines as the distribution layer.
</p>

<p>
There are reasons to do this, but personally I don’t buy it; the only way to effectively handle a distribution boundary is by specifically designing both sides of the boundary to accommodate to each other. Ultimately designing the remote interface directly according to how the user will interact with the application. One single user transaction may span several conceptual transactions with the system, in a traditional RPC-style remoting design this would mean multiple remote calls which is quite ineffective. In Ajax it would be one single call using one of the three methods as described above. Much more effective.
</p>

<p>
Another reason for making the remote interface generic and system-driven (as opposed to user-driven) is because in a traditional client/server scenario there’s much less control of the client. The server may for example need to support multiple versions of the client or different clients at the same time. This is not the case in an Ajax-enabled web application, the server has a pretty strong control over the client. The browser does cache some stuff (according to specification by the server) but nothing is ever installed on the client. There is only ever one version of the client and when the server gets upgraded so does the client.
</p>

<p>
Finally remember that this is not about integrating two different systems, it’s one single system with a distribution boundary in the middle. If we're talking system-to-system integration then CORBA, EJBs, web services, messaging, SOA or whatever's the latest trend are all valid candidates.
</p>

<p>
The approach used by many Ajax applications also means that a lot more of the presentation logic executes at the server. Paradoxically this stems from the fact that web applications in the end actually don't have very strong control of the client. There are a lot of differences between different browsers and in terms of security the server can never depend on something getting executed in the browser. Instead the best practice seems to be to delegate a lot of the logic to the server that returns pre-baked responses that require very little logic to handle on the client.
</p>

<p>
The end result is that many Ajax applications has an extremely tight collaboration between client and server, so tight that the distribution boundary is in fact conceptually blurred and the conceptual presentation layer could be said to run both on the server and the client. Or in other words...
</p>

<blockquote>
The conceptual division between presentation logic and business logic does not coincide with the physical separation of client and server.
</blockquote>

<p>
<b>So are Ajax developers guru software designers for coming up with this?</b>
I don’t think most Ajax developers are aware of all this. The good ones are simply pragmatic programmers that are more focused on the user experience than theoretical mumbo-jumbo like this article (which kinda explains why PHP could've ever been so popular, the horrible language that it is). So the special approach to remoting that is used in many Ajax applications has developed in a much more pragmatic (and I would say healthier) fashion than with for example CORBA or Web services. If you permit me to interpret and extrapolate this a little bit then I would even say that this could mean that Ajax web applications may soon become a very serious competitor to desktop applications. The best practices and frameworks in the "AJAX community" is simply better positioned to delivering compelling applications instead of complying to various pretty theoretical dogmas.
</p>

<p>
So, well, I’m pretty pleased about it…
</p>

<p>
<b>Post scriptum: What about more complex calls?</b>
All these designs use a simple REST style call from the client, which only allows for simple values or name/value encoded pairs. I have yet to observe a more complex call from the client "in the wild". There's the <a href="http://wiki.script.aculo.us/scriptaculous/show/SortableListsDemo">drag-and-drop list reordering</a> callback in script.aculo.us which is essentially a list of ids but it's still pretty simple. If anyone has a good example of a more complex call I'd love to hear about it!
</p>

<p>
<b>Post scriptum 2</b>
Sorry for mainly using examples from script.aculo.us, it's simply the Ajax framework I know best.
</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2005-08-16T06:37:05+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/001147_superb_presentation_about_dependency_injection.html">
<title>Superb presentation about dependency injection</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/001147_superb_presentation_about_dependency_injection.html</link>
<description><![CDATA[<p>From Jim Weirich (the maker of Rake, make for Ruby) comes an excellent presentation of dependency injection and whether it's needed in Ruby:</p>

<p><a href="http://www.onestepback.org/articles/depinj/index.html">http://www.onestepback.org/articles/depinj/index.html</a></p>

<p>I just love when a technology or pattern grows up, passes the buzz stage and you can really get a grip on what it's about and what to use it for.</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2005-08-07T09:46:04+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/001129_london_blasts_im_alive_and_well.html">
<title>London blasts: I&apos;m alive and well</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/001129_london_blasts_im_alive_and_well.html</link>
<description><![CDATA[<p>Readers of my blog might be interested in knowing I'm alive and well. I was in London a few days ago but I'm currently in the safety of Stockholm.</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2005-07-08T10:21:34+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/001125_back_in_london_and_then_sweden.html">
<title>Back in London and then Sweden</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/001125_back_in_london_and_then_sweden.html</link>
<description><![CDATA[<p>Tomorrow I'm leaving wintry Sydney (ok, it's winter but it's like a swedish summer) and heading to other side of the planet for a couple of weeks. I'm going to be in London from Friday the 1st of July to the Monday after. After that I'm going to Stockholm but will visit various places all over Scandinavia. Definitely Norway to hang out with Aslak and probably also Copenhagen (just because it's such a nice city). I'm heading back to Sydney early August.</p>

<p>Send me an email if you want to meet up and have a beer and talk Java, open source, agile, Ruby on Rails or whatever...</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2005-06-29T05:28:46+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/001069_tiger_dashboard_widgets_are_just_dhtml.html">
<title>Tiger Dashboard widgets are just DHTML</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/001069_tiger_dashboard_widgets_are_just_dhtml.html</link>
<description><![CDATA[<p>As any other Mac owner I'm eagerly awaiting Tiger. While waiting I've been catching up on some of the latest technologies. For example, I've been reading this Dashboard Programming guide:</p>

<p><a href="http://developer.apple.com/documentation/AppleApplications/Conceptual/Dashboard_Tutorial/">http://developer.apple.com/documentation/AppleApplications/Conceptual/Dashboard_Tutorial/</a></p>

<p>I knew that there were some HTML involved in Dashboard but I didn't realize to what extent. Dashboard widgets are pretty much only DHTML (HTML+CSS+JavaScript) where the Dashboard infrastructure is just some extra APIs added to a <code>window.widget
</code>
 object!</p>

<p>I wonder when you can build full DTHML applications that look exactly like native Mac OS X apps...?</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2005-05-02T23:18:52+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/001051_git_new_scm_for_the_linux_kernel.html">
<title>Git new SCM for the Linux kernel</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/001051_git_new_scm_for_the_linux_kernel.html</link>
<description><![CDATA[<p>Linus seems to have not chosen any of the established change-oriented SCMs (Arch, Monotone, Darcs) and have instead chosen to implement his own: Git.</p>

<p>Does anyone know more about this Git? Would it be suitable to use for projects other than the Linux kernel?</p>

<p>I can't even find any documentation for it...</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2005-04-22T06:23:04+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/001049_turning_pages_in_the_iht_website.html">
<title>Turning pages in the IHT website</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/001049_turning_pages_in_the_iht_website.html</link>
<description><![CDATA[<p>While reading my usual MacOS rumour sites this morning I came on to <a href="http://www.iht.com/articles/2005/04/10/news/letter.html">this article about Bush and his iPod</a>. While the article itself isn't very interesting I did get very impressed about the "Ajaxish" (sorry about the buzzword drop here, it's just the best way to describe it) way of turning pages. If your mouse hovers over the right hand side the "Next page" widget lights up, if you click the next page comes up without refreshing the whole browser. If you hover over the left side the same goes for turning to the previous page.</p>

<p>Very nice! Anyone know how this holds up accessibility wise?</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2005-04-18T05:07:43+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/001047_railsfastcgi_vs_j2ee_scaling_take_2.html">
<title>Rails/FastCGI vs. J2EE scaling, take 2</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/001047_railsfastcgi_vs_j2ee_scaling_take_2.html</link>
<description><![CDATA[<p><p><br />
By popular demand, I present to you the follow-up to my extensively slaughtered last blog post. This time I'll try something new; balanced analysis! ;-) <br />
</p></p>

<p><p><br />
Just a disclaimer to start off, I have extensive experience designing, developing and maintaining J2EE based systems but I have no practical in-production experience with FastCGI whatsoever (apart from my own dabbing around with various internal ThoughtWorks stuff). Yeah, yeah, call me a kid that's too young to remember and blah blah. (Yes, I'm looking at you Jason.) ;-)<br />
</p></p>

<p><p><br />
Without further ado, these are the various issues that I see with <em>both</em> solutions to the scalability problem (jumbled together with latency and perceived speed, but hopefully you'll get my point):<br />
</p></p>

<p><p><br />
<h3>Sharing data between processes</h3><br />
Both J2EE and FastCGI share this problem; J2EE applications that needs to scale is usually deployed to a cluster with multiple processes on multiple machines and FastCGI of course is always running in multiple processes. There are two solutions to the problem, implement session affinity so that all requests in a session always ends up at the same process, or implement a way of sharing session data using some form of intra-process communication. Doing the latter is actually so easy and well-understood nowadays (both in J2EE and FastCGI) that session affinity is rarely needed (session affinity also has a availability. The main strategies is to use shared in-memory storage (memcached in Rails land), session replication (JBoss uses JavaGroups for this), storing the session state in a database (both Rails and J2EE can do this) or on the filesystem (this is the default out-of-the-box behavior of Rails). Storing session state on the filesystem is a simple solution that actually works amazingly well, distributed filesystems with good enough performance is very easy to set up and use in all environments nowadays. As load increases it's probably worth investigating the other options.<br />
</p></p>

<p><p><br />
<h3>Cost of running multiple processes on the same node</h3><br />
Processes are more expensive than threads because of the cost of maintaining an extra heap and other kernel resources. That said, most modern operative systems have highly optimized process management, Linux can for example easily run thousands of processes on well-speced hardware and with the new scheduler in 2.6 the limit should be even higher. I'm not completely up-to-date with this but the JVM used to fall over after a couple of hundred threads. Also, the standard solution to the problem of limiting multi-threading issues is to limit the number of objects shared between threads, thus the benefits of just having one single heap is slightly limited.<br />
</p></p>

<p><p><br />
<h3>Simplicity of programming models</h3><br />
FastCGI has a simpler programming model as each request is processed completely separated from other requests going on at the same time. This may not be a big difference to application developers but it does makes a huge difference to the framework code in Rails. I've <a href="http://blogs.codehaus.org/people/tirsen/archives/000865_how_to_build_maintainable_systems_simple_design.html">discussed simplicity before</a> (it is one of my favorite subjects) and it should mean that if this simplicity is harnessed a framework based on FastCGI can be easier to maintain, stabilizes faster, could get more committers and have features added to it in a more rapid pace. Of course, simplicity is an elusive thing and if the Rails developers does too many design mistakes then they might not be able to reap the rewards. Complexity always lures around the corner, ready to attack when you least suspect it. Personally I have quite a lot of confidence in the Rails developers: The introduction of Ajax to Rails was one of the cross-roads where complexity could have started to cripple the entire framework but the implementation is such a wonderful showcase of <a href="http://prototype.conio.net/">elegance</a> and <a href="http://rails.rubyonrails.com/classes/ActionView/Helpers/JavascriptHelper.html">simplicity</a> (where as <a href="http://wiki.rubyonrails.com/rails/show/IntegrationWithOrbjsonWish">my own design</a> quite frankly... ehm... sucked...).<br />
</p></p>

<p><p><br />
<h3>Multi-threading safe objects</h3><br />
J2EE's multi-threaded design requires shared objects to be designed and implemented with multi-threading in mind. Again, this may or may not be a problem for application developers; in Struts for example the action instances are shared by multiple threads where as in WebWork each request gets its own instance. It does make a big difference to the framework though. A lot of the objects that are shared by multiple threads are in the framework and this is tricky indeed to get exactly right. Just an example of this: We did a minor upgrade of Jetty on a system I maintained some years ago. Everything seemed to work fine but blew up completely on some machines in our server farm. Eventually we tracked it to that the version of Jetty we upgraded to didn't function properly on a multi-processor machine. Granted, our QA process was lacking as we didn't do regression testing on the same hardware as we had in our server farm but this was a small shop that just couldn't afford this.<br />
</p></p>

<p><p><br />
<h3>Cost of intra-process communication between webserver and FastCGI process</h3><br />
This extra cost is limited if the webserver and FastCGI process are running on the same machine, most operative systems has highly optimized IPC solutions. If they are deployed to two physical node, which is the case in a FastCGI cluster, then there is certainly an extra cost which can give high latency. Most J2EE applications (particularly enterprise ones) are deployed in a double firewall architecture where the J2EE application server and the webserver resides on two different machines. In this case the J2EE solution also suffers from this problem.<br />
</p></p>

<p><p><br />
<h3>One database connection allocated to each FastCGI process</h3><br />
For each FastCGI process you need to allocate one connection and this connection is open for the entire lifetime of the process. When using connection pools in a multi-threaded process the connection is only allocated during actual transactions with the database. This could potentially limit how far you can scale a FastCGI architecture although how high this limit is is very hard to say as it depends on the type of load your application have, what type of database and so forth. (Remember that many databases can also be clustered to handle a large amount of connections.) Also, it is best practice when using for example Hibernate to allocate a connection early in a requests lifecycle and keep it to the end, so this problem could show up in a Java application too. Also to note is that one of Rails caching strategies is to generate static HTML to the filesystem and then let the webserver deliver it, this means that a FastCGI process isn't used for that request at all. How applicable this caching strategy is depends very much on your application. On some applications (blogging engines and content management systems for example) this can be used extensively where as on other applications (internet banks for example) it cannot be used at all.<br />
</p></p>

<p><p><br />
<h3>Summary</h3><br />
Do I dare a summary or will I get shredded to pieces in blogsphere? Well, I suppose I'll get abuse anyway so I'll just give it a go: Both FastCGI and J2EE have both been proven to scale in production through many years and are both very well understood. They should both be considered low risk. Where FastCGI has a simpler programming model J2EE seems to possibly have lower latency and a higher theoretical limit to what dimensions it will scale to (although where this limit is is hard to tell). <br />
</p></p>

<p><p>Both FastCGI and J2EE are good solutions to the scalability problem.</p></p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2005-04-15T07:20:59+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/001041_ruby_on_rails_and_fastcgi_scaling_using_processes_instead_of_threads.html">
<title>Ruby on Rails and FastCGI: Scaling using processes instead of threads</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/001041_ruby_on_rails_and_fastcgi_scaling_using_processes_instead_of_threads.html</link>
<description><![CDATA[<p>There's a lot of buzz around the Ruby on Rails framework at the moment. Something that doesn't get a lot of attention is it's scalability solution: FastCGI. Partly because it doesn't seem very exciting on first glance and partly because it's so fundamentally different to how "enterprise systems" have traditionally scaled. I think Java developers in particular should invest some time in understanding FastCGI.</p>

<p>A Java virtual machine is extremely expensive to start. When started it occupies huge amounts of memory and system resources. This property of the Java platform has led us down the path of scaling using one single virtual machine per physical machine.</p>

<p>One way of doing this is to use some form of non-blocking event-driven architecture and have a fixed small number of threads (typically one per CPU). Each thread handles a number of requests at the same time, as one request waits for IO it moves on and processes another request. This is a complicated (but interesting) way of building systems and not very well suited for non-senior developers. Most enterprise software projects have a large portion of junior or mid-level developers so this is not really a practical way of scaling the Java architecture for enterprise systems.</p>

<p>The other way of scaling this is with a larger number of threads, each thread processing only one request at a time. As one request waits on some form of IO operation the thread blocks and dispatches to another thread. This approach is much easier to develop in and it has been shown to if not scale as well as the non-blocking IO solution it can still scale pretty well. (Take a look at for example the mixed-threading model of JRockit, where a lot of IO optimizations are done on the virtual machine level.)</p>

<p>Another interesting issue is how expensive resources are handled (typically database connections). In a one-VM solution they are pre-allocated in pools so that the cost of allocating one doesn't get incurred on each request. As a request is completed it's very important to return the connection to the pool so it is available to other requests. Another complication is that the heap is shared by multiple threads and all shared objects needs to be built for multi-threading safety. Designing and implementing multi-threading safe objects that doesn't deadlock and have a high throughput is extremely hard. Because of this complexity the traditional solution has been to simply dodge the issue and minimize the amount of objects that are used by multiple threads at the same time. Those objects that are used by multiple threads have little or no state. This effectively solves the problem, but minimizes the benefits of having a shared heap. Because many systems are clustered on multiple physical nodes the shared heap can not even be used as a means of inter-process communication.</p>

<p>These are all interesting characteristics of the typical enterprise software architecture. We've slowly learnt to deal with them and have built up a toolbox of quite effective tools around them (J2EE being one of them).</p>

<p>Ruby on Rails and FastCGI scales in a <i>completely</i> different way.</p>

<p>FastCGI is an extension to the old and ultra-simple CGI architecture which to put it bluntly doesn't scale one single bit. For each request a CGI implementation will fork off a new process containing the application code with a bunch of environment variables telling the application what to do, it will capture the output of the process and send it back to the web client. Starting a new process is usually a very expensive operation (depending on operative system and what type of process and so on) and no resources can be kept alive between requests so database connections and so on will all have to be reallocated on each request.</p>

<p>In contrast, a FastCGI implementation will on startup pre-fork off a number of CGI processes. Each process will listen to standard input (or any other IPC solution such as named pipes, domain sockets or even network sockets in case of a cluster). As a request comes in an available process is chosen and the content of the request is sent as name-value pairs to the process. The FastCGI implementation captures the output and sends it back to the client. The process is then returned back to the pool of available processes.</p>

<p>This means that each process can pre-allocate one single database connection (for each database that it talks to). There are no issues of multi-threading as each process processes only one request at a time. No objects needs to be written to handle multi-threading, as there is just one single thread per process. Expensive resources doesn't need to be allocated in pools and application code doesn't need to return the resources once done with them. Complicated non-blocking IO solutions or muxer/demuxer architectures doesn't need to be used. You can even allocate FastCGI processes on multiple physical nodes, effectively implementing a cluster. In high-security situations a double-firewall security architecture can be set up so that the web-server is protected by one and the back-end FastCGI servers are protected by an additional one.</p>

<p>There seems to be some indications that FastCGI scales at least as well as the typical application server architecture. If this is the case then it's great news. Dealing with the complexities of a multi-thread/one-process system are very expensive. In practice the real performance and scaleability from FastCGI applications might be even higher as the much easier development model decreases the risk for programmer errors.</p>

<p>Java 5 seems to have done some clever optimizations on some platforms for starting up additional virtual machines (you pay up front for the first one, the rest is very cheap). Maybe it's time we try this stuff out in Java too?</p>

<p>For more information:<br />
<li> <a href="http://www.fastcgi.com/">http://www.fastcgi.com/</a><br />
<li> <a href="http://www.fastcgi.com/devkit/doc/fcgi-perf.htm">http://www.fastcgi.com/devkit/doc/fcgi-perf.htm</a><br />
<li> <a href="http://cryp.to/publications/fastcgi/">http://cryp.to/publications/fastcgi/</a><br />
<li> <a href="http://www.google.com/search?q=fastcgi">...and much more.</a></p>

<p><b>Update 1:</b> I may come off as bashing the multi-threading solution here, which really wasn't my intent. I am intrigued by the simplicity of scaling with processes and am curious as to whether this will actually work.</p>

<p><b>Update 2:</b> Cameron Purdy <a href="http://www.jroller.com/page/cpurdy/20050412#fastcgi_not_so_fast">points out a very valid flaw</a> with the FastCGI architecture; if you for example create one hundred FastCGI processes per server in a 20 blade cluster then each separate process needs to allocate one database connection. This would amount to 2000 database connections which occupies a lot of memory (both in the database server and on the client) and bluntly put just doesn't scale. ;-) Does anybody that have real experience using FastCGI know how to solve this problem? Is there a solution or does FastCGI simply not scale to these dimensions? (Please ignore the unfriendly tone Cameron uses in his post, which surprises me as it's quite unlike Cameron "Peace" Purdy. It's really sad that Hani is making such an impact on the Java blogging community.)</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2005-04-12T00:30:16+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/001030_i_have_a_life.html">
<title>I have a life!</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/001030_i_have_a_life.html</link>
<description><![CDATA[<a href="http://www.flickr.com/photos/tirsen/2638322/" title="Photo Sharing"><img src="http://photos3.flickr.com/2638322_df3a7a78f4.jpg" width="500" height="375" /></a>

<p>
You may be wondering why there have been so little activity from me the latest, well, almost a year. Ok, you might not be wondering but I'm gonna tell you anyway:
</p>

<p>
I found paradise.
</p>

<p>
Let me put it this way: I currently live about 50 meters away from one of the most beautiful beaches in the world. I can get up 6.30 in the morning, grab my surf board and watch the sun rise out in the line up. On the ferry to work I pass through amazing nature and get off just in between the Sydney opera house and the bridge (if you're lucky you can even see dolphins or whales on they way). I can get my car and drive north past spectacular beach after spectacular beach. Go on weekend trips to the vineyards, the best diving in the world, or some extraordinary sailing.
</p>

<p>
Who really cares about OSS, IoC, AOP, RoR, Ajax, XP, OSX, etc anymore? Well, ok, I do... it's just kinda in the background nowadays... I want to care, but life is just too damn good down here.
</p>

<p>
(Btw, we're still looking for top people in ThoughtWorks Australia. You want to seriously increase your life quality <i>and</i> work with the best people in the world, drop me an email.)
</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2005-04-04T13:25:45+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000980_ejb_3_interceptors_finally_or.html">
<title>EJB 3 Interceptors: Finally! Or...?</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000980_ejb_3_interceptors_finally_or.html</link>
<description><![CDATA[<p>Ok, so the EJB team has finally understood the value of supporting custom interceptors. For some reason they can't avoid the temptation to put in some ludicrous limitation making it way less useful than it could've been. This time they've decided that entity beans doesn't need interceptors. So the following (incomplete) list of applications is according to the EJB spec committee pointless and unnecessary:<br />
<ul><br />
<li> Fine-grained data-based access control (this person can see this data, this person can't see this data)<br />
<li> Data-based audit logging (create date/who, modified date/who, etc)<br />
<li> Indexing (reindex this data when modified)<br />
<li> Messaging (send me an email when this data has changed)<br />
</ul></p>

<p>Personally I've been to few projects that doesn't need one or more of the above things. (And implemented them in more or less elegant ways, the more elegant ways have always been some type of interception on domain object level, be it Hibernate interceptors, bytecode magic, dynamic proxies or full-blown AOP.)</p>

<p>EJB 3... Still not impressed.</p>

<p>Oh well...</p>

<p>Update: Gavin King points out that EJB 3 supports entity callbacks which can be used to implement parts of the above list. I'm not sure about all of them though. What about data-based access control?</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2005-02-09T23:27:26+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000979_undo_in_aspectj_revisited.html">
<title>Undo in Aspect/J revisited</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000979_undo_in_aspectj_revisited.html</link>
<description><![CDATA[<p>A Marius Marin from Delft University of Technology has written a paper based on my blog entry about implementing <a href="http://blogs.codehaus.org/people/tirsen/archives/000690_undo_in_aspectj.html">undo with Aspect/J</a>. He extends my naive implementation and applies it to JHotDraw, a very interesting read:</p>

<p><a href="http://sepc.twi.tudelft.nl/~marin/papers/undoWARE04.pdf">http://sepc.twi.tudelft.nl/~marin/papers/undoWARE04.pdf</a></p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2005-02-09T03:27:12+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000960_rich_web_applications.html">
<title>Rich Web Applications</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000960_rich_web_applications.html</link>
<description><![CDATA[<p>I'm really amazed how these "rich web clients" are popping up all over the place: <a href="http://gmail.com">GMail</a> (anybody want an invite? ;-)  ), <a href="http://flickr.com">Flickr</a>, <a href="http://www.tadalist.com/">Tada-list</a>, <a href="http://www.bloglines.com">Bloglines</a> and so forth. In some respects they are even easier to use than their desktop equivalents; Mail.app on my lovely PowerBook is really the sweetest mail client ever but... I still tend to use GMail more often. Same with iPhoto vs. Flickr. It's something about these apps that maintain the ease of use of a web interface with the responsiveness of a fat client one.</p>

<p>I guess it's time to really brush up on your JavaScript skills, so a couple of days ago I went down to the bookstore to pick up <a href="http://www.oreilly.com/catalog/jscript4/">the book</a>. JavaScript is really quite a lovely language, closures, dynamic typing and so forth.</p>

<p>Oh, and Ruby on Rails <a href="http://www.loudthinking.com/arc/000396.html">really rocks</a>...</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2005-01-21T05:08:53+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000896_re_where_to_put_config_files.html">
<title>Re: Where to put config files?</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000896_re_where_to_put_config_files.html</link>
<description><![CDATA[<p>Dion is writing about <a href="http://www.almaer.com/blog/archives/000550.html">where to put config files</a>.</p>

<p>I always try to make it possible to do as much work as possible without leaving the IDE. For example, I have something I call "standalone mode" where I create a simple StandaloneServer class with a simple main method which uses the Jetty API to start up the server directly inside the IDE. For this reason I always keep my config files around in such a way so that "standalone mode" works without requiring the use of a build script. That is I "Mimic The Deployment Structure". In this mode I try to stub out high-end J2EE services (not available in plain vanilla Jetty) such as JTA, JNDI, JAAS and so forth. Using Spring Framework this is easily done. I also try to stub out backend services that we don't have reliable connectivity to.</p>

<p>The released app is usually deployed to a real appserver where JTA would take care of committing transactions and JNDI would be used to look up pooled DataSources. Therefor I have a build script that <em>converts</em> the standalone mode deployment structure into a deployed production mode ear file, tweaking config files and so forth to make it behave well in a real appserver.</p>

<p>Doing it this way you can have the best of both worlds. You get high productivity in development because you don't need to do a full compile-build-redeploy-cycle every time you've done a change (restarting Jetty takes about 3 seconds), in fact you should never need to leave the IDE to execute build scripts during normal development. You also get an app that is a good J2EE citizen, demarcating transactions with JTA, using JNDI for DataSources and so forth. It really does wonders for productivity!</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2004-11-23T21:12:53+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000882_managing_test_data_for_functional_tests.html">
<title>Managing Test Data for Functional Tests</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000882_managing_test_data_for_functional_tests.html</link>
<description><![CDATA[<p>I love automatic functional tests. They are the most valuable type of automated tests you can do. They give me confidence to do refactorings without regressions. They give the business confidence to release the software when they feel enough functionality is there. They make it possible to release updates to production systems without having to do a long and expensive manual test cycle.</p>

<p>In short, it allows me to be agile.</p>

<p>So functional tests are the most valuable tests you can have. But they are also the most expensive. They are expensive to write, they are expensive to maintain, they are slow to run. When they fail they are very hard to debug and figure out how to fix them. When you change functionality you need to go through your test suite and determine what tests needs to be changed and what tests needs to be removed. As the system grows this becomes more and more tedious and hard work.</p>

<p>Something I'm struggling very hard with now is how to manage test data for functional tests. In order to write a simple test for, for example, a paging list I need to set up all these different objects in the domain to the right state. When some constraints or rules are changed in the domain I need to go through all this test data setup code to make everything obey the new situation.</p>

<p>As the system grows the problem becomes bigger and bigger. It is very hard to get reuse of the test data setup between tests as each test has special needs on the data it uses. I can't use something like mock objects to just mock out where the data is read in because this is a functional tests and I want to test as much as possible with each test. The more I test, the more valuable the test is.</p>

<p>I can use something like the <a href="http://c2.com/cgi/wiki?ObjectMother">Object Mother</a> pattern but it only provides for individual objects. I need something higher level than this, something that can set up scenarios of objects that can be reused between tests and still allow the tests to tune these scenarios to fit their special needs.</p>

<p>I just don't know how to solve this, it seems to be a significant non-trivial problem of very large functional test suites.</p>

<p>What have other people done out there? What has worked (that I can try) and what has not worked (that I don't have to try)? I could use some help!</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2004-11-10T03:48:31+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000867_intellij_uses_picocontainer.html">
<title>IntelliJ uses PicoContainer!!</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000867_intellij_uses_picocontainer.html</link>
<description><![CDATA[<p>Man! This is cool: check out the lib directory of the latest IntelliJ EAP drop: "picocontainer-1.0.jar"!! They're using PicoContainer internally! That is so cool!</p>

<p>IntelliJ IDEA has given me so much during the years, I'm so happy to give something back.</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2004-10-29T03:56:24+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000865_how_to_build_maintainable_systems_simple_design.html">
<title>How to build maintainable systems: Simple design</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000865_how_to_build_maintainable_systems_simple_design.html</link>
<description><![CDATA[<p>I'm not saying that simple designs by some divine judgement are <em>better</em> designs (I do believe so, I just don't want to start that particular debate again). There are other much larger problems with complicated designs when it comes to implementing maintainable systems: complicated designs usually become poorly understood and therefor poorly implemented.</p>

<p>I've seen this many times in the field: Some hot-shot architect works for an intense period early in a projects lifecycle and produces some really hot-shot, ultra-cool, super-slick design that solves everything that the system would ever be conceived to do and then some. Job done, the architect leaves for his next hot-shot assignment (he holds himself too high for such profane tasks as, bah, implementation).</p>

<p>Left on the project are a bunch of more junior people who are up to the task of actually delivering the system. If they ever understood the design in the first place they are certainly not understanding it good enough to be able to maintain it when exposed to realities such as time-pressure, performance problems, inconsistent requirements and so forth. The design starts to break down and technical debt accumulates. The biggest problem now is that not only has the design broken down, they are also dragging around a massive framework hampering their every step.</p>

<p>I have been to places that had frameworks of hundreds and hundreds of classes that when it came down to it did the equivalent functionality of about two mid-sized classes work. I kid you not.</p>

<p>Some warning signs to look out for:</p>

<p><i>"We're building a generic framework so it will take a little longer to deliver the first project. But then we will be able to reuse all this stuff so we'll save time in the long run."</i> (Building reusable software is many, many times more difficult, expensive and time-consuming than one-off software. Is there really a business case for a reusable framework?)</p>

<p><i>"Let's build it so that all this functionality can be accessible from any possible client."</i> (Technologies like web services or CORBA has a huge up-front cost in terms of complexity. It's better to build the remote interfaces when the client actually exists.)</p>

<p><i>"Make the customer disappointed the first time, because they will be more than happy the next time."</i> (Are you sure you will get a next time?)</p>

<p><i>"We want to use a rules engine so that the business can easily extend the system in the future."</i> (Even a rules engine requires programmers to write the rules.)</p>

<p><i>"It might seem a little complicated for this simple project, but if we stick to a standard technology we can be sure to find developers that can maintain the system in the future."</i> (Nobody can maintain an unmaintainable system, standard or no standard.)</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2004-10-26T03:55:27+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000859_data_transfer_objects_makes_me_sick.html">
<title>Data Transfer Objects makes me sick!</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000859_data_transfer_objects_makes_me_sick.html</link>
<description><![CDATA[<p>If I see another DTO in a non-distributed webapp again I think I'm going to throw up.</p>

<p>Data Transfer Objects are meant for one single thing, transfer data over a distribution boundary. Extremely few webapps benefit from being <i>distributed</i> (as opposed to <i>clustered</i> which is an entirely different thing). Everybody seems to know this by now. So why do I still see all these completely non-distributed webapps with DTOs all over the place!?</p>

<p>You would think that people start thinking something just gotta be wrong when a significant portion of their system is just about shuffling data in and out of DTOs. Or when the domain model is left completely atrophied and looks more like a relational database schema expressed in an awkward Java syntax. Or as their carefully crafted architecture just falls apart in a mumbo jumbo of completely unmaintainable procedural code.</p>

<p>Oh nooo. They are the perfect excuse for creating objects completely without behaviour or responsibilities, approved and signed by the <a href="http://www.martinfowler.com/">uber guru of enterprise architecture himself</a>. "Hey, if Martin Fowler says I can do objects without behaviour then I can bloody hell do them all the time!"</p>

<p>Martin, you're a great bloke and I don't mean no disrespect but couldn't you just have left this bastard of a pattern out of your books! People just can't handle it responsibly.</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2004-10-12T05:36:18+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000748_aop_is_not_just_descatter_detangle.html">
<title>AOP is not just de-scatter, de-tangle</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000748_aop_is_not_just_descatter_detangle.html</link>
<description><![CDATA[<p>I've used AOP more or less actively for almost two years now, and I think I'm really starting to get it. Given that it took me almost 5 years to really master object-orientation I would say AOP is quite a lot easier. (Granted, I learned OOP through C++ which made it a lot harder).</p>

<p>Anyway, there's an important design characteristic of AOP that I've been starting to appreciate more lately. Most people talk about AOP as it's all about moving things that has been implemented in several places into one place, and separating things that has been cramped up into one single place into several places. I think there's a different important part to it though. I call it <i>Dependency Inversion on Stereoids</i>.</p>

<p>The <i>Dependency Inversion Principle</i> is basically the old OO principle for managing type dependencies in an object-oriented system. Given you have a dependency:<br />
A -> B<br />
If you want to minimize dependencies and separate A and B, you would introduce an interface or baseclass that B implements and A depends on ("implementation" is a type dependency where the implementation depends on the interface). So you would get:<br />
A -> I <- B<br />
Voila! You have inverted the dependencies and separated A from B!</p>

<p>But with AOP you have a much more direct and powerful dependency inversion (it's on stereoids!). So from:<br />
A -> B<br />
If you make B an aspect you can completely and directly invert the dependency:<br />
A <- B<br />
B would depend on A in this case, but you could completely eliminate the extra luggage in A that makes it call into the interface I in the right places.</p>

<p>This is a new powerful design construct, you wouldn't use it all the time but it allows you a new degree of freedom. For example, you could let one team develop a domain model and another team bolt on undo or persistence on it (I know Crazy Bob is doing this).</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2004-06-01T11:16:11+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000747_best_aop_explanation_ever.html">
<title>Best AOP explanation, ever!</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000747_best_aop_explanation_ever.html</link>
<description><![CDATA[<p>Adrian Colyer, project lead of AspectJ has written the best motivation for AOP I've ever read.</p>

<p><a href="http://jroller.com/page/colyer/20040531#the_ted_neward_challenge_aop">http://jroller.com/page/colyer/20040531#the_ted_neward_challenge_aop</a></p>

<p>Adrian, can you explain the constructs of AOP (joinpoints, pointcuts, advice, etc) in the same way?</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2004-06-01T10:59:00+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000723_i_have_many_alter_egos.html">
<title>I have many alter egos!</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000723_i_have_many_alter_egos.html</link>
<description><![CDATA[<p>This latest gosspi on fake posters is funny. Just check out <a href="http://www.theserverside.com/user/userthreads.tss?user_id=74755">how many alter egos I have</a>. Can anyone beat me?</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2004-05-18T13:49:51+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000706_why_i_still_wont_do_ejb.html">
<title>Why I still won&apos;t do EJB</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000706_why_i_still_wont_do_ejb.html</link>
<description><![CDATA[<p>Ok, first of all. I actually think EJB3 will be a massive improvement compared to previous version. They really seem to be on the right track.</p>

<p>But I'm going to prefer not to do EJB anyway.</p>

<p>Jason Carreira touched upon in it in this <a href="http://jroller.com/page/jcarreira/20040506">blog entry</a>. The reason is simply that the choice of app-server (and thus EJB container) is usually not a technical decision. It is a political/strategic/whatever decision. When I come into a project at a customer all those decisions have already been made and a simple consultant will rarely (never?) be involved in those decisions. Here's your app-server, here's your database. Now, build me this bad-ass system.</p>

<p>This means that if there's a bug somewhere in the app-server you're looking at a 3+ months cycle of nagging on IBM support until they assume responsibility, waiting for them to actually figure out a way to fix the problem and finally persuading the customers production department to apply the fix. And that's assuming you don't hit a brick wall somewhere and it's just not going to happen.</p>

<p>In a situation like that you got one choice: rely as little as possible on the app-server/container, and always expect the worst. We're talking basic servlets here, you'd be lucky if you get a jsp running and don't even dare thinking about servlet-filters, EJBs or anything fancy like that.</p>

<p>With Spring/Hibernate (or whatever is the current vibe) I bring my own lunch. I can build the entire solution as simple servlets. I can run it standalone with Jetty inside my IDE. If there's a bug somewhere I'll just go in and fix it. If there's a nasty deadlock under heavy load in production (or whatever) I can figure it out. In a put-your-trust-in-the-holy-container-provider-situation my ass is grass.</p>

<p>So thank god for lightweight enterprise Java (as it's currently seem to be called)! You've saved my ass so many times.</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2004-05-07T22:35:56+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000690_undo_in_aspectj.html">
<title>Undo in AspectJ</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000690_undo_in_aspectj.html</link>
<description><![CDATA[<p>

On an internal ThoughtWorks conference I presented a couple of cool examples of what you can do with AspectJ (avoiding the rightfully impopular and boing logging example, which was appreciated by the audience). Most of them was blatantly stolen from Ramnivas Laddad's superb book <a href="http://www.manning.com/laddad">AspectJ in Action</a> (hope you don't mind Ramnivas ;-)  ). Read it if you haven't yet, I cannot recommend it enough. I rewrote them using TDD on the train back and forth to my current project outside of London.

<p>

One of the more popular ones (and one of the few I did not steal from Ramnivas) was the undo framework. Anyone that has written a large GUI application knows that undo is a major pain in the ass, each command has to written twice, how to do it and how to undo it. Well, with AspectJ things like this becomes quite easy and can be written completely modularized in a generic "non-intrusive" fashion.

<p>

Here's a test-case that demonstrates the usage of the framework:
<pre>
		UndoChain undoChain = new UndoChain();
		final Point point = new Point(100, 100);
		undoChain.execute(new Runnable() {
			public void run() {
				point.x = 150;
			}
		});
		assertEquals(150, point.x);
		undoChain.undo();
		assertEquals(100, point.x);
		undoChain.redo();
		assertEquals(150, point.x);
</pre>

<p>

A Point is created and the x-coordinate is modified in a command. <tt>undoChain.undo()</tt> rolls back all modifications done by the command and <tt>undoChain.redo()</tt> reapplies them again.

<p>

Ok, so here's the gist of the solution, an aspect that records all field modifications their previous value and their new value.
<pre>
	aspect RecordFieldModifications
	{
		/**
		 * Picks out the execution of a command.
		 */
		pointcut inCommand(Command cmd) :
			this(cmd) &&
			execution(* Command.execute());
		
		/**
		 * Picks out any modification of a field. 
		 */
		pointcut fieldModification(Object o, Object newValue) :
			args(newValue) && this(o) &&
			set(* *.*);
		
		/**
		 * Picks out any modification of a field caused by the execution of
		 * a Command, the old value can unfortunately not be picked out by
		 * the pointcut. :-( 
		 */
		pointcut fieldModificationFromCommand(Command cmd, Object o, Object newValue) :
			!within(UndoChain) &&
			cflow(inCommand(cmd)) && 
			fieldModification(o, newValue);
		
		/**
		 * Advice to any field modification caused by the execution of a field. Stores
		 * the new value and the old value as a Modification on the Command.
		 */
		before(Command cmd, Object o, Object newValue) : 
			fieldModificationFromCommand(cmd, o, newValue)
		{
			// retrieve extra context information via reflection
			Field field = getField(thisJoinPoint.getSignature());
			Object oldValue = field.get(o);
			// record modification in currently executing command
			cmd.addModification(o, field, oldValue, newValue);
		}

		/**
		 * Gets the field using reflection. 
		 */
		private Field getField(Signature signature) {
			Field field = signature.getDeclaringType().getDeclaredField(signature.getName());
			field.setAccessible(true);
			return field;
		}
	}
</pre>

<p>

The rest of the solution is basically just plumbing, to undo a command all modifications are undoed in sequence. Undo of a single modification is basically just about restoring the old value of the field using reflection:
<pre>
	field.set(o, oldValue);
</pre>

<p>

The whole solution clocks in at 156 lines of code, which <em>includes</em> imports, package statements, and quite lengthy comments.

<p>

Neat, huh!?]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2004-04-25T17:33:03+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000669_xml_deprecates_binary_packages_in_tcp.html">
<title>XML deprecates binary packages in TCP</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000669_xml_deprecates_binary_packages_in_tcp.html</link>
<description><![CDATA[<p>This is a great new innovation for TCP/IP:<br />
http://www.x-cp.org/index.html</p>

<p>James, maybe it was too early to repent Jelly. Imagine if you combined Jelly and XCP, your TCP packages would not only be in XML, you would also be able to execute them!!</p>

<p>We are definitely making progress.</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2004-04-01T15:50:53+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000647_groovy_and_ruby.html">
<title>Groovy and Ruby</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000647_groovy_and_ruby.html</link>
<description><![CDATA[<p>As some may have noticed I'm a big Ruby fan.</p>

<p>Some wise person once said that learning a new programming language will change they way you think, if not it's no point learning a new language. I've done quite some bit of C# lately, but that hasn't really changed the way I think. It's basically more or less the same language as Java. Ruby fundamentally changes the way I think though. It's dynamically but strongly typed (strongly typed as: in Ruby "6" + "2" will give you "62" but in a loosely typed language like Perl or TCL that would give you 8) and it's got plenty of modern language features that really boosts your productivity.</p>

<p>People that think you only need one single language and that would give you everything you need should really try out some of these scripting languages for a while. In the beginning you're trying to do stuff like interfaces and abstract classes but after a while you just realize it's pointless. The compiler won't help you or protect you from yourself, there's only one way you know whether your code works or not: run it, test it. (In fact, this is the case in Java too, but the compiler gives you a false sense of security. I would say...)</p>

<p>I think Martin Fowler explains it best in his blog entry about <a href="http://martinfowler.com/bliki/SoftwareDevelopmentAttitude.html">enabling vs. directing</a>. Ruby and other dynamically typed languages are enabling, they help a good programmer do a better job.</p>

<p>For this reason I really think it's great to see the <a href="http://www.jcp.org/en/jsr/detail?id=241">Groovy JSR</a> being submitted to the JCP. It might not be the only scripting language for the Java platform, but it's one that's particularly close to my heart. I think Java has always been a better platform for multi-language stuff than .NET so it's good to see this untapped resource being put to use.</p>

<p>Groovy's got a bunch of really nice Rubyesque features like closures, syntax for advanced data structures, inline strings and so on but it's also very tightly integrated into the Java platform. You can compile a Groovy script directly into a .class file and that's just going to be like any class in Java and vice versa you can reuse any Java class and library within Groovy. As James <a href="http://radio.weblogs.com/0112098/2004/03/17.html#a466">points out</a> this binary compatability is way more important than syntactical similarities (although I must admit, I much prefer curly braces to the Pascalesque begin/end in Ruby). Groovy also avoids the magical implicit proc-variable and yield that is quite confusing and quite pointless in Ruby. In Groovy a closure is just like any other object, and you just invoke it. You can also do magical stuff like overriding invokeMethod. That sort of stuff is actually almost absurdly useful when doing framework stuff like remoting libraries, persistence or transparent proxies. (Yes, think poor mans AOP.) Unfortunately I don't see continuations making it into the language due to some quite significant JVM support for it. Continuations are really useful for implementing asynchrous processes like web applications without threads and can also be used to implement logic programming.</p>

<p>(And, yes, to Hani's <a href="http://www.jroller.com/page/fate/20040316">dismay</a> I will probably represent ThoughtWorks on the expert group once we get the paperwork sorted out. :-)  )</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2004-03-17T14:58:54+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000618_confluence_rocks.html">
<title>Confluence rocks!</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000618_confluence_rocks.html</link>
<description><![CDATA[<p>
This blog is starting to look like an advertisment for Atlassian, but I just have to tell you about some stuff I wrote over the weekend (with some help with the finishing touches from <a href="http://blogs.codehaus.org/people/rinkrank/">Aslak</a> and <a href="http://jroller.com/page/cv">Carlos</a>, the latter being in town all the way from Brazil).

<p>
You know when you are trying to write that long anticipated documentation for your latest open-source library and you want to include some code samples in your tutorials? Only problem is, the project is coming close to a release but you're still refactoring like crazy. So how do you keep all those code-snippets up-to-date?

<p>
Confluence to the rescue! Your open-source library is the latest and coolest cutting-edge stuff you can think of so of course you are using the latest and coolest cutting-edge tool to write the documentation in. For those who don't know about it: Confluence is basically a wiki with some really nice features like for example an awesome look-and-feel that makes me all warm and fuzzy inside.

<p>
So, one of the features in Confluence is that you can easily extend it with new macros. This is actually a result of that they are basing their wiki rendering on <a href="http://radeox.org/">Radeox</a> the same rendering engine used by <a href="http://snipsnap.org/">SnipSnap</a>.

<p>
So I basically just wrote a macro that extracts code snippets from any url (hint, think viewcvs) and renders them into a Confluence page.

<p>
You basically puts this into your code (easily done with an IntelliJ surround live template):
<pre>
// START SNIPPET: boy
public class Boy {
    public void kiss(Object kisser) {
        System.out.println("I was kissed by " + kisser);
    }
}
// END SNIPPET: boy
</pre>

<p>
Then you add the following to your wiki page (I've snipped the long viewcvs url that points to my java code in cvs, because it wrecks the formatting of this page completely):
<pre>
{snippet:lang=java|id=boy|url=[long viewcvs url deliberately left out]}
</pre>

<p>
Don't get fooled by the "lang=java" thing, the only thing that does is to render the content as a code block with java syntax highlighting. This actually works for any language, xml, text, html, whatever. Thanks to <a href="http://www.martinfowler.com">Martin Fowler</a> who explained the idea of putting the snippet demarcators into the code, which avoids any crazy ideas of having to parse the Java code and makes the same thing work for virtually any text file. Simple, elegant and powerful, almost <a href="http://c2.com/cgi/wiki?WardCunningham">Wardish</a>.

<p>
Have a look at the following page, there is not one single line of java code in that page (except for that snippet that for some reason doesn't work properly, I'll look into that later):
<br>
<a href="http://docs.codehaus.org/display/PICO/Two+minute+tutorial">http://docs.codehaus.org/display/PICO/Two+minute+tutorial</a>

<p>
By the way, I haven't tested this but the macro probably works just as well in SnipSnap or any other Radeox based applications. It does not depend on any features in Confluence whatsoever.

<p>
The code temporarily lives in the NanoContainer CVS:<br>
<a href="http://cvs.codehaus.org/viewcvs.cgi/snippet/?root=nanocontainer">http://cvs.codehaus.org/viewcvs.cgi/snippet/?root=nanocontainer</a>
]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2004-02-26T09:38:27+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000617_happy_birthday_codehaus.html">
<title>Happy birthday Codehaus!</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000617_happy_birthday_codehaus.html</link>
<description><![CDATA[<p>So, one year huh? It's been great fun and we've accomplished a lot. Projects like AspectWerkz, Drools, Groovy, PicoContainer, JMock, QDox, XDoclet 2, Nanning, Plexus, XStream shows that Codehaus in a short time has attracted a lot of innovative projects. One reason is probably all the great and fun Hausmates and another reason is probably the amazing infrastructure. People that get sick of Sourceforge's low quality service has all the reason in the world to move. We have to thank <a href="http://blogs.codehaus.org/people/bob/">Bob The Uberdespot</a> for that, but I should also mention <a href="http://www.atlassian.com">Atlassian</a> whom never thinks twice about giving away an open-source license or two of their excellent products. I wish more companies worked like that (and there is, but I just wish *everone* worked like that :-) ).</p>

<p>A birthday is a time for review. What can we be better at? I think something we have to start thinking more about is how we face our users. Codehaus used to be alot about technology but there has been a movement lately to try and clean up our public face. We should definitely think more about our documentation.</p>

<p>That said: Hipp, hipp, hooray!</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2004-02-26T08:59:59+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000614_subversion_10_released.html">
<title>Subversion 1.0 released!</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000614_subversion_10_released.html</link>
<description><![CDATA[<p>Wow! I've been looking forward to this for a long time. Subversion 1.0 is finally released. It's been stable for quite some time now, but having a 1.0 out means we can probably start moving some of our projects over. For example we've been discussion moving PicoContainer to Subversion after the 1.0 release of Pico which is due soon. Dealing with some of the idiosyncrasies of CVS is finally starting to wear me down. CVS is still a lot better than many other version control systems but things like moving files, renaming stuff, absurdly slow tagging and so on is getting tiresome.</p>

<p>http://subversion.tigris.org/</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2004-02-23T13:41:54+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000606_jetbrains_resharper.html">
<title>JetBrains Resharper</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000606_jetbrains_resharper.html</link>
<description><![CDATA[<p>Weee! The JetBrains Resharper EAP is open! This could be the turn-around for .NET development!</p>

<p>http://www.jetbrains.net/resharper</p>

<p>I can't wait to give it a whirl! They seem to have kept all the key bindings exactly like in IDEA. The joy!</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2004-02-16T09:19:38+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000604_a_lesson_about_simplicity.html">
<title>A lesson about simplicity</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000604_a_lesson_about_simplicity.html</link>
<description><![CDATA[<p>Keeping things simple is not just about keeping a design simple, it can also be applied on micro-level.</p>

<p>For example, today me and my pair-mate refactored some especially nasty and complicated code where this really made sense. Basically it was a thing which hooked up events to the various nodes of an hierarchical structure and maintained those event-listeners when the hierarchical structure changed. The old code used some quite complicated logic to unhook event-handlers when a branch got removed and to hook it up when a branch got added. The refactored implementation basically just unhooked all events from the old nodes and hooked everything up again to the new nodes whenever something changed, regardless of what changed. This made the new implementation do things a little bit too much, but the the code just looked so much cleaner and maintainable. (Which in my experience means less bugs.)</p>

<p>So in essence, by choosing the much simpler implementation strategy we could produce code that was much better.</p>

<p>The good thing about this specific code was that it was exceptionally well-tested with small well-readable test-methods. So we basically ripped out the old nasty code and started to reimplement the refactored solution by fixing the tests one-by-one. It was truly a pleasure! People that say TDD is boring (nudge, nudge Chiara) should really try to learn it properly before making such judgements. Btw, this also teaches you that it's much more important to write good tests than to write good code.</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2004-02-13T17:49:14+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000595_prevayler_finalist_in_jolt_awards.html">
<title>Prevayler finalist in Jolt Awards!</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000595_prevayler_finalist_in_jolt_awards.html</link>
<description><![CDATA[<p>Cool, <a href="http://www.prevayler.org">Prevayler</a> is finalist in the Jolt Awards: <a href="http://www.sdmagazine.com/pressroom/jolt_finalists_2004.pdf">http://www.sdmagazine.com/pressroom/jolt_finalists_2004.pdf</a>.</p>

<p>Boy, I've been using Prevayler for around two years now and it's certainly a very powerful alternative to the relational-mapping dance. Of course, the toughest competitor in the category is Hibernate. ;-)</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2004-02-04T19:34:56+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000582_tdd_is_about_testing.html">
<title>TDD *is* about testing</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000582_tdd_is_about_testing.html</link>
<description><![CDATA[Sorry, <a href="http://www.sys-con.com/story/?storyid=37795&DE=1">Dan North</a> but I have to disagree. I've always been a bit sceptical about TDD not being about testing but Martin Fowler <a href="http://martinfowler.com/bliki/VeryLowDefectProject.html">latest blog entry</a> got me thinking. So I might be a bit old-fashioned here but let's approach the subject from a pragmatic view-point.

<p>

I see two fundamentally different types of testing in an XP/TDD/Agile project. <i>Acceptance</i> testing and <i>Unit</i> testing. There's no point in describing acceptance tests as driving the design but unit testing is commonly viewed as doing just that. What you are saying Dan, is that to a very large extent TDD is about driving the design and very little about producing a high-quality unit-test harness. Let's see what I prioritize when it comes to acceptance and unit-tests (both can be used to drive <i>development</i>) and why these two testing approaches complement each other so nicely.

<p>

Acceptance tests are about (in order of priority):
<ol>
<li> <b>Capturing, documenting and proving customer requirements</b> This is sort of the holy grail of XP, but <a href="http://www.thoughtworks.com">we</a> actually have a couple of projects were customer requirements are <i>primarily</i> captured as acceptance tests (never actually written solely by the customer of course, that is (j)utopia, but definitely written in a form that can easily be read and verified by the customer, more on this some other time).
<li> <b>Ensuring that all components in the system play along nicely</b> Acceptance tests should therefor as much as possible be integration tests, that is as little part as is practically possible should be stubbed out. If you rely on some systems that are in internal control, run directly against them, if you rely on external systems consider stubbing them out if they are volatile. This also implies that acceptance tests are quite <i>slow</i>, many suites can keep on going for many, many hours (I've seen suites that take as long as 20 hours).
<li> <b>Insuring against regressions</b> Many agile projects try to release often, the acceptance tests can be used to insure the customer from broken business-critical behaviour.
<li> <b>Provide a way for the customer to monitor progress</b> Reports on what stories (or use-cases) have been succesfully tested is the surest and most truthful way for a customer to understand what progress a project is making.
</ol>

<p>

The point of unit-tests are (in level of priority):
<ol>
<li> <b>Run fast</b> Agile projects are all about enhancing and shortening feedback loops, if something goes wrong you should know about it as soon as possible so that you can correct your behaviour. The acceptance tests are usually sloooow (unless you're really lucky) so they are virtually useless for providing feedback to a developer when he's checked in some bad code. A unit test suite should run with <i>everything stubbed out</i> and run in minutes. My rule of thumb is: unit tests < 1 min => you're at top productivity, unit tests ~ 5 mins => you're still agile, unit tests > 10 mins => you're no longer an agile project, unit tests > 30 mins => you're project is screwed, look for a new job. Okay, don't take this to literally, but you get my point. (This is also the reason why I keep bitching about not starting web servers in your unit tests.)
<li> <b>Show <i>what</i> is broken</b> Acceptance tests show that <i>something</i> is broken, unit tests should show <i>what</i> is broken. Ideally for each failing acceptance tests there should be a couple of failing unit tests. To be more precise, a failing acceptance test is symptom of an <i>incomplete unit-test suite</i> (thanks for that one Martin) and before the fix is introduced a new failing unit-test should be added to the unit-test suite.
<li> <b>Give you courage to refactor</b> Refactoring without unit tests is like the circus without a safety net. You can do it, but you it's really dangerous (and you have to be really good). Most people don't have that sort of courage (I sure know I don't!) so important refactorings never ends up being done leading to faster <a href="http://www.jroller.com/page/tirsen/20030601">software rot</a>.
<li> <b>Ease communication with your peer while pair programming</b> In my opinion you can't do pair programming if you're not doing TDD. The unit-test is a natural discussion point and the rule about just implementing enough for the test to pass makes discussions more to the point. This makes the pair less likely to disagree about subjective matters where communication usually start breaking down.
<li> <b>Drive the design on unit level</b> Here's what you are talking about Dan. This is actually essential for creating a high-quality test-suite that fulfills all of the above, but when I actually judge a test-suite this comes quite long down on my list. The unit-test acts as "yet another client" to the unit (eg class) you are trying to develop helping you think about the interfaces, collaborators and other types of structure before you actually start writing the actual code.
</ol>

To be quite honest, the main reason why I write my tests <i>before</i> I actually write the code is because it's sooo boring writing tests afterwards. I mean, I usually know it works (via for example manual tests) so why should I spend all that time writing tests for it again?]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2004-01-26T18:47:14+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000562_using_ruby_to_build_java_systems.html">
<title>Using Ruby to build Java systems</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000562_using_ruby_to_build_java_systems.html</link>
<description><![CDATA[<p>
Last year I created a build system for a very big project here at <a href-"http://www.thoughtworks.com">ThoughtWorks</a>.
<p>
It's been through many iterations using <a href="http://ant.apache.org">Ant</a>, <a href="http://maven.apache.org">Maven</a> and finally <a href="http://www.ruby-lang.org">Ruby</a>. It's been quite a journey but the end result works quite nicely.
<p>
<b>Why not a standard build-tool like Maven or Ant?</b> As I said it's a huge system with a very complicated build. We started out with Ant-scripts generated by XSLT from a configuration-file. The configuration-file declaratively described the modules and their dependencies (something like a Maven-POM). You could easily edit the simple configuration-file to change things like classpaths and dependencies between modules and creating new WAR-files. This worked quite nicely initially but the system grew and the build became more and more complicated. For example, the generated build-script was several megabytes large!! The xslt transform was also absurdly large and very hard to maintain. We had similar maintainability problems with Maven. To summarize: using a standard build tool for something as big as this is simply not feasible. Build tools don't have things like data-types, control structures, object-orientation and when your build grows to become a system in itself you need all this stuff.
<p>
<b>Why Ruby?</b> This was basically a personal preference, any scripting language would do, like Python or even Perl. Ruby is at the core a very clean object-oriented language (unlike Python and Perl) and on top of this a lot of nice Perl-inspired syntactic sugar that makes it possible to write compact and good looking code. The perfect combination! Almost (but not quite) brings me back to my <a href="http://www.digitool.com/">Common Lisp</a> days (writing <a href="http://www.noteheads.com">this</a>).
<p>
Due to the dynamicity of Ruby we could do lots of nice things. For example we added a new construct that you could use to make ordinary methods behave like build targets, if a target had already been built the next time you built it (with the same arguments) it would simply not get executed. (Almost like a caching interceptor.) For example:
<pre>
def generate
  # execute code generators
end
target_method :generate

def compile
  # execute javac  ant-task
end
target_method :compile

def test
  generate_code
  # execute junit ant-task
end
build_command :test, "run unit tests"

def jar
  generate_code
  compile
  # execute jar ant-task
end
build_command :jar, "create jar"

def all
  test
  jar
end
build_command :all, "default target"
</pre>
<p>
So if you execute <code>all
</code>
 the targets <code>generate
</code>
 and <code>compile
</code>
 would only get execute once. Without this they would get executed twice with catastrophical effects (since test execution take almost 95% of the build time).
<p>
The <code>build_command
</code>
 modifier makes the method a target and also adds it to the list of externally callable commands (with an optional description). A little framework makes it possible to call these from the command-line or a simple console (keeping caches in memory thus speeding things up).
<p>
There's a RCR (Ruby Change Request) to make the <code>def
</code>
 method return something sensible (now it returns <code>nil
</code>
) so you could instead do:
<pre>
  target_method def generate
    # execute code generators
  end
</pre>
<p>
Like a modifier in Java. This should look much better!
<p>
<b>Reusing Ant tasks in Ruby</b> This project used code generation quite extensively with custom code generators and XDoclet for Hibernate configuration files. (Personally I'm not very fond of code generation, but this choice was made long before I came in.) All of this was implemented with Ant-tasks. Another reason for reusing Ant-tasks is that starting things like <code>javac
</code>
 and <code>jar
</code>
 has a high startup time but when started they run quite fast. (Unfortunately <code>jikes
</code>
 fell over on this massive codebase.) Within Ant these tasks does not have the same problem.
<p>
So reusing Ant-tasks was simply a must.
<p>
We ended up creating a small "Ant-server", a simple program that once started took Ant-snippets on it's standard input and printed out the results on the standard output. With some work on the Ruby side to manage this process correctly it all you needed to do to execute Ant-tasks within Ruby was:
<pre>
    ant(%{
      &lt;javac
          encoding="#{default_file_encoding}"
          destdir="#{destdir}"
          classpath="#{to_classpath(tools_classpath)}"
          debug="true"
          srcdir="#{src}" />
    })
</pre>
<p>
(The "#{}" inserts the corresponding Ruby-expression into the String, almost like Ants "${}" but much more powerful.)
<p>
<b>Summary</b> The end-result was still quite a large codebase but much more maintainable. We reused the declarative configuration file that was used to generate the Ant build so we could coexist neatly with the Ant build. Editing the declarative configuration file to change things like classpathes was really simple and did not require editing the Ruby-code. We used some of the object-oriented constructs in Ruby but the next time I would probably take this a step ahead and make things even more object-oriented, so instead of "compiling" you would ask a "module" to "build itself". This should make the build code much easier to understand (we had the typical smells of too long parameter lists and so on).
<p>
I would also look into <a href="http://groovy.codehaus.org/">Groovy</a>, it has very cool ways of <a href="http://groovy.codehaus.org/ant.html">calling Ant scripts</a>. Since it also has some of the niceties of Ruby it could be the perfect scripting language for doing complicated builds.
<p>
(We also used a cool invention by <a href="http://blogs.codehaus.org/people/rinkrank/">Aslak</a> that made it easy to parallelize and distribute the build. More on this some other time.)]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2004-01-16T18:47:20+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000560_dependency_injection_is_the_first_step_to_a_unified_standard_for_lightweight_containers.html">
<title>&apos;Dependency Injection&apos; is the first step to a unified standard for lightweight containers</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000560_dependency_injection_is_the_first_step_to_a_unified_standard_for_lightweight_containers.html</link>
<description><![CDATA[<p>Me, <a href="http://paulhammant.com/blog/">Paul Hammant</a>, <a href="http://blogs.codehaus.org/people/rinkrank/">Aslak Hellesoy</a> and <a href="http://www.wrox.com/books/0764543857.shtml">Rod Johnsson</a> met at the <a href="http://www.thoughtworks.com">ThoughtWorks</a> offices the other week to discuss <a href="http://martinfowler.com/">Martin Fowler</a>'s new <a href="http://martinfowler.com/articles/injection.html">article</a> on a topic dear to our hearts.</p>

<p>Historically it may have seemed like the communities around <a href="http://www.springframework.org/">Spring</a> and <a href="http://picocontainer.org/">PicoContainer</a> have been in disagreement. In fact nothing could have been more wrong. We have a very common vision on where we want to take Java enterprise development.</p>

<p>Next steps? Well, although activity has been slightly low on <a href="http://aopalliance.sourceforge.net/">AOP Alliance</a> I don't think we've heard the last of it. When <a href="http://nanning.codehaus.org">Nanning</a> implements the standard you will be able to reuse interceptors from Spring for PicoContainer components and in fact it should be possible to write completely portable interceptors that offers things like caching, transactions, persistence or distribution. PicoContainer and Spring both already support setter based injection (formerly IoC type 2) and constructor based injection (formerly IoC type 3) so it should already be possible to easily move components between the platforms.</p>

<p>When I started blogging on Freeroller (now JRoller, then roller.anthonyeden.com) over two years ago (I think I was user number 15) there were some talk about <a href="http://www.jroller.com/page/ara_e/20021102">J3EE</a> (ever so slightly tounge-in-cheek). A platform that was lightweight, extensible and testable. Well... </p>

<p>We're almost there...</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2004-01-16T00:26:26+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000552_codeguide_debugger_has_step_back.html">
<title>CodeGuide debugger has step BACK!!</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000552_codeguide_debugger_has_step_back.html</link>
<description><![CDATA[<p>Wow! Mr. <a href="http://www.jroller.com/page/fate/20040113#idea_what_happened_to_innovation">Bile</a> pointed me to the new debugger in CodeGuie. Take a look at <a href="http://www.omnicore.com/htmls/newdebugger.html">this</a>. That's innovation, a step BACK feature that allows you to take a look at the execution history. How cool is that!? I've been needing this sooo many times. Don't you just hate it when you accidently step over that method call you really needed to look at. Click 'step back', 'step into' and you're there!</p>

<p>I wouldn't mind some focus from the IDEA guys either. We started using you because you did <em>not</em> have all that bloated EJB-support, GUI designer what have you, instead you had a spectacular editor. (Although personally I do think Aspect/J support would've been seriously cool.)</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2004-01-13T17:18:20+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000550_picocontainer_presentation_from_javapolis_now_also_in_japanese.html">
<title>PicoContainer presentation from JavaPolis, now also in Japanese</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000550_picocontainer_presentation_from_javapolis_now_also_in_japanese.html</link>
<description><![CDATA[<p>Mine and Aslaks presentations from JavaPolis on PicoContainer is available <a href="http://picocontainer.codehaus.org/presentations/">here</a>.</p>

<p>Keiichi Matsunaga translated it into Japanese, which is really, really cool. Thanks Keiichi!</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2004-01-12T14:38:02+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000542_dont_be_sad_chiara.html">
<title>Don&apos;t be sad, Chiara</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000542_dont_be_sad_chiara.html</link>
<description><![CDATA[<p>Chiara is <a href="http://www.jroller.com/page/chiara/20040104#all_these_buzz_words_make">tired</a> of all the buzzwords, XP, domain models and what have you.</p>

<p>I gotta tell you, maybe you should reevaluate your choice of profession. Software development is continuous learning. Just like a medical doctor continuously has to be up to date on new medicines, research and so on, so must we. I mean, letting a patient die while a drug could actually cure him is not good enough. If we could deliver better software faster and at a smaller price, it's our responsibility to do it.</p>

<p>I don't understand what you have against XP, ThoughtWorks has virtually no failed projects, we could certainly not have pulled that off without XP or agile methodologies. Which other consultancy can brag about the same thing? (Okay, okay, it's not the Silver Bullet, you also need a project full of ThoughtWorkers, but that's a small price for success...)</p>

<p>Would you rather do RUP? I don't think so...</p>

<p>Keep it up, Chiara. This is what makes it interesting! You can never know everything, there's always ways to improve. You're never the best. It's brilliant! I love it!</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2004-01-05T20:18:08+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000535_my_humble_predictions_for_2004.html">
<title>My humble predictions for 2004</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000535_my_humble_predictions_for_2004.html</link>
<description><![CDATA[<p>Seems kinda a funny to do some predictions for the next year and see whether they hold out or not. Here are mine:</p>

<ul>
<li><b>Lightweight containers.</b> Things like <a href="http://www.springframework.org">Spring Framework</a>, <a href="http://nanning.codehaus.org">Nanning</a>+<a href="http://www.picocontainer.org">PicoContainer</a> and <a href="http://www.jboss.org/developers/projects/jboss/aop">JBoss AOP</a> are already a compelling alternative to EJB. These offerings will be more complete and possibly even some community-driven standards will evolve.
<li><b>Full-fledged AOP will become more popular.</b> As we all know, AOP != Interceptors, so the lightweight containers can only support a limited number of AOP patterns (something I will try to address in an upcoming blog entry). IntelliJ will hopefully have full support for Aspect/J in a coming version, Eclipse already have it, <a href="http://aspectwerkz.codehaus.org">AspectWerkz</a> is really getting more and more interesting.
<li><b>JCP (IBM/BEA/Sun) will (maybe) get it in the end.</b> I'm not holding my breath, but when the big players realize they are loosing projects to the lightweight containers they will actually have a serious thinker about the absurdly complicated J2EE platform. Microsoft gets it of course, .NET is much easier to use.
<li><b>Agile practices becomes main-stream.</b> The amount of hugely successful agile projects will be a driving force for use of more agile practices in any software development project. TDD will become completely ubiquitous especially in open source. A higher focus on quality and testing in general will follow.
<li><b>"Scripting" languages.</b> Languages like Ruby and Python are really clean object-oriented languages and also extremely productive. Compile-time safety is not as necessary when you do TDD (and compile-time checks can't give you 100% security anyway). Smalltak didn't have compile-time safete, and many large systems where written in that. I don't suspect scripting languages to be used for writing really large apps on a massive scale yet, but with for example <a href="http://groovy.codehaus.org">Groovy</a> you will be able to Java in a dynamic language!
<li><b>Linux will grow.</b> I just recommended my father to switch to SUSE or Mandrake. The desktop-oriented Linux-distros are really amazingly easy to use, maybe like Windows a couple of years ago. Worms, security holes and so on will force businesses to have a serious look at more secure alternatives to Windows, even on the desktop. Especially when it's only a matter of time before worms or other hacks are used for criminal purposes, stealing credit-card numbers or other sensitive information. Some might make the jump to Linux, some might not.
</ul>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2004-01-01T22:44:12+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000531_happy_new_year.html">
<title>Happy new year!</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000531_happy_new_year.html</link>
<description><![CDATA[<p>So, 2003 is about to be history. Quite an eventful year for me I'd say. I quit <a href="http://www.lecando.com">Lecando</a> (great company though, if you get the chance to work there, do it!) and started on <a href="http://www.thoughtworks.com">ThoughtWorks</a> and moved from Stockholm to London.</p>

<p><a href="http://nanning.codehaus.org">Nanning</a> is almost ready for a 1.0 release. I started working with <a href="http://www.picocontainer.org">PicoContainer</a> with <a href="http://paulhammant.com/blog/">Paul</a> and <a href="http://blogs.codehaus.org/people/rinkrank/">Aslak</a>. That and <a href="http://damagecontrol.codehaus.org">DamageControl</a> (still kind of a secret project) is taking most of my open-source time at the moment.</p>

<p>I also learned <a href="http://www.ruby-lang.org">Ruby</a> which is really an amazing language! If you get the chance, do learn it. I suspect it will get a lot more attention in the year to come. It's like the bastard child of Perl and Smalltalk (with a pinch of Common Lisp on the side)! Lovely! Hopefully <a href="http://groovy.codehaus.org">Groovy</a> will take off too, so Java development becomes endurable in a post-Ruby state-of-mind. Strong typing!? Pfft, it's for wimps!</p>

<p>The move to London and all the new experiences that comes from living in probably the most happening open-source cities of the world has completely exhausted my inspiration for blogging. Hopefully that will change in the next year. (I've actually got a couple of entries that never got through enough touch-ups to be in a publish-ready state.)</p>

<p>Anyways, happy new year!</p>

<p>And with those words let's give a thought to the people in Iran. What can you say? Terrible, terrible.</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2003-12-31T20:05:22+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000189_hausparty_first_annual_codehaus_conference_in_amsterdam_this_weekend.html">
<title>Hausparty, first (annual?) Codehaus conference in Amsterdam this weekend</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000189_hausparty_first_annual_codehaus_conference_in_amsterdam_this_weekend.html</link>
<description><![CDATA[<p>Yep, the first Codehaus conference is of this weekend in Amsterdam. I'll be there, so will Joe, Bob, Paul, Chris, Aslak and more. We'll be discussing plans for world domination and the new Ruby movement within Codehaus. Expect updates here.</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2003-10-03T10:50:05+00:00</dc:date>
</item>
<item rdf:about="http://blogs.codehaus.org/people/tirsen/archives/000129_new_jutopia.html">
<title>New jutopia</title>
<link>http://blogs.codehaus.org/people/tirsen/archives/000129_new_jutopia.html</link>
<description><![CDATA[<p>I've moved off Freeroller and into Codehaus. Here's the new Jutopia blog.</p>]]></description>
<dc:subject></dc:subject>
<dc:creator>tirsen</dc:creator>
<dc:date>2003-08-22T15:03:27+00:00</dc:date>
</item>


</rdf:RDF>
