<?xml version="1.0"?><!-- RSS generated by Radio UserLand v8.2.1 on Sun, 27 Nov 2005 03:33:58 GMT --><rss version="2.0">	<channel>		<title>Nick Sieger: software engineering</title>		<link>http://radio.weblogs.com/0141460/categories/softwareEngineering/</link>		<description>Software engineering, patterns, programming.</description>		<language>en</language>		<copyright>Copyright 2005 Nick Sieger</copyright>		<lastBuildDate>Sun, 27 Nov 2005 03:33:58 GMT</lastBuildDate>		<docs>http://backend.userland.com/rss</docs>		<generator>Radio UserLand v8.2.1</generator>		<managingEditor>nsieger@bitstream.net</managingEditor>		<webMaster>nsieger@bitstream.net</webMaster>		<category domain="http://www.weblogs.com/rssUpdates/changes.xml">rssUpdates</category> 		<skipHours>			<hour>23</hour>			<hour>0</hour>			<hour>3</hour>			<hour>4</hour>			<hour>5</hour>			<hour>17</hour>			<hour>2</hour>			<hour>1</hour>			</skipHours>		<cloud domain="radio.xmlstoragesystem.com" port="80" path="/RPC2" registerProcedure="xmlStorageSystem.rssPleaseNotify" protocol="xml-rpc"/>		<ttl>60</ttl>		<item>			<title>Maven-proxy in ruby</title>			<link>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/11/26.html#a91</link>			<description>&lt;p&gt;Lothar M&amp;auml;rkle has a neat little &lt;a href=&quot;http://mountproc.org/JSPWiki/Wiki.jsp?page=Maven&quot;&gt;perl CGI substitute&lt;/a&gt; for &lt;a href=&quot;http://maven-proxy.codehaus.org/&quot;&gt;Maven proxy&lt;/a&gt;.  I started to use it to build up a Maven 2 repository at work for our Maven 2 builds.  Only when it wasn&apos;t quite behaving as I expected, I really didn&apos;t want to brush up my perl skills to debug it.  Why do that when you can spend an afternoon polishing up a ruby version?&lt;/p&gt;&lt;p&gt;So here&apos;s &lt;a href=&quot;/0141460/gems/maven-proxy.html&quot;&gt;maven-proxy.rb, version 1.0&lt;/a&gt; (&lt;a href=&quot;/0141460/gems/maven-proxy.rb.zip&quot;&gt;download zip&lt;/a&gt;).  Check it out, I think I baked in a couple extra neat features, including the ability to transparently navigate remote, uncached directories from your local repository.  I also gave an example Apache configuration to let Apache serve the cached content while deferring to the CGI for the remote, uncached resources.  It&apos;s licensed under an MIT-style license, so I only ask that you give me credit (or blame) for the original code :)&lt;/p&gt;&lt;p&gt;If you ask me, this is better than running the original maven-proxy under Tomcat...&lt;/p&gt;&lt;p&gt;Happy Holidays!&lt;/p&gt;</description>			<guid>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/11/26.html#a91</guid>			<pubDate>Sat, 26 Nov 2005 22:57:05 GMT</pubDate>			<comments>http://radiocomments2.userland.com/comments?u=141460&amp;amp;p=91&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0141460%2F2005%2F11%2F26.html%23a91</comments>			</item>		<item>			<title>Microsoft, Competition and the Right Fork</title>			<link>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/09/13.html#a89</link>			<description>&lt;p&gt;So, it turned out to be a well-timed &lt;ahref=&quot;http://gillmorgang.podshow.com/?p=15&quot;&gt;Gillmor Gang&lt;/a&gt; this weekfor me, as I started listening to it on the same day as the &lt;ahref=&quot;http://msdn.microsoft.com/events/pdc/&quot;&gt;PDC keynotes&lt;/a&gt; were &lt;ahref=&quot;http://www.microsoft.com/events/executives/billgates.mspx&quot;&gt;webcast&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;It seems that Microsoft is fast approaching a fork-in-the-road.The left fork represents the illusion of continued desktop dominancefueled by Wall Street hunger for &lt;ahref=&quot;http://kasparov.skife.org/blog/tech/i-want-a-monopoly.html&quot;&gt;sky-highprofit margins&lt;/a&gt; in the Windows and Office businesses, and is verymuch grounded in the 20th-century Microsoft.  The right forkrepresents the future of the company, battling for market share in aWeb 2.0 world, innovating both in the rich client and web applicationarenas, playing fair by creating and building open standards, anddoing all of this in such a way that the end user comes out thewinner.&lt;/p&gt;&lt;p&gt;So which way will they go?  Where&apos;s the new revenue model in the openworld of the web when your sacrifice your existing business to getthere?  That&apos;s the big white elephant in the room at PDC.&lt;/p&gt;&lt;p&gt;Microsoft, stop charging for the tools.  If Avalon, Indigo, Atlas,LINQ, Max and all the other goodies being dangled in front ofdevelopers this week are to ever gain any widespread adoption, theyneed to be accessible to the hobbyists out there.  Give away IIS.  IfApache is already free, what incentive is there to run IIS?  Give awaySQL Server, to at least level the playing field with MySQL.  Give awayVisual Studio, allow companies to develop and deploy ASP.NET andIndigo applications to their heart&apos;s content.  Make it possible forthe hacker in the basement (i.e., me) who&apos;s taken up Ruby on Rails totry your way of building web apps.&lt;/p&gt;&lt;p&gt;Jon Udell tells a &lt;ahref=&quot;http://weblog.infoworld.com/udell/2005/06/14.html&quot;&gt;goodstory&lt;/a&gt; in the Gang podcast of the difference between TerraServerand Google Maps.  TerraServer has been out for years, has a publicAPI, and yet has not inspired innovation or remixing in the way thatGoogle Maps has.  The conclusion was that Microsoft has too longfocused on the developer as a professional ISV.  In this scenario, theISV is just a middleman preventing and stifling user innovation because thecycle is too lengthy.  By the time developers have gotten around tobuilding and distributing apps and getting some level of useradoption, there&apos;s no where left and no reason for the user to innovate-- it&apos;s too late.  Of course, user customization and innovation iswhat the new 21st century web is all about.&lt;/p&gt;&lt;p&gt;So, Microsoft, take that leap of faith, get your stuff out there,gain adoption through cool, fun, programmer-friendly, easy-to-usetools and an open platform.  Compete based on speed of innovation andthe ability to retain a user base through that innovation withoutlocking them in.  Choice is what builds trust.&lt;/p&gt;&lt;p&gt;Take the Right Fork.&lt;/p&gt;</description>			<guid>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/09/13.html#a89</guid>			<pubDate>Wed, 14 Sep 2005 02:43:21 GMT</pubDate>			<comments>http://radiocomments2.userland.com/comments?u=141460&amp;amp;p=89&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0141460%2F2005%2F09%2F13.html%23a89</comments>			</item>		<item>			<title>Using Drools, If It Weren&apos;t For All That Bloody XML</title>			<link>http://www.onjava.com/pub/a/onjava/2005/08/24/drools.html?page=4</link>			<description>&lt;p&gt;Rule engines, at the outset, appear to be a nifty concept formaking Java applications more late-bound, dynamic and configurable.Drools in particular even seems to be getting some traction as I&apos;veseen in mentioned several times over the past few weeks.  But why, ohwhy do they insist on the angly-bracket, ugly XML syntax?&lt;/p&gt;&lt;p&gt;Maybe I&apos;m just a &lt;ahref=&quot;http://kasparov.skife.org/blog-live/src/java/bpelscript.writeback&quot;&gt;Ruby-as-platform-for-building-DSLs&lt;/a&gt;&lt;ahref=&quot;http://www.vanderburg.org/Blog/Software/Languages/Ruby/oscon_slides.rdoc&quot;&gt;convert&lt;/a&gt;,but doesn&apos;t this seem a whole lot more readable than that &lt;ahref=&quot;http://www.onjava.com/pub/a/onjava/2005/08/24/drools.html?page=4&quot;&gt;messof XML&lt;/a&gt; that Drools uses?&lt;/p&gt;&lt;pre&gt;require &lt;span class=&quot;string&quot;&gt;&apos;drools&apos;&lt;/span&gt;require &lt;span class=&quot;string&quot;&gt;&apos;daofactory&apos;&lt;/span&gt;require &lt;span class=&quot;string&quot;&gt;&apos;stockoffer&apos;&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;StockOffer&lt;/span&gt;  &lt;span class=&quot;keyword&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;function-name&quot;&gt;print&lt;/span&gt;    p &lt;span class=&quot;string&quot;&gt;&amp;quot;Name: &lt;/span&gt;&lt;span class=&quot;variable-name&quot;&gt;#{@name}&lt;/span&gt;&lt;span class=&quot;string&quot;&gt; Price: &lt;/span&gt;&lt;span class=&quot;variable-name&quot;&gt;#{@price}&lt;/span&gt;&lt;span class=&quot;string&quot;&gt; BUY: &lt;/span&gt;&lt;span class=&quot;variable-name&quot;&gt;#{@recommend_purchase}&lt;/span&gt;&lt;span class=&quot;string&quot;&gt;&amp;quot;&lt;/span&gt;  &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;type&quot;&gt;BusinessRulesSample&lt;/span&gt; &amp;lt; &lt;span class=&quot;type&quot;&gt;Drools&lt;/span&gt;::&lt;span class=&quot;type&quot;&gt;RuleSet&lt;/span&gt;  application_data &lt;span class=&quot;type&quot;&gt;DaoFactory&lt;/span&gt;  rule &lt;span class=&quot;string&quot;&gt;&amp;quot;XYZCorp&amp;quot;&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt; |rule|    rule.accepts &lt;span class=&quot;type&quot;&gt;StockOffer&lt;/span&gt;    rule.salience = &lt;span class=&quot;string&quot;&gt;&amp;quot;-1&amp;quot;&lt;/span&gt;    rule.condition {|stock| stock.name == &lt;span class=&quot;string&quot;&gt;&amp;quot;XYZ&amp;quot;&lt;/span&gt; }    rule.condition {|stock| stock.recommend_purchase.nil? }    rule.condition {|stock| stock.price &amp;gt; 10 }    rule.consequence &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt; |stock|      stock.recommend_purchase = &lt;span class=&quot;constant&quot;&gt;:no&lt;/span&gt;      stock.print    &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;  &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;  rule &lt;span class=&quot;string&quot;&gt;&amp;quot;Stock Price Not Negative&amp;quot;&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt; |rule|    rule.accepts &lt;span class=&quot;type&quot;&gt;StockOffer&lt;/span&gt;    rule.condition {|stock| stock.price &amp;lt; 0 }    rule.consequence &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt; |stock|      stock.recommend_purchase = &lt;span class=&quot;constant&quot;&gt;:no&lt;/span&gt;      stock.print    &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;  &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;  rule &lt;span class=&quot;string&quot;&gt;&amp;quot;Stock Price Low Enough&amp;quot;&lt;/span&gt; &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt; |rule|    rule.accepts &lt;span class=&quot;type&quot;&gt;StockOffer&lt;/span&gt;    rule.condition {|stock| &lt;span class=&quot;variable-name&quot;&gt;@dao_factory&lt;/span&gt;.stock_dao.on_stock_list? stock.name }    rule.condition {|stock| stock.recommend_purchase.nil? }    rule.condition {|stock| stock.price &amp;lt; 100 }    rule.consequence &lt;span class=&quot;keyword&quot;&gt;do&lt;/span&gt; |stock|      stock.recommend_purchase = &lt;span class=&quot;constant&quot;&gt;:yes&lt;/span&gt;      stock.print    &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;  &lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;end&lt;/span&gt;&lt;/pre&gt;</description>			<guid>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/09/02.html#a88</guid>			<pubDate>Sat, 03 Sep 2005 04:23:31 GMT</pubDate>			<comments>http://radiocomments2.userland.com/comments?u=141460&amp;amp;p=88&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0141460%2F2005%2F09%2F02.html%23a88</comments>			</item>		<item>			<title>Goodbye OSCON</title>			<link>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/08/06.html#a85</link>			<description>&lt;p&gt;What a whirlwind week at &lt;a href=&quot;http://conferences.oreilly.com/os2005&quot;&gt;OSCON&lt;/a&gt;!  I&apos;m still spinning and trying to catch up on sleep the day after getting back home from my first O&apos;Reilly conference experience.&lt;/p&gt;&lt;p&gt;For me, the main themes this week were Java, Ruby, Ajax/Remote scripting and Subversion.  I have some skeleton outline notes from several more talks that I&apos;ll put online shortly at &lt;a href=&quot;http://blogs.opml.org/nick/&quot;&gt;my OPML blog&lt;/a&gt;.  I&apos;m still too overwhelmed to form these into fully coherent thoughts, and each could easily generate multiple blog postings.&lt;/p&gt;&lt;p&gt;Off the top of my head, here are a few random thoughts that were floating through my head this week:&lt;/p&gt;&lt;ul&gt; &lt;li&gt;If you want to meet the best hackers in the world, come to OSCON.  Open source programmers are the most passionate of their kind, and where there&apos;s passion there&apos;s intelligence, community and great ideas.&lt;/li&gt; &lt;li&gt;If you want to hire the best hackers in the world, come to OSCON.  The networking opportunities are absolutely incredible -- I was blown away.  Now actually convincing a hacker to come work for you is a different story.  It would help if your business had some kind of open source strategy, so that the hacker can continue to participate in the community and give back what he or she works on at your company.  Non-open-sourcers will find it unreal, but it is possible to contribute to an open source community and still receive a lot of business ROI from the exchange.  Paul Graham is quite possibly the most articulate speaker you could find on this subject.  I was at his &lt;a href=&quot;http://paulgraham.com/opensource.html&quot;&gt;What Business Can Learn From Open Source&lt;/a&gt; keynote and it immediately struck me as great fodder for discussion at the cube farms back at work.&lt;/li&gt; &lt;li&gt;&lt;a href=&quot;http://www.csse.monash.edu.au/~damian/&quot;&gt;Damian Conway&lt;/a&gt; is an &lt;a href=&quot;http://www.csse.monash.edu.au/~damian/papers/HTML/Perligata.html&quot;&gt;evil&lt;/a&gt; &lt;a href=&quot;http://conferences.oreillynet.com/pub/w/38/events.html&quot;&gt;genius&lt;/a&gt;.  And his arch &lt;a href=&quot;http://conferences.oreillynet.com/cs/os2005/view/e_sess/7176&quot;&gt;nemesis&lt;/a&gt; may be &lt;a href=&quot;http://www.ntk.net/&quot;&gt;Danny O&apos;Brien&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;As I mentioned it was my first time at OSCON, and I was really surprised to find the whole OSCON community extremely friendly and receptive.  I never sensed any elitist attitudes (not that there probably aren&apos;t any here or there) and never felt like an outsider.  To me, it&apos;s important that the community retain this sense of welcoming and open-ness so that we can further the cause and be better positioned to promote change for good in the world.&lt;/li&gt; &lt;li&gt;Ruby is a super cool language, but it&apos;s not a panacea.  There is still lots of room for growth in the language.  During Matz&apos;s talk he mentioned that he wants to implement a sealing feature of some kind so that some Ruby code could be locked down or scoped to a single file only (unlike the current implementation where you can change any class, anywhere, on the fly).  Ruby still seems a year or two away from fuller adoption in the enterprise, although that&apos;s not going to stop me from trying to use it.&lt;/li&gt; &lt;li&gt;Likewise, Java&apos;s not dead either.  The same players in the Java open source community are around and are still committed to the language.  However, the politics can tend to get a bit more ugly.&lt;/li&gt; &lt;li&gt;Subversion is ready for primetime and I can&apos;t wait to roll it out at work.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Like I said, my head is still reeling and my blood still pumping after a high-octane week.  I&apos;m looking forward to stepping up my involvment in the open source community and I hope to maintain contact with all the folks I had the pleasure of meeting during the conference.  Cheers!&lt;/p&gt;</description>			<guid>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/08/06.html#a85</guid>			<pubDate>Sat, 06 Aug 2005 21:27:27 GMT</pubDate>			<comments>http://radiocomments2.userland.com/comments?u=141460&amp;amp;p=85&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0141460%2F2005%2F08%2F06.html%23a85</comments>			</item>		<item>			<title>Ruby on rails trials on OS X</title>			<link>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/05/24.html#a79</link>			<description>&lt;p&gt;Finally sitting down play with rails on OS X.  I had previously built Ruby 1.8.2 from source and installed into /usr/bin on top of OS X&apos;s default ruby -- seemed to work fine.  Now, just upgraded to Tiger last weekend, got as far as creating a new rails model, when I got a nifty little error:&lt;/p&gt;&lt;pre&gt;Access denied for user: &apos;&lt;a href=&quot;mailto:root@localhost&quot;&gt;root@localhost&lt;/a&gt;&apos; (Using password: YES)&lt;/pre&gt;&lt;p&gt;Seems that Tiger broke ruby for &lt;a href=&quot;http://weblog.textdrive.com/article/61/grabbing-a-tiger-by-the-tail&quot;&gt;more&lt;/a&gt; &lt;a href=&quot;http://tech.rufy.com/entry/46&quot;&gt;folks&lt;/a&gt; than just me.&lt;/p&gt;&lt;p&gt;Whiz-bang-crash, several packages later...&lt;/p&gt;&lt;ul&gt;&lt;li&gt;fix-ruby-tiger.sh from above&lt;/li&gt;&lt;li&gt;download, build and install fastcgi&lt;/li&gt;&lt;li&gt;download and install MySQL 4.1.12 from an OSX binary package&lt;/li&gt;&lt;li&gt;download, build and install mod_fastcgi (apxs works!)&lt;/li&gt;&lt;li&gt;install mysql gem (&lt;tt&gt;gem install mysql -- --with-mysql-include=/usr/local/mysql/include --with-mysql-lib=/usr/local/mysql/lib&lt;/tt&gt;)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;So far, so good, but haven&apos;t reached the kicker yet...what amazes me though through this whole process is how transparent it all is.  It&apos;s happening on a Mac, but it&apos;s all good ol&apos; FOSS that &lt;tt&gt;configure &amp;&amp; make &amp;&amp; make install&lt;/tt&gt;&apos;s as good as on any other box (except XP :).&lt;/p&gt;</description>			<guid>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/05/24.html#a79</guid>			<pubDate>Wed, 25 May 2005 04:35:58 GMT</pubDate>			<comments>http://radiocomments2.userland.com/comments?u=141460&amp;amp;p=79&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0141460%2F2005%2F05%2F24.html%23a79</comments>			</item>		<item>			<title>A java webservice toolkit (and it&apos;s name does not begin with A)</title>			<link>http://java.sun.com/webservices/index.jsp</link>			<description>&lt;p&gt;Just recently started work on a project which requires the use of WS-Security.  I was initially skeptical about the whole WS-* stack in general, especially with the &lt;a href=&quot;http://lists.xml.org/archives/xml-dev/200503/msg00468.html&quot;&gt;REST/SOAP debate&lt;/a&gt; that&apos;s so hot recently.  My own design philosophy favors simplicity anyway, and just trying to follow the WS-* specs makes me dizzy.&lt;/p&gt;&lt;p&gt;So imagine my surprise when I stumble across &lt;a href=&quot;http://java.sun.com/webservices/index.jsp&quot;&gt;Sun&apos;s webservices stack!&lt;/a&gt;  Why didn&apos;t I think to look to the gatekeeper of Java?  Because it didn&apos;t come from &lt;a href=&quot;http://www.apache.org&quot;&gt;Apache&lt;/a&gt; or the &lt;a href=&quot;http://www.codehaus.org&quot;&gt;the Codehaus&lt;/a&gt;? (&lt;a href=&quot;http://www.jroller.com/page/fate&quot;&gt;Hani&lt;/a&gt; would laugh at that one.)  I had been using trusty &lt;a href=&quot;http://ws.apache.org/axis/&quot;&gt;Axis&lt;/a&gt; for well over a year now, but &lt;a href=&quot;http://ws.apache.org/ws-fx/wss4j/&quot;&gt;WSS4J&lt;/a&gt; is lagging behind and doesn&apos;t even have any downloadable release out.  Worse, I&apos;d be forced to upgrade to the yet-to-be-released Axis 1.2?  Thank you Sun, no thanks, Apache.&lt;/p&gt;&lt;p&gt;Oh, and what&apos;s this?  &lt;a href=&quot;http://java.sun.com/webservices/docs/1.4/tutorial/doc/XWS-Security6.html&quot;&gt;Sun&lt;/a&gt; and &lt;a href=&quot;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnbda/html/interopsun.asp&quot;&gt;Microsoft&lt;/a&gt; are playing well with each other?  We&apos;ll see shortly just how true that is.&lt;/p&gt;</description>			<guid>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/04/07.html#a75</guid>			<pubDate>Thu, 07 Apr 2005 16:22:28 GMT</pubDate>			<comments>http://radiocomments2.userland.com/comments?u=141460&amp;amp;p=75&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0141460%2F2005%2F04%2F07.html%23a75</comments>			</item>		<item>			<title>Holub&apos;s axiom</title>			<link>http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html</link>			<description>&lt;p&gt;From an old &lt;a href=&quot;http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html&quot;&gt;javaworld article&lt;/a&gt; I ran across from &lt;a href=&quot;http://www.holub.com/&quot;&gt;Allen Holub&lt;/a&gt;:&lt;/p&gt;&lt;blockquote&gt;...maintainability is inversely proportionate to the amount of data that moves between objects.&lt;/blockquote&gt;</description>			<guid>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/03/23.html#a71</guid>			<pubDate>Thu, 24 Mar 2005 04:56:13 GMT</pubDate>			<comments>http://radiocomments2.userland.com/comments?u=141460&amp;amp;p=71&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0141460%2F2005%2F03%2F23.html%23a71</comments>			</item>		<item>			<title>Increasing coverage and refactorability in legacy code</title>			<link>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/03/18.html#a70</link>			<description>&lt;p&gt;It&apos;s been over a month since I said I&apos;d write more about &lt;a href=&quot;http://radio.weblogs.com/0141460/2005/02/10.html#a51&quot;&gt;Increasing coverage and refactorability for code with no unit tests&lt;/a&gt;, so here&apos;s my shot.&lt;/p&gt;&lt;p&gt;So here&apos;s the scenario:  You&apos;re faced with trying to improve a large body of existing code with few to zero unit tests.  The code itself is fairly monolithic, has a high degree of coupling, and maybe has an abuse of singletons, static registries or factories and too much &quot;new&quot; operator on large service components that make it really difficult to test a single class at a time.&lt;/p&gt;&lt;p&gt;To make matters worse, methods are large, the business logic isn&apos;t clear, the original requirements that drove the code (if any) aren&apos;t available.  It&apos;s a tangled mess!  Do you &lt;a href=&quot;http://c2.com/cgi/wiki?HaveThisPattern&quot;&gt;Have This (Anti-) Pattern&lt;/a&gt;?&lt;/p&gt;&lt;p&gt;So all I have is a hypothesis and some intuition, but here&apos;s the general sequence of actions that, if taken, may go some of the way toward solving the problem of increasing coverage and making it easier to refactor legacy code.  The central tool in your toolbox for making this happen is none other than &lt;a href=&quot;http://fit.c2.com/wiki.cgi?WelcomeVisitors&quot;&gt;FIT&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;What you&apos;re using FIT for in this case is for a higher-level testing tool to get some coverage for business cases that you may be able to discover, hopefully by finding and talking to a business expert.  Using FIT allows you to automate the tests and get faster feedback than you would having to manually click through interfaces in your application.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Start to write a FIT test page that covers an aspect of the code you&apos;re targeting for increased coverage.&lt;/li&gt;&lt;li&gt;Start writing the &lt;a href=&quot;http://fit.c2.com/wiki.cgi?FieldGuideToFixtures&quot;&gt;FIT fixtures&lt;/a&gt; that will enable you to run the test.  (If you&apos;re suffering from another anti-pattern of having too much application logic inside your MVC layer, you&apos;ll find that if you&apos;re writing action fixtures, during this stage you may have to duplicate large chunks of application logic that you have to cut and paste from models and/or controllers.  Add another item to your list to clean up later.)&lt;/li&gt;&lt;li&gt;Run the test(s).&lt;/li&gt;&lt;li&gt;If possible, use a coverage tool such as &lt;a href=&quot;http://www.cenqua.com/clover/&quot;&gt;Clover&lt;/a&gt; to see how much coverage you were able to buy with your tests.  Now you have a concrete metric for what code you may be able to refactor.&lt;/li&gt;&lt;li&gt;Refactor mercilessly on the code within the coverage zone, treading lightly on code that is not covered.&lt;/li&gt;&lt;li&gt;Re-run the tests to make sure you haven&apos;t changed any behavior.&lt;/li&gt;&lt;li&gt;Once you&apos;ve refactored a reasonably small, unit-testable component out of the quagmire, write a unit test for it.  You still want a unit test to cover your code in the long run as this will allow you to develop and improve the code even more quickly than you can with FIT.&lt;/li&gt;&lt;li&gt;Repeat the entire cycle to spread out and cover other areas.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;I haven&apos;t yet had an opportunity to put this to practice myself, but I&apos;d be interested to hear if anyone else has tried something similar.  If you have, drop a comment!&lt;/p&gt;</description>			<guid>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/03/18.html#a70</guid>			<pubDate>Sat, 19 Mar 2005 04:01:44 GMT</pubDate>			<comments>http://radiocomments2.userland.com/comments?u=141460&amp;amp;p=70&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0141460%2F2005%2F03%2F18.html%23a70</comments>			</item>		<item>			<title>Postel, for my own posterity</title>			<link>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/03/09.html#a68</link>			<description>&lt;p&gt;&lt;a href=&quot;http://www.manageability.org&quot;&gt;Carlos&lt;/a&gt; recently again &lt;a href=&quot;http://www.manageability.org/blog/stuff/why-rest-part-3&quot;&gt;referenced &lt;/a&gt; &lt;a href=&quot;http://www.google.com/search/q?postel%27s+law&quot;&gt;Postel&apos;s Law&lt;/a&gt;, which basically goes,&lt;/p&gt;&lt;blockquote&gt;&lt;i&gt;Be liberal in what you accept, and conservative in what you send.&lt;/i&gt;&lt;/blockquote&gt;&lt;p&gt;I have probably heard this somewhere before, but anyway just wanted to jot it down for reference.&lt;/p&gt;&lt;p&gt;But as the &lt;a href=&quot;http://www.google.com/search/q?postel%27s+law&quot;&gt;query results&lt;/a&gt; show, there was quite a storm in the blogosphere around Postel&apos;s law a little over a year ago.  It appeared to be no more than a squabble about how liberal is &amp;quot;liberal&amp;quot;.  (Reminds me of Clinton: &amp;quot;...depends upon what the meaning of &amp;apos;is&amp;apos; is...&amp;quot;)&lt;/p&gt;&lt;p&gt;My personal view is that you should only bend over far enough and with enough common sense to fill in the blanks.  &lt;a href=&quot;http://www.w3.org/TR/REC-xml/&quot;&gt;XML well-formed-ness&lt;/a&gt; has been a known quantity for some time; I still have a hard time seeing the argument why anyone would want to be so liberal as to accept non-well-formed XML.  Sure, it happened with early HTML and the web, but was HTML that well defined during the early days of the web?&lt;/p&gt;</description>			<guid>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/03/09.html#a68</guid>			<pubDate>Thu, 10 Mar 2005 03:28:21 GMT</pubDate>			<comments>http://radiocomments2.userland.com/comments?u=141460&amp;amp;p=68&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0141460%2F2005%2F03%2F09.html%23a68</comments>			</item>		<item>			<title>Freemind and WSDL</title>			<link>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/03/01.html#a66</link>			<description>&lt;p&gt;I&apos;m experimenting more and more with &lt;a href=&quot;http://freemind.sourceforge.net/wiki/index.php/Main_Page&quot;&gt;Freemind&lt;/a&gt; as a visualization tool.  This time with WSDL.  I&apos;ve taken the &lt;a href=&quot;http://soap.amazon.com/schemas2/AmazonWebServices.wsdl&quot;&gt;Amazon Web Services WSDL&lt;/a&gt; and applied &lt;a href=&quot;http://radio.weblogs.com/0141460/gems/wsdl2mm.xsl&quot;&gt;this XSL transform&lt;/a&gt; to produce the following Freemind map:&lt;/p&gt;&lt;p&gt;(Browseable applet coming soon I hope, but for now here&apos;s a screenshot)&lt;br/&gt;&lt;!-- applet broken&lt;applet code=&quot;freemind.main.FreeMindApplet.class&quot;	archive=&quot;http://radio.weblogs.com/0141460/gems/freemindbrowser.zip&quot; width=&quot;320&quot; height=&quot;240&quot;&gt;	&lt;param name=&quot;type&quot; value=&quot;application/x-java-applet;version=1.4&quot;&gt;	&lt;param name=&quot;scriptable&quot; value=&quot;false&quot;&gt;	&lt;param name=&quot;modes&quot; value=&quot;freemind.modes.browsemode.BrowseMode&quot;&gt;	&lt;param name=&quot;browsemode_initial_map&quot;		value=&quot;http://radio.weblogs.com/0141460/gems/Amazon.xml&quot;&gt;	&lt;param name=&quot;initial_mode&quot; value=&quot;Browse&quot;&gt;	&lt;param name=&quot;selection_method&quot; value=&quot;selection_method_direct&quot;&gt;&lt;/applet&gt;--&gt;&lt;a href=&quot;http://radio.weblogs.com/0141460/gems/Amazon.png&quot;&gt;&lt;img src=&quot;http://radio.weblogs.com/0141460/gems/Amazon.png&quot; width=&quot;50%&quot;/&gt;&lt;/a&gt;&lt;/p&gt;</description>			<guid>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/03/01.html#a66</guid>			<pubDate>Wed, 02 Mar 2005 04:31:13 GMT</pubDate>			<comments>http://radiocomments2.userland.com/comments?u=141460&amp;amp;p=66&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0141460%2F2005%2F03%2F01.html%23a66</comments>			</item>		<item>			<title>Evolutionary database applications</title>			<link>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/02/25.html#a65</link>			<description>&lt;p&gt;Brian had a comment for clarification on &lt;a href=&quot;http://radio.weblogs.com/0141460/2005/02/22.html#a59&quot;&gt;Quote and database evolution&lt;/a&gt; that I thoughtI&apos;d take the time to clarify.  I said:&lt;/p&gt;&lt;blockquote&gt;It&apos;s intriguing to me that the application I&apos;ve worked on for going on fouryears as well as my own perception of what has worked well over that timeframe hasfollowed a pretty similar evolution as what Brian describes in his rant aboutdatabases.&lt;/blockquote&gt;&lt;p&gt;...to which Brian asked:&lt;/p&gt;&lt;blockquote&gt;In terms of what you did with it, or level of frustration at building thingsaround the problem instead of solving problem?&lt;/blockquote&gt;&lt;p&gt;I&apos;d have to say what we did with it.  I&apos;m feeling the need to tell a story here, bearwith me...&lt;/p&gt;&lt;p&gt;I feel like the application has turned out well from a technical standpoint preciselybecause we were in a position early on to build on the database without making it thefocal point of the application.  This is in contrast to some of the other applications inproduction at our company.  One of the older applications is written almost entirely inPL/SQL, so there was an obvious database focus there and the development culture thatsprung up around it was such that, for a while, the DBAs were king and the programmers hadto answer to them.&lt;/p&gt;&lt;p&gt;It seems like a fluke that our app turned out the way it is.  There were a lot offactors that played into this over time, many of them cultural/non-technical.Fortunately, early on we somehow had the leeway to build away for the database.  Becausewe were almost starting greenfield, we didn&apos;t have to initially deal too much with theDBAs, since they were occupied with maintaining the production databases.&lt;/p&gt;&lt;p&gt;The app wasn&apos;t exactly greenfield because we were building off a newly-acquiredcodebase, but it still needed plenty of work.  The codebase had a horrible proprietarypersistence mechansim that included an infamous &lt;ahref=&quot;http://c2.com/cgi/wiki?MagicContainer&quot;&gt;&amp;quot;magic container&amp;quot;&lt;/a&gt; table called&lt;code&gt;MHASHTABLE&lt;/code&gt; that held all associative relationships for every object in thesystem (!).  Because this would obviously not scale for a consumer-facing hosted commerceengine that had to be capable of serving tens of thousands of transactions per day (thinkof the rate of growth of that table!), we had to rip it all out and re-do the persistencelayer.  Basically anything we might come up with would probably be better than this beast,so perhaps we were left to just do our thing.&lt;/p&gt;&lt;p&gt;Our architect at the time was following persistence technologies trying to get an ideaof what direction to go in, and JDO as a standard was just coming out (0.9 in the fall of2001).  The only viable alternatives were expensive, proprietary tools like TopLink.After some brief prototyping, we decided to build our own SQL JDO implementation.&lt;/p&gt;&lt;p&gt;One of the loose requirements that the DBAs did give is that they needed to be able tohave control over the queries.  They thought that they would get some sort of set ofconfiguration files containing query templates that they could tweak to their hearts&apos;content.  Instead, we gave them JDO, with fetch groups and dynamic SQL generation.  Afterthey saw how well it worked, they didn&apos;t bother to complain about the lesser amount ofcontrol they got.  The SQL, though dynamic, was predictable, uniform, and based uponprimary keys or indexable &amp;quot;pseudo&amp;quot; foreign keys.  (Pseudo- because we actuallyhave no foreign key constraints at all on our tables for better insert performance and sowe don&apos;t have to worry about proper ordering of deletes.  Once, when giving an overview ofour JDO-based persistence to a new DBA, her mind was blown away at that fact -- itapparently went against everything she learned about building databases!)&lt;/p&gt;&lt;p&gt;We were able to build the JDO implementation in an evolutionary way to match thegrowing, changing needs of the application.  As a result, we don&apos;t quite have afull-featured, to-spec implementation, but we don&apos;t need it.  There are quirks in the waywe do things like complex subqueries or inheritance (I had no prior background in O/Rmapping and basically learned on the fly), but we&apos;ve got enough features (most of JDOQL,bytecode enhancement) to give an approximation of transparent persistence.  In all myexperience as a developer the amount of transparency we were able to create with our JDOimplementation is probably one of the slicker things that I&apos;ve had a hand in building.  Itwas transparent enough to allow the rest of the development team to not have to worryabout how to persist their objects, to have to remember what the proper way is to close aJDBC connection; but opaque enough so that we could performance tune it to our needs.There were some tough times when develpers would encounter a bug in the JDO engine thatthey&apos;d have no idea what was going on, but today the codebase is so stable that it&apos;shardly an issue.&lt;/p&gt;&lt;p&gt;(As a brief aside I still don&apos;t think I&apos;d advocate building your own persistenceengine, especially today with all the open source options available, but for us it was theright thing to do at the time and we were able to make it work well for us.)&lt;/p&gt;&lt;p&gt;So, with that long yarn I don&apos;t know if I completely answered your question Brian, butthe main takeaway for me is that I&apos;ve seen both sides of the fence, but I much prefer theside that I&apos;m on with the database only playing a supporting role in the functioning ofour app. &lt;/p&gt;&lt;p&gt;There&apos;s a thread in my mind somewhere here about the crucial importance of being ableto do evolutionary application development (as opposed to big-bang or in-a-vacuumdevelopment) in which environment of course the database (and the &amp;quot;DeeBeeAies&amp;quot;)must play well, but I&apos;ll leave that thought for another day. &lt;/p&gt;</description>			<guid>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/02/25.html#a65</guid>			<pubDate>Sat, 26 Feb 2005 04:43:58 GMT</pubDate>			<comments>http://radiocomments2.userland.com/comments?u=141460&amp;amp;p=65&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0141460%2F2005%2F02%2F25.html%23a65</comments>			</item>		<item>			<title>The Java Platform</title>			<link>http://rmh.blogs.com/weblog/2005/02/this_is_java.html</link>			<description>&lt;p&gt;&lt;a href=&quot;http://rmh.blogs.com/weblog/&quot;&gt;RMH&lt;/a&gt; is writing a book about the &quot;Java Platform&quot;.  It&apos;s not just any book, and I applaud him for taking the particular step of saying it&apos;s not a for-profit venture and it&apos;s not going to be a traditionally organized, TOC&apos;d and outlined book.  (Although he may as well just collect blog posts about the java platform for a period of time and collect them together and say &quot;This is Java&quot;.)&lt;/p&gt;&lt;p&gt;One thing in particular in his preface struck me -- the mention of J2ME and J2EE not being long on the world.  I think this is sensible; more and more people are finding great ways of innovating on the core JVM and language platform itself, the Groovies and AspectJs and CGLIBs and Picocontainers of the world are all based on the core J2SE platform.  J2EE is just Sun&apos;s officially sanctioned way of building enterprise applications.  Beyond perhaps .war and web.xml files, there&apos;s really not much else in J2EE that will have a long life in the Java world (although any BEA-er, JBossian, Oracle-ite or IBMian appserver vendor would like to tell you otherwise).&lt;/p&gt;&lt;p&gt;As for J2ME, it will simply be obsoleted by its bigger brother.  At some point mobile device technology will mature enough to be able to host the full J2SE stack and we won&apos;t have to worry about obfuscating and re-jarring class files and developing in a completely different way than we would for standard Java applications.&lt;/p&gt;</description>			<guid>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/02/24.html#a64</guid>			<pubDate>Fri, 25 Feb 2005 02:46:16 GMT</pubDate>			<comments>http://radiocomments2.userland.com/comments?u=141460&amp;amp;p=64&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0141460%2F2005%2F02%2F24.html%23a64</comments>			</item>		<item>			<title>Agile or Fragile?</title>			<link>http://www.itconversations.com/shows/detail355.html</link>			<description>&lt;p&gt;Another nice podcast from &lt;a href=&quot;http://www.itconversations.com&quot;&gt;IT Conversations&lt;/a&gt;.  I&apos;m about 2/3 the way through this long podcast but already I definitely agree that it&apos;s well worth the 4 star rating.&lt;/p&gt;&lt;p&gt;Scott blends metaphors well when talking about software development and tools.  Would you do software development with only one vendor&apos;s toolset?  That&apos;s like using only one brand of tools in your toolbox.  I think Paul Graham in his &lt;a href=&quot;http://www.paulgraham.com/gh.html&quot;&gt;Great Hackers&lt;/a&gt; talk mentioned how the best hackers have a passion for great tools.  A good hacker/developer/however-you-wish-to-be-called is particular about using the correct tool for the job, and is passionate about trying new tools and acquiring them for his or her personal development toolbox.&lt;/p&gt;&lt;p&gt;Another interesting discussion is around the idea of how would you build a project team?  With generalists or specialists?&lt;/p&gt;&lt;ul&gt;&lt;li&gt;With generalists, no one has sharp enough skills to actually implement requirements.&lt;/li&gt;&lt;li&gt;With specialists, each person has their own domain-specific language and artifacts need to be handed off between different members of the team.  Pretty soon you&apos;re tracking deliverables and maintaining way more documentation than necessary.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Of course the solution is to bring on folks that feel comfortable in multiple disciplines.  Ambler calls these &quot;generalized specialists&quot;.  Since everyone on the team has at least a solid baseline in software development processes, a common (ubiquitous to use &lt;a href=&quot;http://www.domaindrivendesign.org&quot;&gt;Eric Evans&apos;&lt;/a&gt; term) language can sprout forth easily.  Of course these folks will generally be more experienced and sharper all around (and be more expensive), but you get what you pay for.  So as always, the philosophy of hire the best is manifested in some shape or form.&lt;/p&gt;</description>			<guid>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/02/23.html#a62</guid>			<pubDate>Thu, 24 Feb 2005 03:10:57 GMT</pubDate>			<comments>http://radiocomments2.userland.com/comments?u=141460&amp;amp;p=62&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0141460%2F2005%2F02%2F23.html%23a62</comments>			</item>		<item>			<title>Freemind and OPML take 2</title>			<link>http://radio.weblogs.com/0141460/2005/02/17.html#a57</link>			<description>&lt;p&gt;A follow-up on &lt;a href=&quot;http://radio.weblogs.com/0141460/2005/02/17.html#a57&quot;&gt;FreeMind and OPML&lt;/a&gt; -- so the impending &lt;a href=&quot;http://sourceforge.net/forum/forum.php?thread_id=1230551&amp;forum_id=22101&quot;&gt;0.8 release&lt;/a&gt; is chock full of new goodies including a MM-to-OPML XSL file and an export option that allows you to apply an arbitrary XSLT.  Nice work guys, but I still think that the UI should somehow auto-detect all transform files available (both in the distro plus the user&apos;s freemind directory) and create menu options for each in the Export submenu instead of forcing the user to select the transform...maybe the next iteration?&lt;/p&gt;</description>			<guid>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/02/22.html#a61</guid>			<pubDate>Wed, 23 Feb 2005 03:46:17 GMT</pubDate>			<comments>http://radiocomments2.userland.com/comments?u=141460&amp;amp;p=61&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0141460%2F2005%2F02%2F22.html%23a61</comments>			</item>		<item>			<title>Quote and database evolution</title>			<link>http://kasparov.skife.org/blog/2005/02/21#db-is-not-sacred</link>			<description>&lt;p&gt;Today&apos;s quote courtesy of Brian McCallister:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;If you are worried about correct behavior, write tests.&lt;/p&gt;&lt;p&gt;If you are worried about integration, expose an integration API via messaging or SOAP.&lt;/p&gt;&lt;p&gt;If you are worried about your job, produce useful software.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;It&apos;s intriguing to me that the application I&apos;ve worked on for going on four years as well as my own perception of what has worked well over that timeframe has followed a pretty similar evolution as what Brian describes in his &lt;i&gt;rant&lt;/i&gt; about databases.&lt;/p&gt;&lt;p&gt;Thanks for the astute and honest observations, dude.&lt;/p&gt;</description>			<guid>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/02/22.html#a59</guid>			<pubDate>Wed, 23 Feb 2005 03:34:21 GMT</pubDate>			<comments>http://radiocomments2.userland.com/comments?u=141460&amp;amp;p=59&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0141460%2F2005%2F02%2F22.html%23a59</comments>			</item>		<item>			<title>FreeMind and OPML</title>			<link>http://freemind.sourceforge.net/wiki/index.php/Development#Why_not_use_OPML_for_storage_instead_of_FreeMind.27s_native_XML_format</link>			<description>&lt;p&gt;I just discovered &lt;a href=&quot;&quot;&gt;FreeMind&lt;/a&gt;, and am all jittery with excitement about a new tool to try out and see if it fits the way my brain works.  All early signs point to yes...&lt;/p&gt;&lt;p&gt;It seems that since FreeMind is at its core a fancy graphical outliner that it should support &lt;a href=&quot;http://www.opml.org&quot;&gt;OPML&lt;/a&gt; natively.  The only answer given is :&lt;/p&gt;&lt;blockquote&gt;It should be easy to create conversion XSLT between FreeMind and OPML.&lt;/blockquote&gt;&lt;p&gt;These guys have created a great program with a solid UI and decent usability, yet they don&apos;t understand how big a benefit interop with growing standards like OPML would give them?  At least give me built-in &quot;Import from OPML&quot; and &quot;Export to OPML&quot; commands so that non-techie users don&apos;t have to a) write an XSL transform; b) write scripts to run it on their .mm files just to get to OPML.  At best FreeMind is a nice toy program right now; if it groked OPML it suddenly jumps into a whole new class of eminently useful applications.  Imagine being able to import the &lt;a href=&quot;http://www.ipodder.org/directory/4/podcasts&quot;&gt;Podcast directory&lt;/a&gt; (&lt;a href=&quot;http://www.ipodder.org/discuss/reader$4.opml&quot;&gt;OPML&lt;/a&gt;) into FreeMind!&lt;/p&gt;</description>			<guid>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/02/17.html#a57</guid>			<pubDate>Fri, 18 Feb 2005 05:25:34 GMT</pubDate>			<comments>http://radiocomments2.userland.com/comments?u=141460&amp;amp;p=57&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0141460%2F2005%2F02%2F17.html%23a57</comments>			</item>		<item>			<title>Users GOOD</title>			<link>http://www.livejournal.com/users/jwz/444651.html</link>			<description>Another quote of the day:&lt;blockquote&gt;If you want to do something that&apos;s going to change the world, build software that &lt;em&gt;people want to use&lt;/em&gt; instead of software that &lt;em&gt;managers want to buy&lt;/em&gt;.&lt;/blockquote&gt;Brought to you by the indefatigable JWZ.</description>			<guid>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/02/16.html#a55</guid>			<pubDate>Wed, 16 Feb 2005 15:25:18 GMT</pubDate>			<comments>http://radiocomments2.userland.com/comments?u=141460&amp;amp;p=55&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0141460%2F2005%2F02%2F16.html%23a55</comments>			</item>		<item>			<title>RESTless applications</title>			<link>http://www.xml.com/pub/a/2005/01/05/restful.html</link>			<description>An article that looks to be worth reading -- I&apos;ve also posted over to &lt;a href=&quot;http://del.icio.us/nicksieger&quot;&gt;del.icio.us&lt;/a&gt;...&lt;blockquote&gt;One of the things I frequently criticize SOAP and XML-RPC for is doing everything through POST. Of the many problems with doing everything through POST, the biggest is that there are things that could be better done through GET. Well, the Amazon Queue Service does everything through GET, and no, that&apos;s not a good thing. Let&apos;s take a look.&lt;/blockquote&gt;</description>			<guid>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/02/15.html#a54</guid>			<pubDate>Wed, 16 Feb 2005 02:30:39 GMT</pubDate>			<comments>http://radiocomments2.userland.com/comments?u=141460&amp;amp;p=54&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0141460%2F2005%2F02%2F15.html%23a54</comments>			</item>		<item>			<title>Agile Manifesto</title>			<link>http://agilemanifesto.org/principles.html</link>			<description>&lt;p&gt;A quote for today:&lt;/p&gt;&lt;blockquote&gt;Continuous attention to technical excellenceand good design enhances agility.&lt;/blockquote&gt;&lt;p&gt;That pretty much summarizes the attitude I try to take to work every day...&lt;/p&gt;</description>			<guid>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/02/14.html#a53</guid>			<pubDate>Tue, 15 Feb 2005 03:41:40 GMT</pubDate>			<comments>http://radiocomments2.userland.com/comments?u=141460&amp;amp;p=53&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0141460%2F2005%2F02%2F14.html%23a53</comments>			</item>		<item>			<title>Oracle does not grok transparency</title>			<link>http://www.oracle.com/technology/sample_code/tech/java/codesnippet/jdbc/clob10g/handlingclobsinoraclejdbc10g.html</link>			<description>&lt;p&gt;Oracle just does not get it!  Any java programmer who has written code against an Oracle database knows about the dreaded CLOB issue -- string values over 4000 characters cannot be stored using &lt;code&gt;PreparedStatement.setString&lt;/code&gt;; instead you&apos;re forced to bind to Oracle&apos;s proprietary &lt;code&gt;oracle.sql.CLOB&lt;/code&gt; class.  In the new 10g release, Oracle &lt;a href=&quot;http://www.oracle.com/technology/sample_code/tech/java/codesnippet/jdbc/clob10g/handlingclobsinoraclejdbc10g.html&quot;&gt;claims to have rectified the issue&lt;/a&gt;, but in actuality all they&apos;ve done is up the limit to 32765, unless you set a &quot;SetBigStringTryClob=true&quot; property in the connection or data source.  When you&apos;re Oracle, you don&apos;t have to play by the rules, apparently...&lt;/p&gt;</description>			<guid>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/02/11.html#a52</guid>			<pubDate>Fri, 11 Feb 2005 15:55:58 GMT</pubDate>			<comments>http://radiocomments2.userland.com/comments?u=141460&amp;amp;p=52&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0141460%2F2005%2F02%2F11.html%23a52</comments>			</item>		<item>			<title>Increasing coverage and refactorability for code with no unit tests</title>			<link>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/02/10.html#a51</link>			<description>&lt;p&gt;Note to self: I have some new ideas about improving test coverage and refactorability for a legacy codebase with few existing unit tests where writing tests is extremely hard due to high coupling.  Hopefully more to come on this soon...&lt;/p&gt;</description>			<guid>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/02/10.html#a51</guid>			<pubDate>Fri, 11 Feb 2005 05:02:47 GMT</pubDate>			<comments>http://radiocomments2.userland.com/comments?u=141460&amp;amp;p=51&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0141460%2F2005%2F02%2F10.html%23a51</comments>			</item>		<item>			<title>Backspacing over unicode characters</title>			<link>http://blogs.msdn.com/michkap/archive/2005/01/14/352802.aspx</link>			<description>&lt;p&gt;Does your browser backspace correctly?   Follow the title link and page down a bit and try it out.  Interesting how easy it is for folks to not get this right -- even the demigods over at &lt;a href=&quot;http://www.spreadfirefox.com&quot;&gt;Firefox&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The post itself is a little Microsoft-centric (as it&apos;s from an MS employee), but contains a good bit of info.&lt;/p&gt;</description>			<guid>http://radio.weblogs.com/0141460/categories/softwareEngineering/2005/02/07.html#a42</guid>			<pubDate>Tue, 08 Feb 2005 03:41:14 GMT</pubDate>			<comments>http://radiocomments2.userland.com/comments?u=141460&amp;amp;p=42&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0141460%2F2005%2F02%2F07.html%23a42</comments>			</item>		<item>			<title>Maven alternate test suites</title>			<link>http://radio.weblogs.com/0141460/categories/softwareEngineering/2004/11/04.html#a28</link>			<description>&lt;p&gt;A common complaint of &lt;a href=&quot;http://maven.apache.org&quot;&gt;Maven&apos;s&lt;/a&gt;integrated testing plugin is that it only allows you to define asingle test suite.  I figured out a way to implement alternate testsuites by tweaking the project configuration and adding a little extrajelly script.  It would be nice if this was a standard feature ofMaven, but at least the amount of extra jelly required is minimal.&lt;/p&gt;&lt;p&gt;In my case, I wanted an acceptance testing suite that contained allthe integrated components tested as a whole.&lt;/p&gt;&lt;ol&gt;  &lt;li&gt; I put the acceptance tests in       &lt;code&gt;${project.home}/src/acceptance-test&lt;/code&gt; (instead of       the Maven standard &lt;code&gt;${project.home}/src/test&lt;/code&gt;).&lt;/li&gt;  &lt;li&gt; I set the property &lt;code&gt;maven.test.search.classdir=true&lt;/code&gt;       in project.properties.&lt;/li&gt;  &lt;li&gt; I set the include pattern for tests in &lt;code&gt;project.xml&lt;/code&gt;       as &lt;code&gt;**/*Test.*&lt;/code&gt;.  This is because setting       &lt;code&gt;maven.test.search.classdir=true&lt;/code&gt; requires Maven to       search for tests by class, not by source file.  Doing this       allows Maven to find the unit tests in the unit test output       directory and the acceptance tests in the acceptance test       output directory.&lt;/li&gt;  &lt;li&gt; I put the following jelly code in &lt;code&gt;maven.xml&lt;/code&gt;.  If       you wish, you can keep it in a separate file (say       &lt;code&gt;acceptance-test.xml&lt;/code&gt;) and import it in your main       &lt;code&gt;maven.xml&lt;/code&gt; with a &lt;code&gt;&amp;lt;j:import inherit=&quot;true&quot;       file=&quot;${basedir}/acceptance-test.xml&quot; /&amp;gt;&lt;/code&gt; import       statement.&lt;div class=&quot;fixed&quot;&gt;&lt;pre&gt;&lt;span class=&quot;function-name&quot;&gt;&amp;lt;?&lt;/span&gt;&lt;span class=&quot;keyword&quot;&gt;xml version=&amp;quot;1.0&amp;quot;&lt;/span&gt;&lt;span class=&quot;function-name&quot;&gt;?&amp;gt;&lt;/span&gt;&lt;span class=&quot;function-name&quot;&gt;&amp;lt;project&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;xmlns&lt;/span&gt;:j=&amp;quot;jelly:core&amp;quot;         &lt;span class=&quot;variable-name&quot;&gt;xmlns&lt;/span&gt;:maven=&amp;quot;jelly:maven&amp;quot;         &lt;span class=&quot;variable-name&quot;&gt;xmlns&lt;/span&gt;:u=&amp;quot;jelly:util&amp;quot;          &lt;span class=&quot;variable-name&quot;&gt;xmlns&lt;/span&gt;:define=&amp;quot;jelly:define&amp;quot;         &lt;span class=&quot;variable-name&quot;&gt;xmlns&lt;/span&gt;:ant=&amp;quot;jelly:ant&amp;quot;&lt;span class=&quot;function-name&quot;&gt;&amp;gt;&lt;/span&gt;    &lt;span class=&quot;function-name&quot;&gt;&amp;lt;goal&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;constant&quot;&gt;=&amp;quot;acceptance:init&amp;quot;&lt;/span&gt;&lt;span class=&quot;function-name&quot;&gt;&amp;gt;&lt;/span&gt;        &lt;span class=&quot;function-name&quot;&gt;&amp;lt;j:set&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;constant&quot;&gt;=&amp;quot;maven.test.dest&amp;quot;&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;constant&quot;&gt;=&amp;quot;${maven.build.dir}/acc-test-classes&amp;quot;&lt;/span&gt; /&lt;span class=&quot;function-name&quot;&gt;&amp;gt;&lt;/span&gt;        &lt;span class=&quot;function-name&quot;&gt;&amp;lt;j:set&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;constant&quot;&gt;=&amp;quot;maven.test.reportsDirectory&amp;quot;&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;constant&quot;&gt;=&amp;quot;${maven.build.dir}/acc-test-reports&amp;quot;&lt;/span&gt; /&lt;span class=&quot;function-name&quot;&gt;&amp;gt;&lt;/span&gt;        &lt;span class=&quot;function-name&quot;&gt;&amp;lt;j:set&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;var&lt;/span&gt;&lt;span class=&quot;constant&quot;&gt;=&amp;quot;maven.test.searchdir&amp;quot;&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;constant&quot;&gt;=&amp;quot;${maven.src.dir}/acceptance-test&amp;quot;&lt;/span&gt; /&lt;span class=&quot;function-name&quot;&gt;&amp;gt;&lt;/span&gt;        &lt;span class=&quot;function-name&quot;&gt;&amp;lt;ant:path&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;constant&quot;&gt;=&amp;quot;maven.test.compile.src.set&amp;quot;&lt;/span&gt;&lt;span class=&quot;function-name&quot;&gt;&amp;gt;&lt;/span&gt;            &lt;span class=&quot;function-name&quot;&gt;&amp;lt;ant:pathelement&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;location&lt;/span&gt;&lt;span class=&quot;constant&quot;&gt;=&amp;quot;${maven.test.searchdir}&amp;quot;&lt;/span&gt; /&lt;span class=&quot;function-name&quot;&gt;&amp;gt;&lt;/span&gt;        &lt;span class=&quot;function-name&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;builtin&quot;&gt;/ant:path&lt;/span&gt;&lt;span class=&quot;function-name&quot;&gt;&amp;gt;&lt;/span&gt;    &lt;span class=&quot;function-name&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;builtin&quot;&gt;/goal&lt;/span&gt;&lt;span class=&quot;function-name&quot;&gt;&amp;gt;&lt;/span&gt;    &lt;span class=&quot;function-name&quot;&gt;&amp;lt;goal&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;constant&quot;&gt;=&amp;quot;acceptance:compile&amp;quot;&lt;/span&gt;&lt;span class=&quot;function-name&quot;&gt;&amp;gt;&lt;/span&gt;        &lt;span class=&quot;function-name&quot;&gt;&amp;lt;attainGoal&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;constant&quot;&gt;=&amp;quot;acceptance:init&amp;quot;&lt;/span&gt; /&lt;span class=&quot;function-name&quot;&gt;&amp;gt;&lt;/span&gt;        &lt;span class=&quot;function-name&quot;&gt;&amp;lt;attainGoal&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;constant&quot;&gt;=&amp;quot;test:compile&amp;quot;&lt;/span&gt; /&lt;span class=&quot;function-name&quot;&gt;&amp;gt;&lt;/span&gt;    &lt;span class=&quot;function-name&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;builtin&quot;&gt;/goal&lt;/span&gt;&lt;span class=&quot;function-name&quot;&gt;&amp;gt;&lt;/span&gt;    &lt;span class=&quot;function-name&quot;&gt;&amp;lt;goal&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;constant&quot;&gt;=&amp;quot;acceptance:test&amp;quot;&lt;/span&gt;&lt;span class=&quot;function-name&quot;&gt;&amp;gt;&lt;/span&gt;        &lt;span class=&quot;function-name&quot;&gt;&amp;lt;attainGoal&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;constant&quot;&gt;=&amp;quot;acceptance:init&amp;quot;&lt;/span&gt; /&lt;span class=&quot;function-name&quot;&gt;&amp;gt;&lt;/span&gt;        &lt;span class=&quot;function-name&quot;&gt;&amp;lt;attainGoal&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;constant&quot;&gt;=&amp;quot;test:test&amp;quot;&lt;/span&gt; /&lt;span class=&quot;function-name&quot;&gt;&amp;gt;&lt;/span&gt;    &lt;span class=&quot;function-name&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;builtin&quot;&gt;/goal&lt;/span&gt;&lt;span class=&quot;function-name&quot;&gt;&amp;gt;&lt;/span&gt;    &lt;span class=&quot;function-name&quot;&gt;&amp;lt;goal&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;constant&quot;&gt;=&amp;quot;acceptance:single&amp;quot;&lt;/span&gt;&lt;span class=&quot;function-name&quot;&gt;&amp;gt;&lt;/span&gt;        &lt;span class=&quot;function-name&quot;&gt;&amp;lt;attainGoal&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;constant&quot;&gt;=&amp;quot;acceptance:init&amp;quot;&lt;/span&gt; /&lt;span class=&quot;function-name&quot;&gt;&amp;gt;&lt;/span&gt;        &lt;span class=&quot;function-name&quot;&gt;&amp;lt;attainGoal&lt;/span&gt; &lt;span class=&quot;variable-name&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;constant&quot;&gt;=&amp;quot;test:single&amp;quot;&lt;/span&gt; /&lt;span class=&quot;function-name&quot;&gt;&amp;gt;&lt;/span&gt;    &lt;span class=&quot;function-name&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;builtin&quot;&gt;/goal&lt;/span&gt;&lt;span class=&quot;function-name&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;function-name&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;builtin&quot;&gt;/project&lt;/span&gt;&lt;span class=&quot;function-name&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;</description>			<guid>http://radio.weblogs.com/0141460/categories/softwareEngineering/2004/11/04.html#a28</guid>			<pubDate>Thu, 04 Nov 2004 22:50:28 GMT</pubDate>			<comments>http://radiocomments2.userland.com/comments?u=141460&amp;amp;p=28</comments>			</item>		<item>			<title>Web acceptance testing</title>			<link>http://radio.weblogs.com/0141460/categories/softwareEngineering/2004/11/04.html#a27</link>			<description>&lt;p&gt;A critical part of XP is automated acceptance testing, whetherthrough the &lt;a href=&quot;http://radio.weblogs.com/0141460/2004/10/26.html#a20&quot;&gt;Story-test driven development&lt;/a&gt; of using FIT and fixturesor through some other mechansim.  A whole crop of functional webtesting frameworks exist of various quality:&lt;/p&gt;&lt;ul&gt;  &lt;li&gt; &lt;a href=&quot;http://jakarta.apache.org/cactus/&quot;&gt;Cactus&lt;/a&gt;&lt;/li&gt;  &lt;li&gt; &lt;a href=&quot;http://httpunit.sourceforge.net/&quot;&gt;HttpUnit&lt;/a&gt;&lt;/li&gt;  &lt;li&gt; &lt;a href=&quot;http://jakarta.apache.org/commons/latka/&quot;&gt;Latka&lt;/a&gt;&lt;/li&gt;  &lt;li&gt; &lt;a href=&quot;http://jameleon.sourceforge.net/&quot;&gt;Jameleon&lt;/a&gt;&lt;/li&gt;  &lt;li&gt; &lt;a href=&quot;http://fitnesse.org/FitNesse.SuiteAcceptanceTests.HtmlTests.FrontPageTest&quot;&gt;FitNesse Web Acceptance Testing Tool&lt;/a&gt;&lt;/li&gt;  &lt;li&gt; &lt;a href=&quot;http://opensource.atlassian.com/fatcow/&quot;&gt;Atlassian FatCow&lt;/a&gt;&lt;/li&gt;  &lt;li&gt; &lt;a href=&quot;http://webtest.canoo.com/manual/WebTestHome.html&quot;&gt;Canoo WebTest&lt;/a&gt;&lt;/li&gt;  &lt;li&gt; &lt;a href=&quot;http://www.softwareqatest.com/qatweb1.html#FUNC&quot;&gt;and too many others to name.&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Recently I came across an &lt;ahref=&quot;http://karmalab.org/~kschrader/blog/archives/000003.html&quot;&gt;interestingapproach&lt;/a&gt; that combines Latka with &lt;ahref=&quot;http://jakarta.apache.org/jmeter/&quot;&gt;Apache JMeter&lt;/a&gt;&apos;s proxyrecord functionality and uses Maven to record a Latka script.  Yeah, Iknow, maven, latka and jelly, the bane of a java open source, but itcould be a quick way to get some web acceptance testing going.&lt;/p&gt;</description>			<guid>http://radio.weblogs.com/0141460/categories/softwareEngineering/2004/11/04.html#a27</guid>			<pubDate>Thu, 04 Nov 2004 17:26:48 GMT</pubDate>			<comments>http://radiocomments2.userland.com/comments?u=141460&amp;amp;p=27&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0141460%2F2004%2F11%2F04.html%23a27</comments>			</item>		<item>			<title>Story-test driven development</title>			<link>http://www.otug.org/meeting/20041025.html</link>			<description>&lt;p&gt;Attended a &lt;a href=&quot;http://www.otug.org/meeting/20041025.html&quot;&gt;talk last night&lt;/a&gt;about &lt;em&gt;Story-Test-Driven Development&lt;/em&gt;.  More to come on this as I need a littlewhile to digest, and to research FIT frameworks.  I must say that the idea of havingprovable tests that tell you exactly when the business needs are satisfied could beimmensely useful in any situation, not just XP environments.&lt;/p&gt;&lt;p&gt;Links to follow:&lt;/p&gt;&lt;ul&gt;  &lt;li&gt;&lt;a href=&quot;http://fit.c2.com/wiki.cgi?WelcomeVisitors&quot;&gt;Ward&apos;s FIT&lt;/a&gt;&lt;/li&gt;  &lt;li&gt;&lt;a href=&quot;http://www.fitnesse.org/&quot;&gt;Fitnesse&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</description>			<guid>http://radio.weblogs.com/0141460/categories/softwareEngineering/2004/10/26.html#a20</guid>			<pubDate>Wed, 27 Oct 2004 05:11:24 GMT</pubDate>			<comments>http://radiocomments2.userland.com/comments?u=141460&amp;amp;p=20&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0141460%2F2004%2F10%2F26.html%23a20</comments>			</item>		</channel>	</rss>
