<?xml version="1.0"?>
<!-- RSS generated by Radio UserLand v8.0.8 on Mon, 08 Dec 2003 13:27:43 GMT -->
<rss version="2.0">
	<channel>
		<title>Rodney Waldhoff: Tech</title>
		<link>http://radio.weblogs.com/0122027/categories/tech/</link>
		<description>about technical stuff in general, but mostly software development</description>
		<language>en</language>
		<copyright>Copyright 2003 Rodney Waldhoff</copyright>
		<lastBuildDate>Mon, 08 Dec 2003 13:27:43 GMT</lastBuildDate>
		<docs>http://backend.userland.com/rss</docs>
		<generator>Radio UserLand v8.0.8</generator>
		<managingEditor>rwaldhoff@eb.com</managingEditor>
		<webMaster>rwaldhoff@eb.com</webMaster>
		<category domain="http://www.weblogs.com/rssUpdates/changes.xml">rssUpdates</category> 
		<skipHours>
			<hour>1</hour>
			<hour>2</hour>
			<hour>20</hour>
			<hour>22</hour>
			<hour>23</hour>
			<hour>21</hour>
			<hour>0</hour>
			<hour>4</hour>
			</skipHours>
		<cloud domain="radio.xmlstoragesystem.com" port="80" path="/RPC2" registerProcedure="xmlStorageSystem.rssPleaseNotify" protocol="xml-rpc"/>
		<ttl>60</ttl>
		<item>
			<title>An SQL Annoyance</title>
			<link>http://radio.weblogs.com/0122027/2003/12/08.html#a103</link>
			<description>&lt;p&gt;SQL isn&apos;t consistent under row/column transposition.  For example:&lt;/p&gt;
&lt;pre&gt;select 3 + NULL&lt;/pre&gt;
&lt;p&gt;yields NULL.  Yet,&lt;/p&gt;
&lt;pre&gt;create table TEMP ( NUM number );
insert into TEMP values ( 3 );
insert into TEMP values ( NULL );
select sum(NUM) from TEMP&lt;/pre&gt;
&lt;p&gt;yields 3 (since NULL valued rows are ignored by aggregate functions).&lt;/p&gt;
&lt;p&gt;This inconsistency is all the more annoying since both:&lt;/p&gt;
&lt;pre&gt;select sum(NUM) from TEMP where NUM is not NULL&lt;/pre&gt;
&lt;p&gt;and&lt;/p&gt;
&lt;pre&gt;select sum(coalesce(NUM,0)) from TEMP&lt;/pre&gt;
&lt;p&gt;would yield the same result under an &quot;aggregation of NULL is NULL&quot; rule. Yet under the &quot;aggregation function ignores NULL&quot; rule, creating a &lt;i&gt;single&lt;/i&gt;, efficient, cross-database query the yields NULL if there&apos;s a NULL row and the SUM otherwise is awkward at best.&lt;/p&gt;</description>
			<guid isPermaLink="false">http://radio.weblogs.com/0122027/categories/tech/2003/12/08.html#a103</guid>
			<pubDate>Mon, 08 Dec 2003 13:27:27 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=122027&amp;amp;p=103&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0122027%2F2003%2F12%2F08.html%23a103</comments>
			</item>
		<item>
			<title>Ruby Userland</title>
			<link>http://radio.weblogs.com/0122027/2003/11/21.html#a102</link>
			<description>&lt;p&gt;
As I &lt;a href=&quot;http://radio.weblogs.com/0122027/2003/11/04.html#a95&quot; title=&quot;Custom Radio UserLand Clients?&quot;&gt;previously mentioned&lt;/a&gt;, I&apos;ve been toying with custom clients to the &lt;a href=&quot;http://www.soapware.org/xmlStorageSystem&quot;&gt;XmlStorageSystem&lt;/a&gt; XML-RPC protocol used by &lt;a href=&quot;http://radio.userland.com/&quot;&gt;Radio Userland&lt;/a&gt; and &lt;a href=&quot;http://www.myelin.co.nz/wcswiki/w/CommunityServerWiki&quot;&gt;several open source blog servers&lt;/a&gt;, with the ultimate goal of hosting a custom blog on the radio.weblogs.com host.
&lt;/p&gt;&lt;p&gt;
Over the past couple of evenings I&apos;ve hacked out &lt;a href=&quot;http://radio.weblogs.com/0122027/files/xmlStorageSystem.rb.txt&quot; title=&quot;xmlStorageSystem.rb&quot;&gt;xmlStorageSystem.rb&lt;/a&gt;, a reasonably functional Ruby-based client to the XmlStorageSystem system protocol.  It works like this:
&lt;/p&gt;
&lt;p&gt;
To create a new instance of the client, use:
&lt;/p&gt;
&lt;pre&gt;XmlStorageSystem.new(&lt;i&gt;&amp;lt;usernumber&amp;gt;&lt;/i&gt;,&lt;i&gt;&amp;lt;md5-hash-of-password&amp;gt;&lt;/i&gt;,&lt;i&gt;&amp;lt;root-directory&amp;gt;&lt;/i&gt;)&lt;/pre&gt;
&lt;p&gt;
For instance, I use:
&lt;/p&gt;
&lt;pre&gt;XmlStorageSystem.new(&apos;122027&apos;,&apos;8c8034f5c9d68564e155c67a6d4e4612&apos;,&apos;/0122027/&apos;)&lt;/pre&gt;
&lt;p&gt;
although that&apos;s not my actual password.  
&lt;/p&gt;
&lt;p&gt;
Actually, my local copy of xmlStorageSystem.rb has these value specified as the defaults, so I just user XmlStorageSystem.new, and I&apos;ll use that form in the rest of these examples.  The constructor also accepts an number of arguments that should allow one to connect to the &lt;a href=&quot;http://www.pycs.net/&quot;&gt;Python Community Server&lt;/a&gt; and others, although Radio is the only server I&apos;ve tried.
&lt;/p&gt;
&lt;p&gt;
To get a listing of the files currently stored on the server, use:
&lt;/p&gt;
&lt;pre&gt;XmlStorageSystem.new.getMyDirectory&lt;/pre&gt;
&lt;p&gt;
To download all those files to a local directory
&lt;/p&gt;
&lt;pre&gt;XmlStorageSystem.new.backupMyDirectory &apos;backupdir&apos;&lt;/pre&gt;
&lt;p&gt;
To upload a file (or files) to the server, use:
&lt;/p&gt;
&lt;pre&gt;XmlStorageSystem.new.saveMultipleFiles( &apos;local-base-dir&apos;, [ &apos;file1&apos;, &apos;file2&apos;, &apos;etc&apos; ])&lt;/pre&gt;
&lt;p&gt;
To delete a file (or files)  from the server, use:
&lt;/p&gt;
&lt;pre&gt;XmlStorageSystem.new.deleteMultipleFiles( [ &apos;file1&apos;, &apos;file2&apos;, &apos;etc&apos; ])&lt;/pre&gt;
&lt;p&gt;
Finally, the really handy one:
&lt;/p&gt;
&lt;pre&gt;XmlStorageSystem.new.updateFromLocalDirectory &apos;localdir&apos;&lt;/pre&gt;
&lt;p&gt;
Which will compare the list of files in the local directory with those on the server, delete the ones that don&apos;t appear locally, and load/update the rest.
&lt;p&gt;
Since this is Ruby, it&apos;s easy to set up little shell scripts that invoke those commands in ways useful to your personal work style.
&lt;/p&gt;&lt;p&gt;
If one wanted to be clever, there is metadata available via XmlStorageSystem.getMyDirectory that would allow one to determine whether or not a file has changed since it was last uploaded, but I haven&apos;t gotten around to that yet.
&lt;/p&gt;&lt;p&gt;
I&apos;m still pretty much a Ruby neophyte, so there&apos;s probably substantial room for improvement there.  In particular, (1) there&apos;s no error handling present just yet and (2) the current implementation supports hackablity (changing the script itself) more than extensibility.  Nevertheless, it&apos;s neat that a Ruby neophyte can write a basic XmlStorageSystem client in 150 lines of readable code.
&lt;/p&gt;</description>
			<guid isPermaLink="false">http://radio.weblogs.com/0122027/categories/tech/2003/11/21.html#a102</guid>
			<pubDate>Fri, 21 Nov 2003 18:58:26 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=122027&amp;amp;p=102&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0122027%2F2003%2F11%2F21.html%23a102</comments>
			</item>
		<item>
			<title>On Programming Idioms</title>
			<link>http://radio.weblogs.com/0122027/2003/11/14.html#a99</link>
			<description>&lt;p&gt;
Two things I&apos;m always keen to learn when picking up a new programming language are:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;How does one organize large projects?  In other words, how does one partition responsibilities and types across namespaces, modules and files?&lt;/li&gt;
&lt;li&gt;What are the common idioms in the language?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
I&apos;ve been doing some string processing work with Ruby recently, and it&apos;s got me thinking about examples of the latter.
&lt;/p&gt;&lt;p&gt;
For example, in Java, the String class doesn&apos;t have a direct, boolean-valued method that will tell you whether or not a String contains another String, i.e., there&apos;s nothing like:
&lt;/p&gt;
&lt;pre&gt;if(someString.contains(anotherString)) { ... }&lt;/pre&gt;
&lt;p&gt;
Instead, most Java developers will write:
&lt;/p&gt;
&lt;pre&gt;if(someString.indexOf(anotherString) != -1) { ... }&lt;/pre&gt;
&lt;p&gt;
where String.indexOf(String) returns the index of the first occurrence of the argument String, or -1 if the given String isn&apos;t found.  Most Java developers will immediately recognize that as the &quot;String.contains&quot; idiom, and won&apos;t miss a beat.
&lt;/p&gt;&lt;p&gt;
This idiom is so strong in the Java community that it&apos;s almost counter-productive to write a custom utility method:
&lt;/p&gt;
&lt;pre&gt;public class StringUtils {
  public static boolean contains(String a, String b) {
    return (a.indexOf(b) != -1);
  }
}&lt;/pre&gt;
&lt;p&gt;
since many developers who see 
&lt;/p&gt;
&lt;pre&gt;if(StringUtils.contains(someString,anotherString)) { ... }&lt;/pre&gt;
&lt;p&gt;
are likely to wonder whether the StringUtils.contains method really does what it is implied--Is this equivalent to the String.indexOf idiom?  Is that someString.contains(anotherString) or vice versa? How are null&apos;s handled? etc.  Unless the developer is already comfortable and familiar with the StringUtils class being used, this code is probably less readable to an experienced developer than the &quot;indexOf != -1&quot; formulation.
&lt;/p&gt;&lt;p&gt;
(This is not to say that &quot;String.indexOf(x) != -1&quot; is actually preferable to &quot;String.contains(x)&quot;, but rather that in the absence of String.contains, the idiom is more widely recognized than a custom utility method.  Why Sun can&apos;t at some point introduce a String.contains method, say in JDK 1.5,  isn&apos;t entirely clear to me.)
&lt;/p&gt;&lt;p&gt;
Now, in the Ruby scripting I&apos;ve been doing recently, I keep needing to determine whether a String begins with a given prefix.  In Java, that&apos;s the String.startsWith method, of course.  The Ruby String class does not have a startsWith method, but one of the neat things about Ruby is that it&apos;s possible to literally add such a method the the String class, as follows:
&lt;/p&gt;
&lt;pre&gt;class String
  def startsWith str
    return self[0...str.length] == str
  end
end&lt;/pre&gt;
&lt;p&gt;
after which everything behaves exactly like the built-in String class contained that definition.  For example, one can then write:
&lt;/p&gt;
&lt;pre&gt;if someString.startsWith(anotherString) ...&lt;/pre&gt;
&lt;p&gt;
or even
&lt;/p&gt;
&lt;pre&gt;if &quot;a literal string&quot;.startsWith(anotherString) ...&lt;/pre&gt;
&lt;p&gt;
etc.
&lt;/p&gt;&lt;p&gt;
Of course, the implementation I used for String.startsWith (&lt;code&gt;self[0...str.length] == str&lt;/code&gt;) is just one of several possible implementations.  Regular expressions provide one way of implementing such a check.  The Java-like indexOf function provides another (e.g., &lt;code&gt;self.indexOf(str) == 0&lt;/code&gt;). 
&lt;/p&gt;&lt;p&gt;
Since there is no built-in String.startsWith (or for that matter String.contains) in Ruby, I wonder if there is some common idiom that experienced Ruby developers find more readable than adding a custom method to String?  If not for String.startsWith, how about String.contains?
&lt;/p&gt;</description>
			<guid isPermaLink="false">http://radio.weblogs.com/0122027/categories/tech/2003/11/14.html#a99</guid>
			<pubDate>Fri, 14 Nov 2003 17:36:09 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=122027&amp;amp;p=99&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0122027%2F2003%2F11%2F14.html%23a99</comments>
			</item>
		<item>
			<title>The impotence of functional programming (by Sjoerd Visscher)</title>
			<link>http://radio.weblogs.com/0122027/2003/11/11.html#a98</link>
			<description>&lt;p&gt;
Sjoerd Visscher &lt;a href=&quot;http://w3future.com/weblog/2003/11/11.xml#theImpotenceOfFunctionalProgramming&quot; title=&quot;11 November 2003: The impotence of functional programming&quot;&gt;writes&lt;/a&gt;:
&lt;/p&gt;
&lt;blockquote&gt;&quot;Take for example the function zip (or zip3, zip4, exponential ugh-ness), a very popular function in f.e. Haskell. Firstly, if you have two lists, with values that go pairwise together, those values shouldn&apos;t have been apart in the first place. Secondly, what you end up with is a list of tuples. Values in a tuple always have more context than just being together. All this information is lost.&quot;&lt;/blockquote&gt;
&lt;p&gt;
[Via &lt;a href=&quot;http://w3future.com/weblog&quot; title=&quot;w3future.com&quot;&gt;Sjoerd Visscher&apos;s weblog&lt;/a&gt;]
&lt;/p&gt;</description>
			<guid isPermaLink="false">http://radio.weblogs.com/0122027/categories/tech/2003/11/11.html#a98</guid>
			<pubDate>Wed, 12 Nov 2003 01:12:06 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=122027&amp;amp;p=98&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0122027%2F2003%2F11%2F11.html%23a98</comments>
			</item>
		<item>
			<title>Apache Jakarta Commons Primitives 1.0 Released</title>
			<link>http://radio.weblogs.com/0122027/2003/11/06.html#a97</link>
			<description>&lt;p&gt;
I&apos;ve blogged a bit about the &lt;a href=&quot;http://jakarta.apache.org/commons/primitives/&quot; title=&quot;Apache Jakarta Commons Primitives&quot;&gt;Primitives Component&lt;/a&gt;
in &lt;a href=&quot;http://radio.weblogs.com/0122027/2003/04/15.html#a22&quot; title=&quot;Tuesday, 15 April 2003: I/O Iterators for Java&quot;&gt;the&lt;/a&gt; &lt;a href=&quot;http://radio.weblogs.com/0122027/2003/04/07.html#a13&quot; title=&quot;Monday, 7 April 2003: Rod&apos;s Open Source To Do List&quot;&gt;past&lt;/a&gt;, and I&apos;m happy to note that &lt;a href=&quot;http://article.gmane.org/gmane.comp.jakarta.commons.devel/34432&quot; title=&quot;[ANN] Jakarta Commons Primitives 1.0 Released&quot;&gt;commons-primitives now has an official 1.0 release&lt;/a&gt;
(&lt;a href=&quot;http://jakarta.apache.org/site/binindex.cgi#commons-primitives&quot; title=&quot;links to download primitives from a mirror&quot;&gt;binaries&lt;/a&gt;) (&lt;a href=&quot;http://jakarta.apache.org/site/sourceindex.cgi#commons-primitives&quot; title=&quot;links to download primitives from a mirror&quot;&gt;source&lt;/a&gt;).
&lt;/p&gt;&lt;p&gt;
Currently Primitives provides Java-primitive based versions of various Collection interfaces, which is substantially smaller and faster than working with the Object-wrapper equivalents.  For instance, an ArrayShortList requires 1/10th the space of an ArrayList of Shorts, and an ArrayLongList requires 2/5ths the space of an ArrayList of Longs.  There&apos;s a substantial time savings as well, in that one isn&apos;t constantly &quot;boxing&quot; and &quot;unboxing&quot; the primitives and their Object equivalents when moving them in and out of the Collection.  There are readability and &lt;a href=&quot;http://radio.weblogs.com/0122027/2003/04/15.html#a22&quot; title=&quot;Tuesday, 15 April 2003: I/O Iterators for Java&quot;&gt;other&lt;/a&gt; advantages as well.
&lt;/p&gt;&lt;p&gt;
(And, no, as I understand it, neither the auto-boxing nor the generics features of JDK 1.5 will obviate the need for this library.  You could use auto-boxing to emulate the syntax of list.add(int), but the internal representation will still be Object based.)
&lt;/p&gt;&lt;p&gt;
We use the primitive collections fairly extensively within the &lt;a href=&quot;http://axion.tigris.org/&quot; title=&quot;Axion Java Database Engine&quot;&gt;Axion database&lt;/a&gt; project for things like indices and lists of row identifiers or data file offsets, indeed the code was originally developed there.
&lt;/p&gt;</description>
			<guid isPermaLink="false">http://radio.weblogs.com/0122027/categories/tech/2003/11/06.html#a97</guid>
			<pubDate>Thu, 06 Nov 2003 17:08:37 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=122027&amp;amp;p=97&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0122027%2F2003%2F11%2F06.html%23a97</comments>
			</item>
		<item>
			<title>Custom Radio UserLand Clients?</title>
			<link>http://radio.weblogs.com/0122027/2003/11/04.html#a95</link>
			<description>&lt;p&gt;
&lt;a href=&quot;http://radio.userland.com/&quot; title=&quot;Radio UserLand&quot;&gt;Radio&lt;/a&gt; is a reasonably nifty weblog client, 
sporting an easy-to-use, web-based content management tool, a workable server-based news aggregator and a 
fairly robust weblog hosting infrastructure for USD$3.33 a month.
&lt;/p&gt;&lt;p&gt;
Things I find annoying about Radio include the fact that it won&apos;t run on a Unix-based OS (although there
are &lt;a href=&quot;http://radio.weblogs.com/0102385/2003/04/24.html&quot; title=&quot;Chris Double&apos;s Radio Weblog&quot;&gt;reports&lt;/a&gt;
of folks who&apos;ve got the Windows version up and running under Wine on Linux), it&apos;s got a fairly large footprint, and
it uses a relatively cumbersome and under-documented scripting framework.
&lt;/p&gt;&lt;p&gt;
All in all, the biggest appeal of Radio Userland to me is that I can get quick, easy and generally adequate weblog 
hosting for monthly cost less than a trip to Starbucks.  If only I could continue to use the hosting service and 
replace the Windows-based client--I&apos;d be happy to generate the weblog HTML via some homegrown software and simply 
upload the content via FTP or SCP.
&lt;/p&gt;&lt;p&gt;
Well, it&apos;s not quite as easy as FTP, but after poking around a bit, I&apos;ve figured out how to &quot;manually&quot; update a 
Radio hosted site, or more generally, 
&lt;a href=&quot;http://www.myelin.co.nz/wcswiki/w/CommunityServerWiki&quot; title=&quot;Community Server Wiki&quot;&gt;any of a number of servers&lt;/a&gt; 
that supports the 
&lt;a href=&quot;http://www.soapware.org/xmlStorageSystem&quot; title=&quot;SoapWare.org: xmlStorageSystem&quot;&gt;xmlStorageSystem&lt;/a&gt; XML-RPC protocol.
&lt;/p&gt;&lt;p&gt;
Here&apos;s a relatively crude but functional example using &lt;a href=&quot;http://jakarta.apache.org/commons/httpclient&quot;&gt;HttpClient&lt;/a&gt;.
&lt;/p&gt;&lt;p&gt;
First, the basic framework for processing a request and it&apos;s response.  This method takes a request &quot;body&quot; and returns the response.  Typically both the request and the response will be XML-RPC documents.
&lt;pre&gt;String processRequest(String body) throws IOException, HttpException {
    PostMethod method = new PostMethod();
    method.setRequestHeader(&quot;Content-type&quot;,&quot;text/xml&quot;);
    method.setRequestBody(body);
    method.setPath(&quot;/RPC2&quot;);
    method.setRequestContentLength(body.length());
&amp;nbsp;        
    HttpClient client = new HttpClient();        
&amp;nbsp;        
    HostConfiguration host = new HostConfiguration();
    host.setHost(&quot;radio.xmlstoragesystem.com&quot;);
&amp;nbsp;
    client.executeMethod(host,method);
&amp;nbsp;  
    return method.getResponseBodyAsString();
}&lt;/pre&gt;
&lt;p&gt;
Typically we pass an xmlStorageSystem request to this method as the String parameter.  Here&apos;s one simple example, a sort of
&quot;status&quot; query:
&lt;/p&gt;
&lt;pre&gt;&amp;lt;?xml version=&quot;1.0&quot;?&amp;gt;
&amp;lt;methodCall&amp;gt;
  &amp;lt;methodName&amp;gt;xmlStorageSystem.getServerCapabilities&amp;lt;/methodName&amp;gt;
  &amp;lt;params&amp;gt;
    &amp;lt;param&amp;gt;&amp;lt;value&gt;&amp;lt;!-- your radio user number, e.g., mine is &quot;122027&quot; --&gt;&amp;lt;/value&amp;gt;&amp;lt;/param&amp;gt;  
    &amp;lt;param&amp;gt;&amp;lt;value&gt;&amp;lt;!-- the md5 hash of your radio password as ASCII bytes --&gt;&amp;lt;/value&amp;gt;&amp;lt;/param&amp;gt;
  &amp;lt;/params&amp;gt;
&amp;lt;/methodCall&amp;gt;&lt;/pre&gt;
&lt;p&gt;
To create or update a file (or files), we use &lt;code&gt;saveMultipleFiles&lt;/code&gt;, for example:
&lt;/p&gt;
&lt;pre&gt;&amp;lt;?xml version=&quot;1.0&quot;?&amp;gt;
&amp;lt;methodCall&amp;gt;
  &amp;lt;methodName&amp;gt;xmlStorageSystem.saveMultipleFiles&amp;lt;/methodName&amp;gt;
  &amp;lt;params&amp;gt;
    &amp;lt;param&amp;gt;&amp;lt;value&amp;gt;&amp;lt;!-- your radio user number, e.g., mine is &quot;122027&quot; --&gt;&amp;lt;/value&amp;gt;&amp;lt;/param&amp;gt;  
    &amp;lt;param&amp;gt;&amp;lt;value&amp;gt;&amp;lt;!-- the md5 hash of your radio password as ASCII bytes --&gt;&amp;lt;/value&amp;gt;&amp;lt;/param&amp;gt;
    &amp;lt;param&amp;gt;
      &amp;lt;value&amp;gt;
        &amp;lt;array&amp;gt;
          &amp;lt;data&amp;gt;&amp;lt;value&amp;gt;/rpctest/test.html&amp;lt;/value&amp;gt;&amp;lt;/data&amp;gt; &amp;lt;!-- location of file --&amp;gt;
        &amp;lt;/array&amp;gt;
      &amp;lt;/value&amp;gt;
    &amp;lt;/param&amp;gt;
    &amp;lt;param&amp;gt;
      &amp;lt;value&amp;gt;
        &amp;lt;array&amp;gt;
          &amp;lt;data&amp;gt;&amp;lt;value&amp;gt;Hello World!&amp;lt;/value&amp;gt;&amp;lt;/data&amp;gt; &amp;lt;!-- contents of file --&amp;gt;
        &amp;lt;/array&amp;gt;
      &amp;lt;/value&amp;gt;
    &amp;lt;/param&amp;gt;
  &amp;lt;/params&amp;gt;
&amp;lt;/methodCall&amp;gt;&lt;/pre&gt;
&lt;p&gt;
To delete a file (or files), we use &lt;code&gt;deleteMultipleFiles&lt;/code&gt;, for example:
&lt;/p&gt;
&lt;pre&gt;&amp;lt;?xml version=&quot;1.0&quot;?&amp;gt;
&amp;lt;methodCall&amp;gt;
  &amp;lt;methodName&amp;gt;xmlStorageSystem.saveMultipleFiles&amp;lt;/methodName&amp;gt;
  &amp;lt;params&amp;gt;
    &amp;lt;param&amp;gt;&amp;lt;value&amp;gt;&amp;lt;!-- your radio user number, e.g., mine is &quot;122027&quot; --&gt;&amp;lt;/value&amp;gt;&amp;lt;/param&amp;gt;  
    &amp;lt;param&amp;gt;&amp;lt;value&amp;gt;&amp;lt;!-- the md5 hash of your radio password as ASCII bytes --&gt;&amp;lt;/value&amp;gt;&amp;lt;/param&amp;gt;
    &amp;lt;param&amp;gt;
      &amp;lt;value&amp;gt;
        &amp;lt;array&amp;gt;
          &amp;lt;data&amp;gt;&amp;lt;value&amp;gt;/rpctest/test.html&amp;lt;/value&amp;gt;&amp;lt;/data&amp;gt; &amp;lt;!-- location of file --&amp;gt;
        &amp;lt;/array&amp;gt;
      &amp;lt;/value&amp;gt;
    &amp;lt;/param&amp;gt;
  &amp;lt;/params&amp;gt;
&amp;lt;/methodCall&amp;gt;&lt;/pre&gt;
&lt;p&gt;
etc.
&lt;/p&gt;&lt;p&gt;
See &lt;a href=&quot;http://www.soapware.org/xmlStorageSystem&quot; title=&quot;SoapWare.org: xmlStorageSystem&quot;&gt;Dave Winer&apos;s writeup&lt;/a&gt; for more 
procedures, details and &lt;a href=&quot;http://www.soapware.org/stories/storyReader$16&quot;&gt;examples&lt;/a&gt;.
&lt;/p&gt;&lt;p&gt;
Now that I know how to manipulate my radio.weblogs.com site without using the Radio client, I&apos;m tempted to roll my own weblogging software, if only so I don&apos;t have to keep a Windows box around to support my blog.  As I mentioned above, there are &lt;a href=&quot;http://www.myelin.co.nz/wcswiki/w/CommunityServerWiki&quot; title=&quot;Community Server Wiki&quot;&gt;a number of servers&lt;/a&gt; that support the xmlStorageSystem protocol.  Anyone know of any non-Radio clients for xmlStorageSystem?  At minimum, something that syncs an arbitrary local directory with a remove xmlStorageSystem server should be easy enough to implement, which would allow anything that you can &quot;publish&quot; locally to be used as a client to a Community Server implementation.
&lt;/p&gt;</description>
			<guid isPermaLink="false">http://radio.weblogs.com/0122027/categories/tech/2003/11/04.html#a95</guid>
			<pubDate>Tue, 04 Nov 2003 21:24:32 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=122027&amp;amp;p=95&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0122027%2F2003%2F11%2F04.html%23a95</comments>
			</item>
		<item>
			<title>The Jakarta Commons Problem in a Nutshell</title>
			<link>http://radio.weblogs.com/0122027/2003/10/30.html#a94</link>
			<description>&lt;a href=&quot;http://nagoya.apache.org/eyebrowse/ReadMsg?listName=commons-dev@jakarta.apache.org&amp;msgNo=37216&quot;&gt;Exhibit A&lt;/a&gt;, 
&lt;a href=&quot;http://nagoya.apache.org/eyebrowse/ReadMsg?listName=commons-dev@jakarta.apache.org&amp;msgNo=37218&quot;&gt;Exhibit B&lt;/a&gt;</description>
			<guid isPermaLink="false">http://radio.weblogs.com/0122027/categories/tech/2003/10/30.html#a94</guid>
			<pubDate>Thu, 30 Oct 2003 15:26:23 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=122027&amp;amp;p=94&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0122027%2F2003%2F10%2F30.html%23a94</comments>
			</item>
		<item>
			<title>Wiki + Blog = PIM</title>
			<link>http://radio.weblogs.com/0122027/2003/10/22.html#a92</link>
			<description>&lt;p&gt;
I&apos;m one of those people who&apos;s so obsessed with organization that he&apos;s poorly organized.  I&apos;m constantly trying out new ways to manage the notes I scribble on various physical and electronic media, so much so that the frequency of change leads to greater disorganization.
&lt;/p&gt;&lt;p&gt;
I&apos;ve tried a number of &quot;information management&quot; tools, including index cards, sticky notes, notebooks, a Franklin planner, Microsoft Outlook, and various outlining, mind-mapping and PIM programs, and found them all wanting in one way or another (maybe it&apos;s me).  Paper based systems were too hard to search and too static in their organization.  Lacking a PDA, electronic systems weren&apos;t portable enough.  No matter what the system, I&apos;d always spend more time trying to set up organizational categories than I ever saved by using them. In fact I had pretty much broken the habit, falling back to a collection of loosely organized text files that I could easily scp to and from whatever workstation I was currently using.
&lt;/p&gt;&lt;p&gt;
About a year ago, I got a Sharp Zaurus, and since that addresses one of my recurring PIM complaints--having something that&apos;s always readily available, my hopes for finding the perfect PIM system were renewed.  I&apos;ve played around with a number of the PIM systems available.  Using the bundled Address Book/Calendar/To Do List/Email Client was too jumbled.  The &quot;outliner&quot; &lt;a href=&quot;http://iqnotes.kybu.sk/?page=index&quot;&gt;IQNotes&lt;/a&gt; was promising, but a single hierarchy is inflexible and using it to create dated journal entries requires too much manual effort.  In the end, I came back to a loosely organized collection of text files, this time stored on the Zaurus.
&lt;/p&gt;&lt;p&gt;
Back in my &lt;a href=&quot;http://radio.weblogs.com/0122027/2003/03/28.html#a3&quot; title=&quot;28 March 2003: First Post&quot;&gt;first post&lt;/a&gt;, I mentioned that one of the reasons I was interested in blogging is that I had become interested in journaling in general.  These two concepts--the search for the perfect organizational system and interest in journaling--interrelate.
&lt;/p&gt;&lt;p&gt;
As I&apos;m sure I&apos;m not the first to suggest, it seems that the ideal PIM system presents at least two perspectives on the information to be managed:
&lt;/p&gt;&lt;p&gt;
1) A time based view, answering such questions as &quot;what have I been working with recently?&quot; or &quot;what else was I working on around that time?&quot;
&lt;/p&gt;&lt;p&gt;
2) A &quot;concept network&quot; view, answering such questions as &quot;what&apos;s related to this topic?&quot; or &quot;what else do I know about this subject?&quot;
&lt;/p&gt;&lt;p&gt;
Clearly, I presume, blog-like software is an excellent starting point for the former, and wiki-like software is an excellent starting point for the former.  Fortunately, a number of projects have begun to explore combinations of the two, either by implementing a blog-as-wiki (like &lt;a href=&quot;http://snipsnap.org/&quot; title=&quot;snipsnap.org&quot;&gt;SnipSnap&lt;/a&gt; does) or by adding blogging features to a wiki engine (like &lt;a href=&quot;http://www.jspwiki.org/&quot; title=&quot;jspwiki.org&quot;&gt;JspWiki&lt;/a&gt; and no doubt others do).
&lt;/p&gt;&lt;p&gt;
Having a fair amount of Java experience (indeed, I&apos;ve built a little wiki or two in Java), my first thought was to get a Java based wiki up and running on my Zaurus.  JspWiki looks nice, and like most Java-based wikis is Servlet/JSP based, so I endeavored to get a WAR-friendly Java Servlet engine up and running on my Zaurus.  Having tried both Tomcat and Jetty under both the &lt;a href=&quot;http://www.esmertec.com/products/products_jeode.shtm&quot; title=&quot;Jeode Java Runtime Environment&quot;&gt;Jeode evm&lt;/a&gt; and &lt;a href=&quot;http://developer.java.sun.com/developer/earlyAccess/pp4zaurus/&quot; title=&quot;J2ME Personal Profile for Zaurus&quot;&gt;Personal Java cvm&lt;/a&gt;, I came close, but fundamentally failed to do this.  (I note that my SL-5500 had just barely enough disk space or memory to do this as well.) 
&lt;/p&gt;&lt;p&gt;
I briefly considered setting up a stand-alone (i.e., non-Servlet/JSP) Java wiki engine on the Zaurus, but without a moderate amount of development that seems like an awkward environment for templating and modification, and non-servlet Java web development feels like dead-end development. (Its only a matter of time before a reasonably micro servlet engine is available.)  That&apos;s when I stumbled across &lt;a href=&quot;http://c2.com/cgi/wiki?PhlIp&quot; title=&quot;Ward&apos;s Wiki: PhlIp&quot;&gt;PhlIp&lt;/a&gt;&apos;s &lt;a href=&quot;http://www.xpsd.com/MiniRubyWiki&quot; title=&quot;XpSD Wiki: Mini Ruby Wiki&quot;&gt;Mini Ruby Wiki&lt;/a&gt;, which implements a featureful, stand-alone wiki server in around 1000 lines of Ruby code.
&lt;/p&gt;&lt;p&gt;
(For the record, one could readily build a similarly featured wiki in Java, and probably a number of languages, in roughly the same number of lines, it might not be as much fun.)
&lt;/p&gt;&lt;p&gt;
It still took me a while to get a Ruby interpreter up and running on the Zaurus (after trying a few different builds, I finally got the one from &lt;a href=&quot;http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/46111&quot; title=&quot;Re: Ruby on the Sharp Zaurus PDA&quot;&gt;Vincent Fiack&lt;/a&gt; working), but the resulting binaries are smaller in terms of disk and memory footprint than the JVMs I was playing with.  Perhaps more importantly, as a purely interpreted language, the engine itself is easier to tweak.  And this gives me a reasonably good excuse to hack out some Ruby code.  I&apos;ve already added/modified a few minor features, adding some simple blog-like features to the calendar features that already existed.  If I come up with something I&apos;m not to embarrassed to share, I&apos;ll post it here or submit it to PhlIp&apos;s &lt;a href=&quot;http://rubyforge.org/projects/minirubywiki&quot; title=&quot;RubyForge: Project Info: MiniRubyWiki&quot;&gt;RubyForge&lt;/a&gt; project.
&lt;/p&gt;&lt;p&gt;
My only problem now is resisting the temptation to continually tweak the wiki engine code.
&lt;/p&gt;</description>
			<guid isPermaLink="false">http://radio.weblogs.com/0122027/categories/tech/2003/10/22.html#a92</guid>
			<pubDate>Wed, 22 Oct 2003 15:40:46 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=122027&amp;amp;p=92&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0122027%2F2003%2F10%2F22.html%23a92</comments>
			</item>
		<item>
			<title>A Timely Bug</title>
			<link>http://radio.weblogs.com/0122027/2003/10/17.html#a91</link>
			<description>&lt;p&gt;
I&apos;m a sucker for quirky bugs.  Recently, I&apos;ve been hacking around with &lt;a href=&quot;http://c2.com/cgi/wiki?PhlIp&quot; title=&quot;Ward&apos;s Wiki: PhlIp&quot;&gt;PhlIp&lt;/a&gt;&apos;s excellent &lt;a href=&quot;http://www.xpsd.com/MiniRubyWiki&quot; title=&quot;XpSD Wiki: Mini Ruby Wiki&quot;&gt;Mini Ruby Wiki&lt;/a&gt; (more on that later), and discovered one such bug.
&lt;/p&gt;&lt;p&gt;
There&apos;s a block of code in MiniRubyWiki that renders a small calendar in HTML, not unlike your typical blog calendar widget.  Here&apos;s a small subset (the actual code is more interesting that this) which is largely although not completely unchanged from the original miniWiki.rb source.  See if you can spot the bug.
&lt;/p&gt;&lt;pre&gt;
  # here&apos;s a constant, declared elsewhere in the program
  SecondsInDay = 60 * 60 * 24
&amp;nbsp;
  # ...
&amp;nbsp;
  # In this loop we&apos;re rendering a four-week calendar,
  # from the beginning of last week until the end of the week after next.
  # &quot;beginningOfLastWeek&quot; is a Time indicating the Sunday of last week
&amp;nbsp;
  today = Time.now()
  (0...28).each do |day|
    dayOnCalendar = beginningOfLastWeek + day * SecondsInDay
    # break the row every seven days
    calendar += &apos;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&apos; if day.divmod(7)[1] == 0
    calendar += &apos;&amp;lt;td&apos;
    # highlight today
    if today.mday() == dayOnCalendar.mday() then
      calendar += &apos; bgcolor=&quot;#88ff88&quot;&apos;
    end
    calendar += &apos;&amp;gt;&apos; 
    # show the month for the first day in the calendar or in the month
    calendar += dayOnCalendar.strftime(&apos;%b&apos;) + &apos; &apos; if dayOnCalendar.mday == 1 or day == 0
    calendar += dayOnCalendar.mday.to_s() 
&amp;nbsp;
    # ...snip some stuff displayed within the calendar...
&amp;nbsp;
    calendar += &apos;&amp;lt;/tr&amp;gt;&apos;
  end
&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;
I&apos;ve been running this code on my Zaurus, sometimes launching it from the EmbeddedKonsole on the Zaurus itself, and sometimes from an ssh terminal running on a remote machine.  Eventually I noticed something funky about this.  When I launch the server from the ssh terminal, 1 November 2003 is listed, correctly, as a Saturday.  When I launch the server from a terminal on the Zaurus itself, 1 November isn&apos;t listed at all (the last day on the calendar is 31 October 2003, listed, incorrectly, as a Saturday).  In fact, when I launch the server from the Zaurus, Sunday, 26 October 2003 is listed twice.
&lt;/p&gt;&lt;p&gt;
Adding a &quot;puts curDay.to_s&quot; line inside that loop makes the problem obvious.  This output like the following:
&lt;/p&gt;
&lt;pre&gt;Sun Oct 19 00:00:00 CDT 2003
Mon Oct 20 00:00:00 CDT 2003
Tue Oct 21 00:00:00 CDT 2003
Wed Oct 22 00:00:00 CDT 2003
Thu Oct 23 00:00:00 CDT 2003
Fri Oct 24 00:00:00 CDT 2003
Sat Oct 25 00:00:00 CDT 2003
Sun Oct 26 00:00:00 CDT 2003
Sun Oct 26 23:00:00 CST 2003
Mon Oct 27 23:00:00 CST 2003
Tue Oct 28 23:00:00 CST 2003
Wed Oct 29 23:00:00 CST 2003
Thu Oct 30 23:00:00 CST 2003
Fri Oct 31 23:00:00 CST 2003&lt;/pre&gt;
&lt;p&gt;
That&apos;s right, sometimes &lt;tt&gt;24 * 60 * 60&lt;/tt&gt; is the wrong value for SecondsInDay.  Due to the switch from CDT to CST, 26 October 2003 has 25 hours, so adding SecondsInDay to the midnight time isn&apos;t sufficient to advance the day.
&lt;/p&gt;&lt;p&gt;
For whatever reason, when launched via remote ssh terminal, the interpreter doesn&apos;t seem to be aware of the locale (it shows the times as UTC), but when launched from EmbeddedKonsole, Time.now() is aware of the locale and manages the switch from CDT to CST automatically, leading to the bug.
&lt;/p&gt;&lt;p&gt;
Cute, no?
&lt;/p&gt;</description>
			<guid isPermaLink="false">http://radio.weblogs.com/0122027/categories/tech/2003/10/17.html#a91</guid>
			<pubDate>Fri, 17 Oct 2003 22:23:12 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=122027&amp;amp;p=91&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0122027%2F2003%2F10%2F17.html%23a91</comments>
			</item>
		<item>
			<title>Kudos to Jakarta Commons FileUpload</title>
			<link>http://radio.weblogs.com/0122027/2003/09/15.html#a89</link>
			<description>&lt;p&gt;
Recently &lt;a href=&quot;http://www.sauria.com/blog/2003/09/13#580&quot; title=&quot;Ted Leung: 13 Sep 2003: I don&apos;t want to read your damned source code&quot;&gt;Ted&lt;/a&gt; and &lt;a href=&quot;http://www.freeroller.net/page/jdmarshall/20030912#disinterest_is_not_incompetence&quot; title=&quot;Jason Marshall: 12 Sep 2003: Disinterest Is Not Incompetence&quot;&gt;Jason&lt;/a&gt; blogged on an old complaint: open source projects aren&apos;t well documented.
&lt;/p&gt;&lt;p&gt;
In a curious coincidence, at the same time I had an very positive experience with open source documentation.  Being a Jakarta Commons committer, and having done my share of multipart/form-data parsing in the past, I was vaguely familiar with &lt;a href=&quot;http://jakarta.apache.org/commons/fileupload/&quot; title=&quot;Apache&apos;s Jakarta Commons FileUpload&quot;&gt;Commons FileUpload&lt;/a&gt; but hadn&apos;t had much cause to look into it until recently.  Not only does it feature an easy-to-use API that works like a charm, the &lt;a href=&quot;http://jakarta.apache.org/commons/fileupload/using.html&quot;&gt;Using FileUpload&lt;/a&gt; page tells one everything he needs to know to get up and running in minutes.
&lt;/p&gt;&lt;/p&gt;
Granted FileUpload addresses a pretty limited domain, and &lt;a href=&quot;http://jakarta.apache.org/commons/fileupload/customizing.html&quot; title=&quot;Customizing FileUpload&quot;&gt;not all the documentation is as complete&lt;/a&gt;, but I can&apos;t remember the last time I picked up a Java library and started using it without even cracking open the JavaDocs.
&lt;/p&gt;</description>
			<guid isPermaLink="false">http://radio.weblogs.com/0122027/categories/tech/2003/09/15.html#a89</guid>
			<pubDate>Mon, 15 Sep 2003 15:37:40 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=122027&amp;amp;p=89&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0122027%2F2003%2F09%2F15.html%23a89</comments>
			</item>
		<item>
			<title>Everything new is old again</title>
			<link>http://radio.weblogs.com/0122027/2003/08/27.html#a87</link>
			<description>&lt;p&gt;
Recently, &lt;a href=&quot;http://ww.telent.net/diary/2003/8/#24.85680&quot; title=&quot;Daniel Barlow -- Diary: Sun, 24 Aug 2003 23:48:00 GMT&quot;&gt;Daniel&lt;/a&gt;, &lt;a href=&quot;http://www.sauria.com/blog/2003/08/27#527&quot; title=&quot;Yep, time to stop copying&quot;&gt;Ted&lt;/a&gt;, &lt;a href=&quot;http://linuxintegrators.com/hl40/blog/blog/?permalink=0021.html&quot; title=&quot;OT: Everyone in open source/free software should read this like 10 times&quot;&gt;Andy&lt;/a&gt; and &lt;a href=&quot;http://www.cincomsmalltalk.com/blog/blogView?showComments=true&amp;entry=3239427426&quot; title=&quot;Time to invent&quot;&gt;James&lt;/a&gt; all point to a &lt;a href=&quot;http://lists.fifthvision.net/pipermail/arch-users/2003-May/027591.html&quot; title=&quot;[arch-users] [OT] Red Hat falls into ultimate hypocrisy?&quot;&gt;post&lt;/a&gt; by Tom Lord over on the &lt;a href=&quot;http://lists.fifthvision.net/pipermail/arch-users/&quot; title=&quot;The arch-users Archives&quot;&gt;arch-users&lt;/a&gt; mailing list.
&lt;/p&gt;&lt;p&gt;
Tom&apos;s comments are made in the context of &lt;a href=&quot;http://www.sun.com/smi/Press/sunflash/2003-05/sunflash.20030519.4.html&quot; title=&quot;Sun to Distribute Red Hat Enterprise Linux, Red Hat to Distribute Sun&apos;s Java&quot;&gt;Red Hat&apos;s agreement to distribute Sun&apos;s JVM as part of their &quot;Enterprise Linux&quot; offering&lt;/a&gt;, a story that (although I regularly program in Java and I&apos;m writing this post on Red Hat box) quite frankly I haven&apos;t been following at all.  Much of what is interesting about Tom&apos;s comments may be a function of reading them outside of this context.
&lt;/p&gt;
&lt;p&gt;
I find this a striking post, among other reasons, because it raises several distinct responses from me:
&lt;/p&gt;
&lt;dl&gt;

&lt;dt&gt;&lt;b&gt;1. What are we building?&lt;/b&gt;&lt;/dt&gt;
&lt;dd&gt;
&lt;p&gt;
Tom suggests:
&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There has been a sort of tension in the commercial free operating system world:&lt;/p&gt;
&lt;p&gt;(a) Are we building a free alternative to proprietary software?&lt;/p&gt;
&lt;p&gt;or&lt;/p&gt;
&lt;p&gt;(b) Are we building a commodity, $0-price OS component to lower the cost of proprietary applications?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For my part, this is a false dichotomy.  In my open source efforts I&apos;m not trying to do either of these, but rather to simply &lt;b&gt;build something useful&lt;/b&gt;.  Whether this something is an alternative or adjunct to proprietary software is incidental at best.  For that matter, whether this something is truly innovative or just a more useful variation of a component that already exists isn&apos;t terribly significant either (although the utility of copying something that&apos;s already readily available is limited of course).
&lt;/p&gt;&lt;p&gt;
I wonder if this a symptomatic of differing perspectives between the BSD-style and GPL-style camps of open source development.
&lt;/p&gt;
&lt;/dd&gt;

&lt;dt&gt;&lt;b&gt;2. How do we build it?&lt;/b&gt;&lt;/dt&gt;
&lt;dd&gt;
&lt;p&gt;
Tom writes:
&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
If the goal is (a), then we need an architect.  We need to come up with an inexpensive-to-develop architecture that, nevertheless, contains viable solutions for the needs of our markets.
&lt;/p&gt;&lt;p&gt;
If the goal is (b), then we need an anti-architect.  We need to come up with impossibly-expensive-to-fully-develop clone projects of proprietary software to draw off the energy of volunteer contributors who might otherwise undermine the value of the proprietary applications we expect to drive revenues for our distro.
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
Here option B is obviously a straw-man, so of course I&apos;ll follow option A.  But while I agree we need &quot;an inexpensive-to-develop architecture&quot;, and the word &quot;architect&quot; appears in my job title, I&apos;ll suggest a evolutionary approach is the best way to get there.  Inexpensive-to-develop systems of any interesting size, let alone federations of such systems, are rarely &quot;architected&quot; in a traditional sense.  &lt;b&gt;What we need is an environment where diverse ideas are allowed to compete, cooperate and breed&lt;/b&gt;. 
&lt;/p&gt;
&lt;/dd&gt;

&lt;dt&gt;&lt;b&gt;3. How hard is a Java implementation, really?&lt;/b&gt;&lt;/dt&gt;
&lt;dd&gt;
&lt;p&gt;
Running throughout Tom&apos;s post is the notion that a reasonably complete Java environment is simply too complicated to implement in an open source fashion:
&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
For example, under (a), we would probably have to admit that trying to
clone all the Java libraries _and_ build a competitive Java
implementation is too expensive a course of action.  While we might be
perfectly happy to ship a low-end, incomplete implementation to help
the low-end of the market, in the long run, we&apos;d want to look for a
more clever solution: something that can compete with Java and Java
libraries on functionality, but that is cheaper to build in the first
place (and cheaper and more effective to apply, of course).
&lt;/p&gt;
&lt;p&gt;[...]&lt;/p&gt;
&lt;p&gt;
[Y]ou can also make things expensive to
develop by structuring them as an object oriented framework that you
then spend zillions on filling out with subclasses, or by making
really hard components (like finely tuned JIT compilers and garbage
collectors) critical to implementations.
&lt;/p&gt;
&lt;p&gt;[...]&lt;/p&gt;
&lt;p&gt;
Some architectures, such as the Java environments and the
view-tree/component-based GUI frameworks, are ideal for large
proprietary software companies with large command-and-control armies
of developers and QA practitioners.   Those architectures are a
terrible fit for the loose confederation of generally underresourced
developers in the free and open source software world.
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
Putting aside questions of productivity and effectiveness, and the &quot;enterprise&quot; libraries for the moment, how hard is the core Java environment to implement, really?  More difficult than a Lisp implementation, for example, but I suspect it&apos;s not substantially more difficult to implement than, say, a C implementation, and probably on par with something like Ruby.
&lt;/p&gt;
&lt;/dd&gt;

&lt;dt&gt;&lt;b&gt;4. Where are the alternative Java implementations then?&lt;/b&gt;&lt;/dt&gt;
&lt;dd&gt;
&lt;p&gt;
Well, &lt;a href=&quot;http://dmoz.org/Computers/Programming/Languages/Java/Implementations/&quot; title=&quot;DMOZ: Computers/Programming/Languages/Java/Implementations&quot;&gt;there are several&lt;/a&gt; actually, although relatively few complete or robust ones.  Why?  Perhaps one compelling reason is that proprietary yet free (as in beer) Java runtime environments are readily available for most platforms.
&lt;/p&gt;
&lt;p&gt;Besides, who really wants another Java platform anyway...&lt;/p&gt;
&lt;/dd&gt;

&lt;dt&gt;&lt;b&gt;5. &quot;Yep, time to stop copying&quot;&lt;/b&gt;&lt;/dt&gt;
&lt;dd&gt;
&lt;p&gt;
Like Daniel and Ted, I find the general call for innovation dead on:
&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
For a long time, the right strategy for GNU was to build a basic unix replacement differentiated primarily by licensing. [...]&lt;/p&gt;&lt;p&gt;
Well, that part&apos;s done and the strategy won.
&lt;/p&gt;&lt;p&gt;
[...]
&lt;/p&gt;&lt;p&gt;
If the goal is still &quot;(a) build a free alternative to proprietary software&quot;, then a new strategy is called for: competition on &lt;i&gt;software architecture&lt;/i&gt;, not just licensing. 
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
Here Tom and I are in violent agreement.  If I were building an open source compiler and/or language-platform, I&apos;d certainly think twice about doing it on &lt;a href=&quot;http://www.tbray.org/ongoing/When/200x/2003/07/12/WebsThePlace&quot; title=&quot;The Web&amp;#146;s the Place&quot;&gt;Sun&apos;s plantation&lt;/a&gt;--not because it&apos;s too hard; in part (as before) because the utility of copying something that&apos;s already readily available is limited; but mostly because I think you could construct more useful environments.
&lt;/p&gt;&lt;p&gt;
It&apos;s worth applying this, independently, to the &quot;enterprise libraries&quot; I set aside earlier.  Are J2EE implementations like &lt;a href=&quot;http://incubator.apache.org/projects/geronimo.html&quot;&gt;Apache Geronimo&lt;/a&gt; or &lt;a href=&quot;http://jboss.org&quot;&gt;JBoss&lt;/a&gt; building something &quot;useful&quot; or a &quot;$0-price OS component to lower the cost of proprietary applications&quot;?  From my perspective, I&apos;ve found some pieces of the J2EE suite to be quite useful, and others seem to fit Tom&apos;s &quot;proprietary vendor&quot; strategy. 
&lt;/p&gt;
&lt;/dd&gt;

&lt;dt&gt;&lt;b&gt;6. Except when it isn&apos;t&lt;/b&gt;&lt;/dt&gt;
&lt;dd&gt;
&lt;p&gt;
It&apos;s interesting to observe how quickly the arch-users thread evolves from &quot;we need a new architecture&quot; to &quot;we need a Lisp platform&quot;.  (It&apos;s doubly interesting to note how often that seems to be the case.)  And perhaps that really is what we need.  But there&apos;s a big difference between &quot;time to stop copying&quot; and &quot;time to stop copying Java&quot;.
&lt;/p&gt;&lt;p&gt;
(Actually, although I think one could do much better than to copy Java, you could also do much worse.  It would be naive to think that Java&apos;s success is purely coincidental or purely the result of marketing muscle.  They must be doing something right.)
&lt;/p&gt;&lt;p&gt;
More generally, it would be naive to think that what we need is innovation for innovation&apos;s sake, and I think deciding we need to resurrect a 40 year old platform is evidence of this fact.
&lt;/dd&gt;

&lt;dt&gt;&lt;b&gt;7. What are we building, revisited.&lt;/b&gt;&lt;/dt&gt;
&lt;dd&gt;
&lt;p&gt;Tom writes:&lt;/p&gt;
&lt;blockquote&gt;
Nowadays, the proprietary competition is about databases, and
productivity apps, and browsers, and middleware layers.  The software
we&apos;re competing against is not like unix: it isn&apos;t simple; it wasn&apos;t
built by a small number of people; it&apos;s a moving target.  It
isn&apos;t a tractable project to clone this proprietary software under
different licensing.
&lt;/blockquote&gt;
&lt;p&gt;
This point is puzzling.  Certainly we don&apos;t mean to assert that it is impossible to successfully build
&lt;a href=&quot;http://www.mysql.com/&quot; title=&quot;MySQL, &amp;quot;the world&apos;s most popular open source database&amp;quot;&quot;&gt;open&lt;/a&gt;
&lt;a href=&quot;http://www.postgresql.org/&quot; title=&quot;PostgreSQL, &amp;quot;the world&apos;s most advanced open source database software&amp;quot;&quot;&gt;source&lt;/a&gt;
&lt;a href=&quot;http://axion.tigris.org/index.html&quot; title=&quot;Axion, the Java Database&quot;&gt;databases&lt;/a&gt;, 
&lt;a href=&quot;http://mozilla.org/&quot; title=&quot;Mozilla.org&quot;&gt;web&lt;/a&gt; 
&lt;a href=&quot;http://www.konqueror.org/&quot; title=&quot;Konqueror - Web Browser, File Manager - and more!&quot;&gt;browsers&lt;/a&gt;, 
or &lt;a href=&quot;http://zope.org/&quot; title=&quot;Zope: an open source application server&quot;&gt;middleware&lt;/a&gt;
&lt;a href=&quot;http://www.mico.org/&quot; title=&quot;MICO: a freely available and fully compliant implementation of the CORBA standard&quot;&gt;servers&lt;/a&gt;,
do we?
Do we assert it is a bad idea to do so?
&lt;/p&gt;&lt;p&gt;
While I certainly think we should look for innovative ways to solve the sorts of problems these projects do,
it would be a mistake to believe that the existing approaches don&apos;t offer something of value simply because they have strong proprietary implementations as well--just as it would have been a mistake for the GNU project to reject a pipe-and-filter architecture simply because a strong implementation was once controlled by Bell Labs.  I don&apos;t think it is tractable to create a wholly new software paradigm--one that doesn&apos;t contain variations of n-tier, database and web technologies--out of thin air.  We need new ideas, but we need old ones too.
&lt;/p&gt;
&lt;/dd&gt;
&lt;/dl&gt;</description>
			<guid isPermaLink="false">http://radio.weblogs.com/0122027/categories/tech/2003/08/27.html#a87</guid>
			<pubDate>Thu, 28 Aug 2003 01:26:57 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=122027&amp;amp;p=87&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0122027%2F2003%2F08%2F27.html%23a87</comments>
			</item>
		<item>
			<title>Adaptive vs. Predictive Planning</title>
			<link>http://radio.weblogs.com/0122027/2003/08/18.html#a82</link>
			<description>&lt;p&gt;
At my day job, we develop what seems to be a wide variety of systems: several subscription based web sites, a suite of desktop applications, an e-commerce system for selling both subscriptions and physical products, and various financial, administrative, content management, editorial and reporting systems for supporting them.  We&apos;ve been developing most of those systems under a locally adapted form of XP for about three years now.
&lt;/p&gt;&lt;p&gt;
For a lot of what we do an agile process works well.  We&apos;re often making &quot;small&quot; modifications to a running (production) system, so a process that allows the customer to say &quot;here&apos;s a set of changes, implement and deploy them in the next couple of weeks&quot; fits our needs rather  well.  Even the least imaginative customer is typically able to break down large changes into an incremental series of small ones, and is often happy to see the intermediate steps in a running (although not always production) system.
&lt;/p&gt;&lt;p&gt;
Allow me to call this approach &quot;adaptive&quot; planning. (I don&apos;t think I&apos;m the first to do so.)  An interesting feature, perhaps the defining feature, of this adaptive approach is that customer is often defining new requirements as we&apos;re implementing the old ones, so that we&apos;re not always exactly sure where we&apos;re going when we start.  It&apos;s sort of like a hill climbing approach: we take a few steps in what seems to be the right direction and then reevaluate.  Our plan adapts to changing business requirements and generally doesn&apos;t try to look very far ahead in any detail.
&lt;/p&gt;&lt;p&gt;
It doesn&apos;t take a lot of insight to see that an adaptive approach is well suited to what might be called &quot;product&quot; as opposed to &quot;project&quot; management.  If one conceives of the system as long-lived, constantly improving entity, it&apos;s easier to be comfortable with an iterative development process. No one can really foresee where the system is going to end up anyway, so the urge to ask &quot;when is it going to be done?&quot; is lessened.
&lt;/p&gt;&lt;p&gt;
On the other hand, there are times when the customer wants, or at least thinks he wants, a more predictive planning process:  &quot;Here&apos;s a large set of requirements, when are they going to be met?&quot;  This question is important because the answer will often drive business deals, strategic planning, and revenue projections.  Depending upon the time sensitivity of the opportunity, the answer may determine whether the project is worth initiating at all.
&lt;/p&gt;&lt;p&gt;
Frankly, I don&apos;t think our process is very good at answering this sort of question.  In practice, the way we approach such a question is quite similar to most &quot;traditional&quot; methodologies: we&apos;ll collect coarse grained requirements and prepare coarse grained estimates for them.  This process is often time consuming--the customer team will spend weeks struggling to define and communicate a &quot;base&quot; set of requirements for estimation purposes.  The result is often unsatisfactory--poorly understood and poorly articulated requirements lead to poor estimates.
&lt;/p&gt;&lt;p&gt;
One solution is to somehow dissuade the customer from believing that he needs detailed planning or long term predictions.  Sometimes it really is a distinction without a difference--we&apos;re going to do the work anyway, so knowing precisely what features make it into the version 1.0 release or precisely when this release will occur are details that can be determined later.  Most projects end with some negotiation of scope and schedule anyway.  The trouble is, sometimes accurate predictions really do matter.
&lt;/p&gt;&lt;p&gt;
Another solution is to accept the limitations of this predictive approach--we don&apos;t really know how long it will take to complete the project, or what &quot;complete&quot; really means in the first place, so the best we can do is take an educated guess and know that the margin of error (and therefore the risk) is high.  True as it may be, this answer is unsatisfactory at best, and unacceptable at worst.  The fact that traditional planning approaches don&apos;t fare much better is little consolation.
&lt;/p&gt;&lt;p&gt;
We&apos;ve been through this &quot;predictive&quot; planning exercise perhaps four times in the past three years, and have found it to be successful, but only moderately so.  Increasingly I am beginning to believe that the adaptive process may be a more effective way of arriving at accurate predictions anyway.  Through a lack of information, insight, or political capital, I&apos;ve never seen it played this way, but I&apos;m beginning to think this is the right approach:
&lt;/p&gt;&lt;p&gt;
Rather than spending a couple of weeks (or more) trying to determine a rough but &quot;complete&quot; estimate for the total cost of the project, spend that time developing an implementation of some of the base features (call it a &quot;spike solution&quot; or prototype if that helps, but it&apos;s really neither of those things).  The requirements will certainly be incomplete, maybe even wrong.  The implementation is likely to be wrong too, or will be when the requirements are better understood.  I think that that may not matter.
&lt;/p&gt;&lt;p&gt;
Part of what leads me to this conclusion is that this is what we really do anyway.  Although the thought is &quot;let&apos;s not go down this road until we&apos;re sure that&apos;s what we want to do&quot;, in practice what we&apos;ll struggle to determine what the &quot;total cost&quot; of the project is going to be until it becomes clear that if we don&apos;t initiate the development soon, we won&apos;t be able to hit the requisite dates anyway.  We may only be 60% sure that the project is worth pursuing, but the schedule eventually makes the decision for us.  Indeed, this is how we first adopted an XP practice: as a way out of the &quot;analysis paralysis&quot; threatening a major product initiative.
&lt;/p&gt;&lt;p&gt;
(This last-minute adaptive approach is expensive in at least a couple of ways.  Firstly, by the time a deadline is looming, we no longer have the luxury of slowly ramping up size the development team, we need to throw all our developers at the system immediately.  This is a chaotic way of doing green-field development.  Secondly, when we follow this approach, it&apos;s rarely the most important features we attack first, it&apos;s the ones that are easiest to define.)
&lt;/p&gt;&lt;p&gt;
I think this &quot;just get started&quot; approach may bring several benefits over a predict-then-implement one.  Having a working system, however rudimentary...
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;makes the total cost estimate more accurate simply by virtue of having some of the requirements already implemented.  We don&apos;t need to guess what those will cost--they&apos;re already done.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;makes the development team more confident about their ability to address the remaining requirements.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;makes the development team better able to predict what&apos;s going to be tricky and what isn&apos;t.  We have some measure of the team&apos;s velocity when working on the system in question.  As a result, estimates should be more accurate.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;provides the customer team with a reference point to work from.  Rather than saying &quot;here&apos;s what the final system will look like&quot;, they can be begin to express requirements as &quot;here&apos;s how I want to you change the existing system.&quot;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;may give the customer team enough confidence in the development team&apos;s ability to deliver the end product to follow an iterative/evolutionary approach.  Once it&apos;s clear that we can deliver &lt;i&gt;something&lt;/i&gt; by the deadline, it may be less important precisely what that something is.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Of course, the customer team can in parallel continue to define and refine the requirements and seek a &quot;total cost&quot; estimate, but at least for these first few iterations, we don&apos;t need to worry too much about the total scope of the project
&lt;/p&gt;&lt;p&gt;
There is some risk here, namely that after a couple of weeks of development it becomes clear that this is not a project worth pursuing and hence the development effort in those first few weeks is wasted.  I can&apos;t imagine that this cost is significantly greater than the cost of the predictive analysis, but for better or worse in my environment there is a general impression that development resources are precious and hence need to be conserved--it&apos;s better to waste &quot;analysis&quot; time than &quot;development&quot; time.  Overcoming this impression may be the key to selling this approach.
&lt;/p&gt;&lt;p&gt;
Looking over what I&apos;ve written here, it looks like I&apos;m describing a straight-forward XP process, and perhaps I am.  In some ways, the distinction may be in the &lt;i&gt;reasons&lt;/i&gt; for the adaptive approach.  In our typical agile project, we sell the just-in-time requirements definition process as a way to get development moving while the business is still working out requirements.  When predictive questions are asked, the business often believes that the requirements are already defined (although in practice they&apos;re often not as well defined as the customer may believe), only the technical cost needs to be determined.  In this case the iterative development cycle may be more valuable to the technical team than to the business.
&lt;/p&gt;&lt;p&gt;
It may be interesting to explore how to use an adaptive planning process to answer predictive planning questions.
&lt;/p&gt;</description>
			<guid isPermaLink="false">http://radio.weblogs.com/0122027/categories/tech/2003/08/18.html#a82</guid>
			<pubDate>Mon, 18 Aug 2003 17:13:05 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=122027&amp;amp;p=82&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0122027%2F2003%2F08%2F18.html%23a82</comments>
			</item>
		<item>
			<title>Commons Logging was my fault</title>
			<link>http://radio.weblogs.com/0122027/2003/08/15.html#a81</link>
			<description>&lt;p&gt;
I&apos;ll come right out and admit it: &lt;a href=&quot;http://jakarta.apache.org/commons/logging.html&quot; title=&quot;Jakarta Commons Logging&quot;&gt;commons-logging&lt;/a&gt;, at least in its initial form, was my fault, though probably not mine alone.
&lt;/p&gt;&lt;p&gt;
Back in 2001 I did a fair bit of work &lt;a href=&quot;http://google.com/search?q=cache:www.mail-archive.com/jakarta-commons%40jakarta.apache.org/msg03954.html&quot; title=&quot;&amp;quot;[httpclient] refactoring httpclient&amp;quot; (from jakarta-commons@jakarta.apache.org, 27 Aug 2001) [google cache]&quot;&gt;refactoring and debugging&lt;/a&gt; &lt;a href=&quot;http://jakarta.apache.org/commons/httpclient&quot; title=&quot;Jakarta Commons HttpClient&quot;&gt;commons-httpclient&lt;/a&gt;.  As part of that effort, I replaced a custom setDebug()/System.out.println based logging system with &lt;a href=&quot;http://jakarta.apache.org/log4j/&quot; title=&quot;Apache&apos;s Jakarta Log4J&quot;&gt;log4j&lt;/a&gt;.  I did this for several reasons but all of them come down to the fact that a fully-fledged logging system is often quite useful.  In fact, that debugging effort probably wouldn&apos;t have happened without it.
&lt;/p&gt;&lt;p&gt;
This change turned out to be controversial, and a runtime dependency upon log4j was in fact &lt;a href=&quot;http://google.com/search?q=cache:www.mail-archive.com/jakarta-commons%40jakarta.apache.org/msg02694.html&quot; title=&quot;&amp;quot;Re: [httpclient] logging and testing changes&amp;quot; (from jakarta-commons@jakarta.apache.org, 27 Jul 2001) [google cache]&quot;&gt;vetoed&lt;/a&gt;.  After an enormous amount of discussion, not all of it pretty, a &lt;a href=&quot;http://google.com/search?q=cache:www.mail-archive.com/jakarta-commons%40jakarta.apache.org/msg02778.html&quot; title=&quot;&amp;quot;Re: [httpclient] [VOTE] HTTP client 1.0 release&amp;quot; (from jakarta-commons@jakarta.apache.org, 1 Aug 2001) [google cache]&quot;&gt;compromise&lt;/a&gt; was finally agreed to.  This compromise basically said (a) use a thin wrapper around either log4j or the System.out logging initially implemented and (b) allow the user to specify whether to use log4j or System.out.println based upon a method call (inversion-of-control style I guess) or an external property.  I did the first implementation of this.  It was later &lt;a href=&quot;http://google.com/search?q=cache:www.mail-archive.com/jakarta-commons%40jakarta.apache.org/msg02794.html&quot; title=&quot;&amp;quot;logging again (was RE: [httpclient] [VOTE] HTTP client 1.0 release)&amp;quot; (from jakarta-commons@jakarta.apache.org, 3 Aug 2001) [google cache]&quot;&gt;suggested&lt;/a&gt;, probably reasonably so, that this &quot;log wrapping&quot; package be extracted from httpclient for use in similar circumstances.  In a more robust or complicated form (depending upon your perspective) this eventually became commons-logging.
&lt;/p&gt;&lt;p&gt;
For all its warts, this brief history of Commons Logging shows the &quot;bazaar-style&quot; of open source development working as it should: the operative word here being &quot;compromise&quot;.
&lt;/p&gt;&lt;p&gt;
Personally, I don&apos;t believe it to be especially important that Jakarta Commons committers be able to express their creativity by the selection of logging frameworks.  I&apos;d have been happy simply using log4j, and I think Ceki&apos;s work with the &quot;light&quot; log4j-ME would have been sufficient to address most of the technical concerns raised.  Yet others disagree, and I&apos;ll respect that position.  Certainly respect for that position has encouraged advocates of &lt;a href=&quot;http://avalon.apache.org/logkit/&quot; title=&quot;Apache Avalon LogKit&quot;&gt;alternative logging implementations&lt;/a&gt; to participate more fully in Jakarta Commons.
&lt;/p&gt;&lt;p&gt;
That said, I think &lt;a href=&quot;http://www.freeroller.net/page/fate/20030811#the_evils_of_commons_logging&quot; title=&quot;The evils of commons-logging.jar and its ilk&quot;&gt;Hani&lt;/a&gt; and &lt;a href=&quot;http://www.freeroller.net/page/gstamp/20030812#commons_logging&quot; title=&quot;Commons logging&quot;&gt;Glen&lt;/a&gt; miss the point entirely.  The purpose of Commons Logging is &lt;i&gt;not&lt;/i&gt; to isolate your code from changes in the underlying logging framework.  (That&apos;s certainly easy enough to do on your own, and not really worth doing in the first place given the ease of switching from one logging framework to another.)  The purpose of Commons Logging is &lt;i&gt;not&lt;/i&gt; to somehow be more useful than actual logging frameworks by being more general.  The purpose of Commons Logging is &lt;i&gt;not&lt;/i&gt; to somehow take the logging world by storm.  In fact, there are very limited circumstances in which Commons Logging is useful. If you&apos;re building a stand-alone application, don&apos;t use commons-logging.  If you&apos;re building an application server, don&apos;t use commons-logging.  If you&apos;re building a moderately large framework, don&apos;t use commons-logging.  If however, like the Jakarta Commons project, you&apos;re building a tiny little &lt;i&gt;component&lt;/i&gt; that you intend for other developers to embed in their applications and frameworks, and you believe that logging information might be useful to those clients, and you can&apos;t be sure what logging framework they&apos;re going to want to use, then commons-logging might be useful to you.
&lt;/p&gt;&lt;p&gt;
On a slightly unrelated note, I think that Hani&apos;s post fails to adequately explain how the problems caused by trying to integrate systems that use incompatible versions of the same component are unique to Commons Logging.  If you want a discussion of the technical issues with Commons Logging, which are quite genuine, there are &lt;a href=&quot;http://www.qos.ch/logging/thinkAgain.html&quot; title=&quot;Ceki&apos;s &amp;quot;Think again before adopting the commons-logging API&amp;quot;&quot;&gt;much better analyses&lt;/a&gt; available.
&lt;/p&gt;</description>
			<guid isPermaLink="false">http://radio.weblogs.com/0122027/categories/tech/2003/08/15.html#a81</guid>
			<pubDate>Fri, 15 Aug 2003 18:59:08 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=122027&amp;amp;p=81&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0122027%2F2003%2F08%2F15.html%23a81</comments>
			</item>
		<item>
			<title>A chemist, a physicist and a computer scientist were traveling in a car...</title>
			<link>http://radio.weblogs.com/0122027/2003/08/14.html#a80</link>
			<description>&lt;p&gt;
I have to give a product demo this morning.  Although I hope I don&apos;t need to use it today, I&apos;m reminded of a little joke I used to tell back in my consulting days to keep the customer occupied when a problem forced me to do an unexpected restart, reboot or reinstall in the midst of a demonstration:
&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A chemist, a physicist and a computer scientist were traveling in a car when the engine suddenly puttered out and they were forced to pull over to the side of the road.&lt;/p&gt;
&lt;p&gt;&quot;We must be out of fuel&quot;, the chemist said, &quot;but I just saw a gas station.  I&apos;ll walk back and pick some up.&quot;&lt;/p&gt;
&lt;p&gt;&quot;No, no&quot;, said the physicist, &quot;that clearly sounded like a mechanical problem.  Let me pop the hood and take a look.&quot;&lt;/p&gt;
&lt;p&gt;&quot;Wait!&quot;, said the computer scientist. &quot;I have an idea.  Let&apos;s all get out of the car&amp;nbsp;.&amp;nbsp;.&amp;nbsp;.&amp;nbsp;and then get back in.&quot;&lt;/p&gt;
&lt;/blockquote&gt;</description>
			<guid isPermaLink="false">http://radio.weblogs.com/0122027/categories/tech/2003/08/14.html#a80</guid>
			<pubDate>Thu, 14 Aug 2003 13:17:35 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=122027&amp;amp;p=80&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0122027%2F2003%2F08%2F14.html%23a80</comments>
			</item>
		<item>
			<title>Quickie Radio Tidbits</title>
			<link>http://radio.weblogs.com/0122027/2003/08/11.html#a78</link>
			<description>&lt;ul&gt;
&lt;li&gt;Radio now supports &lt;a href=&quot;http://www.movabletype.org/trackback/&quot; title=&quot;MovableType: TrackBack Development&quot;&gt;TrackBack&lt;/a&gt;.  See &lt;a href=&quot;http://radio.userland.com/discuss/msgReader$26639&quot; title=&quot;TrackBack for Radio&quot;&gt;TrackBack for Radio&lt;/a&gt; for details, but the gist of it is this: (a) enable TrackBack through your &lt;a href=&quot;http://127.0.0.1:5335/system/pages/prefs?page=2.17&quot; title=&quot;your (localhost) trackback preferences page&quot;&gt;TrackBack preferences page&lt;/a&gt; then (b) invoke the &lt;tt&gt;&amp;lt;%trackbackLink%&amp;gt;&lt;/tt&gt; macro somewhere within your &lt;a href=&quot;http://127.0.0.1:5335/system/pages/prefs?page=3.4&quot; title=&quot;your (localhost) item template page&quot;&gt;item template&lt;/a&gt;. &lt;/li&gt;
&lt;li&gt;As you can see, I&apos;ve got trackback links turned on in this blog now.  I&apos;ve also added direct (non-JavaScript) links to my comments and trackback pages.  I did this by adding &lt;tt&gt;&amp;lt;%radio.weblog.getCommentLink(&amp;lt;%itemNum%&amp;gt;, adrblog)%&amp;gt; &lt;/tt&gt;and &lt;tt&gt;&amp;lt;%radio.weblog.getTrackbackLink(&amp;lt;%itemNum%&amp;gt;, adrblog)%&amp;gt;&lt;/tt&gt; calls to my item template.&lt;/li&gt;
&lt;li&gt;I&apos;ve finally figured out where many of the built-in Radio macros are stored.  From the Radio application, go to &lt;tt&gt;Window:Radio.Root:system:verbs:radio:weblog&lt;/tt&gt;.  The &lt;tt&gt;system/verbs&lt;/tt&gt; tree has a number of nifty macros, including &lt;tt&gt;radio.weblog.getUrl&lt;/tt&gt;, which generates the absolute URL of your Radio homepage.  This is the answer to a question I had &lt;a href=&quot;http://radio.weblogs.com/0122027/stories/2003/04/11/radioTidbits.html#waypathit&quot;&gt;previously asked&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Another pair of interesting macros I discovered there are &lt;tt&gt;radio.macros.previousDayLink&lt;/tt&gt; and &lt;tt&gt;radio.macros.nextDayLink&lt;/tt&gt;, which should generate day-to-day links in your archive pages.  I&apos;ve got this set up in my archives now, but there seem to be minor problems here and there.  For example, the previous day link from &lt;a href=&quot;http://radio.weblogs.com/0122027/2003/07/16.html&quot; title=&quot;The [L]GPL, Java and Asymmetry&quot;&gt;Wednesday, 16 July 2003&lt;/a&gt; goes to &lt;a href=&quot;http://radio.weblogs.com/0122027/2003/07/14.html&quot; title=&quot;Given enough eyeballs, are all trends shallow?&quot;&gt;Monday, 14 July 2003&lt;/a&gt;, skipping over the post on &lt;a href=&quot;http://radio.weblogs.com/0122027/2003/07/15.html&quot; title=&quot;my pet bug, or another example of how sun doesn&apos;t get community development&quot;&gt;Tuesday, 15 July 2003&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
When I get a chance, I&apos;ll type these up for my &lt;a href=&quot;http://radio.weblogs.com/0122027/stories/2003/04/11/radioTidbits.html&quot; title=&quot;Radio Tidbits&quot;&gt;Radio Tidbits&lt;/a&gt; page.
&lt;/p&gt;&lt;p&gt;
PS: I&apos;d love it if someone could point me to a definitive reference to Radio&apos;s scripting language.
&lt;/p&gt;</description>
			<guid isPermaLink="false">http://radio.weblogs.com/0122027/categories/tech/2003/08/11.html#a78</guid>
			<pubDate>Mon, 11 Aug 2003 17:26:32 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=122027&amp;amp;p=78&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0122027%2F2003%2F08%2F11.html%23a78</comments>
			</item>
		<item>
			<title>In Defense of XML</title>
			<link>http://radio.weblogs.com/0122027/2003/08/08.html#a77</link>
			<description>&lt;p&gt;
Recently I&apos;ve read a number of comments (some &lt;a href=&quot;http://www.toolshed.com/blog/News/LastArtima.html,v&quot; title=&quot;/\ndy&apos;s Weblog: Forensic Analysis and Plain Text&quot;&gt;old&lt;/a&gt; and some &lt;a href=&quot;http://www.freeroller.net/page/fate/20030801#as_stable_and_maintanable_as&quot; title=&quot;Bile Blog: As stable and maintainable as jelly&quot;&gt;new&lt;/a&gt;) that take issue with the use of XML for one purpose or another (in the above examples, Ant and Jelly scripts, respectively).  In fact, it seems all the cool kids are &lt;a href=&quot;http://www.google.com/search?q=xml+sucks&quot; title=&quot;Google on &amp;quot;xml sucks&amp;quot&quot;&gt;XML detractors&lt;/a&gt; these days, although the coolness may have peaked a few months ago, when even Tim Bray was &lt;a href=&quot;http://www.tbray.org/ongoing/When/200x/2003/03/16/XML-Prog&quot; title=&quot;ongoing: XML Is Too Hard For Programmers&quot;&gt;admitting&lt;/a&gt; that XML may not be as nifty as first thought.
&lt;/p&gt;&lt;p&gt;
Now, I&apos;ll certainly admit that XML has its drawbacks.  Is it overly verbose?  Often.  &lt;a href=&quot;http://okmij.org/ftp/Scheme/xml.html#SXML-spec&quot; title=&quot;XML and Scheme: SXML specification&quot;&gt;An equivalent s-expression syntax&lt;/a&gt; would be more concise and (for Lisp developers at least) more useful.  Is it hard to read? At times.  It&apos;s certainly better suited for documents where the ratio of text to tags is high.  Is XML often used for developer convenience at the expense of user convenience? Is there information that has no business being in an XML format, but that developers or vendors insist on making XML anyway? Yes, yes, of course.
&lt;/p&gt;&lt;p&gt;
(On a related note, if &quot;executable XML&quot; is such a bad idea, how does one explain the longevity of Lisp?)
&lt;/p&gt;&lt;p&gt;
Despite these limitations, there is some value in selecting XML over, say (as Andy Hunt suggested for Ant) some arbitrary context-free grammar.  
&lt;/p&gt;&lt;p&gt;
Part of this value is the ease with which a developer can drop in an XML parser, but that&apos;s only an indirect source of value.  Part of this value is the comfort that users familiar with popular SGML applications (read &quot;HTML&quot;) have with the angle bracket notation, but that may only explain the quick adoption.
&lt;/p&gt;&lt;p&gt;
The real value of XML is in the tool chain.
&lt;/p&gt;&lt;p&gt;
Suppose Ant had been based upon some custom, non-XML grammar.  What would we lose?
&lt;/p&gt;&lt;p&gt;
Well for one, nearly every programmer&apos;s editor has a syntax coloring, well-formedness-checking mode for XML (certainly emacs and vi, or at least vim, and nearly anything that calls itself an IDE).  Moreover, many editors support DTD or Schema validation as well, perhaps even tag and attribute completion.  Using an XML format means a host of editors can handle Ant scripts smartly.  The same would probably not have been true, at least initially, with some arbitrary grammar.
&lt;/p&gt;&lt;p&gt;
How does this come about?  Well in part because XML is a popular format, but also because of the ease with which a developer can drop in an XML parser and other libraries.
&lt;/p&gt;&lt;p&gt;
For another advantage, consider &lt;a href=&quot;http://www.wdvl.com/Authoring/Languages/XML/XMLFamily/BigPicture/bigpix20a.html&quot; title=&quot;Big Picture of the XML Family of Specifications&quot;&gt;the plethora of XML-based or XML-extending specifications&lt;/a&gt;.  Many commentators have looked at that dense diagram and scoffed: not everything is well suited for an XML representation.  Yet few would deny that at least some of those technologies do something truly useful.
&lt;/p&gt;&lt;p&gt;
Similarly, consider the number of tools, libraries and technologies that implement those specifications or provide other XML utilities.  Want a pretty printer?  There&apos;s a tool for that (indeed you&apos;re probably using one right now).  Want an API for processing arbitrary XML?  There&apos;s several, in nearly any language you can name.  Want portable validation?  Want to combine dialects?  Want to translate one schema to another?  Want simple macro support?  Want to embed or link sub-documents?  Want to generate hyperlinked documentation for a script or it&apos;s syntax?  There&apos;s a tool for that too.
&lt;/p&gt;&lt;p&gt;
Sometimes it&apos;s sufficient to be adequate and popular, when that means a strong tool chain comes along for the ride.  Sometimes &lt;a href=&quot;http://www.ai.mit.edu/docs/articles/good-news/good-news.html&quot; title=&quot;Richard P. Gabriel: Lisp: Good News, Bad News, How to Win Big&quot;&gt;worse really is better&lt;/a&gt;, or at least good enough.
&lt;/p&gt;</description>
			<guid isPermaLink="false">http://radio.weblogs.com/0122027/categories/tech/2003/08/08.html#a77</guid>
			<pubDate>Fri, 08 Aug 2003 17:38:26 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=122027&amp;amp;p=77&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0122027%2F2003%2F08%2F08.html%23a77</comments>
			</item>
		<item>
			<title>Clover Plug-in for Eclipse (and NetBeans)</title>
			<link>http://madbean.com/blog/45/</link>
			<description>&lt;p&gt;
Matt Quail &lt;a href=&quot;http://madbean.com/blog/45/&quot;&gt;writes&lt;/a&gt; &quot;We have just released (beta) an &lt;a href=&quot;http://www.thecortex.net/clover/userguide/eclipse/index.html&quot;&gt;Eclipse&lt;/a&gt; plugin and a &lt;a href=&quot;http://www.thecortex.net/clover/userguide/netbeans/index.html&quot;&gt;NetBeans&lt;/a&gt; plugin for Clover, allowing you to instrument your code and view coverage results all from with the those Java IDEs.&quot;
&lt;/p&gt;&lt;p&gt;
Haven&apos;t tried it yet, but the screenshots look like exactly what I was hoping for. Sweet.
&lt;/p&gt;</description>
			<guid isPermaLink="false">http://radio.weblogs.com/0122027/categories/tech/2003/08/08.html#a76</guid>
			<pubDate>Fri, 08 Aug 2003 12:45:59 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=122027&amp;amp;p=76&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0122027%2F2003%2F08%2F08.html%23a76</comments>
			</item>
		<item>
			<title>The Silent Majority Pays for Open Source</title>
			<link>http://radio.weblogs.com/0122027/2003/07/30.html#a69</link>
			<description>&lt;p&gt;
When you think of a writer, you probably imagine a book author, a journalist, an essayist, or even a script writer of some sort, but it&apos;s generally someone who makes a living selling their words.  But the majority of text isn&apos;t produced for direct or even indirect sale: it&apos;s used to remind your spouse to pick up a gallon of milk at the store, or to thank Aunt Rita for that lovely sweater, or to point your friend to that really funny website you saw this morning.  Even the majority of text someone gets paid to write isn&apos;t written for sale: it&apos;s in business correspondence, or restaurant menus, or on mortgage applications, or bus schedules, or in instruction manuals, or on the back of cereal boxes.  Practically everywhere you look you can find the written word.  Someone was paid to write much of it, and yet hardly ever are you buying the words themselves.
&lt;/p&gt;&lt;p&gt;
Most of the time text isn&apos;t the end product, it&apos;s a tool for communication.  Lots of folks are paid to write something, very few of them view the text itself as the product.  It&apos;s a means to an end.
&lt;/p&gt;&lt;p&gt;
Yesterday Alan Williamson asked &lt;a href=&quot;http://alan.blog-city.com/read/158430.htm&quot; title=&quot;Who Pays for Open-Source?&quot;&gt;&quot;Who pays for open source?&quot;&lt;/a&gt; and answered his own question with &quot;The great belief, as sung by pretty much all companies involved in open source, is &apos;we charge for support&apos;.&quot;
&lt;/p&gt;&lt;p&gt;
Andy Oliver &lt;a href=&quot;http://linuxintegrators.com/hl30/blog/general/?permalink=Alan+Williamson+and+the+Forms+of+open+source.html&quot; title=&quot;Alan Williamson and the Forms of open source&quot;&gt;suggests&lt;/a&gt; this is but one open source business model, but goes on to define four &quot;forms&quot; that all pretty much come down to &quot;we charge for support&quot;.
&lt;/p&gt;&lt;p&gt;
I think &lt;a href=&quot;http://www.livejournal.com/users/stevenberkowitz/&quot; title=&quot;Steven&apos;s LJ&quot;&gt;Steven Berkowitz&lt;/a&gt;, in a comment to Alan&apos;s post, gets much closer to the truth: &quot;Open source projects that somehow make money for someone, be it through support, consulting, etc., are the exceptions.&quot;  I&apos;ll take that comment one step further: Modulo outsourcing, software projects that directly make money for someone, be it through sales, support, etc., are the exceptions.
&lt;/p&gt;&lt;p&gt;
I&apos;m going to make an assumption here, but I think it&apos;s an assumption I can safely make.  The majority of software developers aren&apos;t selling software, or even software support and services.
&lt;/p&gt;&lt;p&gt;
Living as I do, in Chicago, where I&apos;m &lt;a href=&quot;http://www.bls.gov/&quot; title=&quot;U.S. Department of Labor: Bureau of Labor Statistics&quot;&gt;told&lt;/a&gt; both the per capita and absolute number of software developers is higher than the Silicon Valley, I think this observation is a bit more obvious.  I know a lot of software developers, but practically none of them build software for direct sale to consumers or businesses.  When a &quot;software development&quot; firm is hired, it&apos;s often for custom (or at least customized) development.  Even when we sell shrink-wrapped software, &lt;a href=&quot;http://store.britannica.com/escalate/store/CategoryPage?pls=britannica&amp;bc=britannica&amp;cc=videos_software&quot; title=&quot;Britannica Store: Software&quot;&gt;as my company does&lt;/a&gt;, it&apos;s not the software that customers are really buying. 
&lt;/p&gt;&lt;p&gt;
For most companies and for most developers, software isn&apos;t a business, it&apos;s a tool for getting the real work done.
&lt;/p&gt;&lt;p&gt;
In this scenario, it&apos;s easy to see why a company might use open source software: just find me the best tool for the job.  It&apos;s also easy to see why a company might allow its IT staff (internal or outsourced) to contribute to open source development.  Critical as it might be, and as disastrous as it can be when it fails, few companies rely upon software for their competitive advantage.  I don&apos;t care if my competitors use the same web or database server that I do, or for that matter the same XML parser, caching engine, unit testing framework, or database connection pool that I do.  Indeed there is some advantage to me if the non-proprietary parts of my infrastructure become commodities.
&lt;/p&gt;&lt;p&gt;
While the public face of open source software might be the folks that are trying to build a business around it, I suspect that&apos;s because, well, they&apos;re selling something.  Who pays for open source development?  My guess is that the answer is the same as it is for most software development: the folks who are trying to get something else done.
&lt;/p&gt;</description>
			<guid isPermaLink="false">http://radio.weblogs.com/0122027/categories/tech/2003/07/30.html#a69</guid>
			<pubDate>Wed, 30 Jul 2003 18:18:19 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=122027&amp;amp;p=69&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0122027%2F2003%2F07%2F30.html%23a69</comments>
			</item>
		<item>
			<title>Wanted: GUI Wrapper for Text-Based Java Applications</title>
			<link>http://radio.weblogs.com/0122027/2003/07/29.html#a67</link>
			<description>&lt;p&gt;
I&apos;ve got a simple console-based (i.e.,  text interface) Java application that I&apos;d like to expose via Java Web Start or as an Applet.  I can&apos;t, however, because System.in and System.out aren&apos;t attached to anything useful, so my application runs invisibly and can&apos;t collect any input.
&lt;/p&gt;&lt;p&gt;
What I need is a simple wrapper application that creates a basic text i/o frame that looks like stdin/stdout to my application&apos;s main method.  (Or, failing that, to a custom &lt;nobr&gt;&lt;code&gt;main(String[] args, InputStream stdin, PrintStream stdout, PrintStream stderr)&lt;/code&gt;&lt;/nobr&gt; method.)  More elaborate interfaces, such as color coded output, distinct stdout and stderr frames, spool to file, etc., are easily imagined.
&lt;/p&gt;&lt;p&gt;
I believe such an application would have fairly broad utility.  A web search finds quite a few elaborate telnet/ssh oriented terminal emulators, which one might be able to pare down to what I&apos;m looking for, but it seems like someone would have already tackled this problem.  Lazy web to the rescue?
&lt;/p&gt;</description>
			<guid isPermaLink="false">http://radio.weblogs.com/0122027/categories/tech/2003/07/29.html#a67</guid>
			<pubDate>Wed, 30 Jul 2003 00:10:38 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=122027&amp;amp;p=67&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0122027%2F2003%2F07%2F29.html%23a67</comments>
			</item>
		<item>
			<title>A is for Axion ... Z is for Zaurus</title>
			<link>http://radio.weblogs.com/0122027/2003/07/24.html#a64</link>
			<description>&lt;p&gt;
I&apos;ve got &lt;a href=&quot;http://axion.tigris.org/&quot; title=&quot;Axion Java Relational Database&quot;&gt;Axion&lt;/a&gt; up and running on my &lt;a href=&quot;http://www.zaurus.com/&quot; title=&quot;Zaurus.com: Sharp&apos;s Zaurus site&quot;&gt;Zaurus&lt;/a&gt;.
&lt;/p&gt;&lt;p&gt;
If you&apos;d like to do the same, here&apos;s how:
&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Obtain a build of the Axion HEAD (1.0M3-dev).  See the &lt;a href=&quot;http://axion.tigris.org/building.html&quot; title=&quot;Building Axion&quot;&gt;instructions on building Axion&lt;/a&gt; for details.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Obtain binaries of Axion&apos;s runtime dependencies, namely &lt;a href=&quot;http://jakarta.apache.org/commons/collections/&quot; title=&quot;Jakarta Commons Collections&quot;&gt;Jakarta Commons Collections&lt;/a&gt; (currently a &lt;a href=&quot;http://jakarta.apache.org/builds/jakarta-commons/nightly/commons-collections/&quot; title=&quot;Commons-Collections nightlies&quot;&gt;nightly&lt;/a&gt; build is required) and &lt;a href=&quot;http://jakarta.apache.org/commons/logging/&quot; title=&quot;Jakarta Commons Logging&quot;&gt;Jakarta Commons Logging&lt;/a&gt; (you&apos;ll want release 1.0.3, earlier versions don&apos;t work on the Jeode VM).&lt;/p&gt;
&lt;p&gt;If you want to use the LIKE operator, you&apos;ll also need &lt;a href=&quot;http://jakarta.apache.org/regexp/&quot; title=&quot;Jakarta Regexp&quot;&gt;Jakarta Regexp&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you want to use the BASE64ENCODE or BASE64DECODE functions, you&apos;ll also need &lt;a href=&quot;http://jakarta.apache.org/commons/codec&quot; title=&quot;Jakarta Commons Codec&quot;&gt;Jakarta Commons Codec&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;Ensure that you have the java.util Collections and java.sql JDBC packages available on your platform.  Since the Insignia Jeode VM installed on the Zaurus by default is JDK 1.1 based, I had to copy over the JDK Collections manually.  I had thought the Collections package was available as a standalone JAR to drop in to JDK 1.1 environments but as I was unable to find it.  I just copied over the rt.jar from a JDK 1.3 installation, but I think the java.util package would suffice.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Obtain a copy of axiondb.properties.  You can pull this out of the Axion JAR or from &lt;a href=&quot;http://axion.tigris.org/source/browse/axion/conf/axiondb.properties&quot; title=&quot;axion/conf/axiondb.properties&quot;&gt;CVS&lt;/a&gt;.  Normally Axion loads this file out of the JAR automatically, but the Jeode VM seems to always return null for getClassLoader so we had to add a mechanism for specifying the configuration as an external file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now simply copy those files over to the Zaurus, add the JARs to your classpath, and you are ready to go.  For example to run the Axion console I use:&lt;/p&gt;
&lt;pre&gt;evm 
 -Dorg.axiondb.engine.BaseDatabase.properties=axiondb.properties 
 -classpath axion-1.0-M3-dev.jar:
            commons-collections.jar:
            commons-logging.jar:
            commons-codec.jar:
            regexp.jar:
            rt.jar 
 org.axiondb.tools.Console $1 $2&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;
Similar steps should get Axion up and running on other micro or J2ME platforms or for that matter, other JDK 1.1 environments.
If the console is any indication, Axion seems to run rather well on the Zaurus (even running off a compact flash card rather than the RAM disk).
&lt;/p&gt;&lt;p&gt;
If folks were interested, it wouldn&apos;t be difficult to create an IPK installer for Axion, although my interest here, and others as well I imagine, is in using Axion within other apps on the Zaurus, rather than playing with Axion via the console.
&lt;/p&gt;&lt;p&gt;
If you&apos;re curious, I did have to make a few minor changes to Axion to get it run on the Jeode/JDK 1.1 VM.  Here&apos;s a brief list of what I had to change:
&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The Jeode VM always seems to return null for getClassLoader (rather than throwing a security exception), so I had to add checks for null, and provide an alternative mechanism for loading the properties file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We had used File.createNewFile in several places, which is a JDK 1.2 method.  These calls turned out to be unnecessary anyway, so I simply removed them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Although it&apos;s easy to add java.util.Comparable and java.util.Comparator to the classpath, none of the core objects (Number, String, etc.) actually implement Comparable in JDK 1.1, so I had to add custom Comparators replacing ComparableComparator for those DataTypes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For reasons I don&apos;t understand, in several places where we had an hierarchy like this:&lt;/p&gt;
&lt;pre&gt;interface Foo {
  void someMethod();
}
&amp;nbsp;
abstract class AbstractBar implements Foo {
  void anotherMethod() {
    doSomething();
  }
}
&amp;nbsp;
class Bar extends AbstractBar {
  void someMethod() {
    doSomethingElse();
  }
}&lt;/pre&gt;
&lt;p&gt;I had to declare the interface methods in the abstract class:&lt;/p&gt;
&lt;pre&gt;abstract class AbstractBar implements Foo {
  &lt;b&gt;abstract void someMethod();&lt;/b&gt;
&amp;nbsp;
  void anotherMethod() {
    doSomething();
  }
}&lt;/pre&gt;&lt;p&gt;
to make various AbstractMethodErrors go away.
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;
These changes have already been checked into the HEAD version of Axion, and should be part of the Milestone 3 release.
&lt;/p&gt;&lt;p&gt;
There are few Axion-based apps I&apos;ve been thinking of tinkering with on my Zaurus, some for personal use, others for my day job.  That may shake out a few issues I haven&apos;t yet encountered, but so far I&apos;ve got feature I&apos;ve tried working without too much trouble.
&lt;/p&gt;</description>
			<guid isPermaLink="false">http://radio.weblogs.com/0122027/categories/tech/2003/07/24.html#a64</guid>
			<pubDate>Thu, 24 Jul 2003 18:11:39 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=122027&amp;amp;p=64&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0122027%2F2003%2F07%2F24.html%23a64</comments>
			</item>
		<item>
			<title>The Great Wall of China</title>
			<link>http://radio.weblogs.com/0122027/2003/07/23.html#a63</link>
			<description>&lt;p&gt;
Although I&apos;m neither old enough nor wise enough to pull it off effectively, I&apos;m a fan of management by narrative: using a brief story or parable to illustrate a point.  Often I find it is sufficient to present the narrative without explicitly connecting the dots--I&apos;ll just tell the story and then launch into what I was otherwise going to say.  (As always, you need to understand your audience to use this approach effectively.  I&apos;ve noticed developers often respond well to leading with the narrative.  Suits, whether management, business or marketing folks, often respond best to hearing the explanation and then the metaphor.)
&lt;/p&gt;&lt;p&gt;
Yesterday, in the context of the early stages of a fairly large scale development project, I had the opportunity to tell the following.
&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;
When the emperor decided to build the 10,000 Li Wall, he didn&apos;t amass an army of men to start at one end and build to the other.  Nor did they start at both ends and build toward the middle, the way one might dig a long tunnel.  Rather, they assembled small teams of men and spread them far and wide.  Each crew was responsible for constructing a small section of the wall, separated by many li from the neighboring sections.
&lt;/p&gt;&lt;p&gt;
Like all ancient construction, the work was difficult, and by the time the section was complete the crew was greatly discouraged.  They had worked so hard, and seemed to have little to show for it but a single, isolated tower.
&lt;/p&gt;&lt;p&gt;
Yet as the crew made the long journey back to their homes, they would come across other sections of the wall--some complete, others being busily attended to by other work crews.  They came to discover that the wall stretched, section by section, from the Yellow Sea deep into the western desert.  They arrived home in awe of the enormity of what had already been accomplished, and more inspired than ever to complete the construction.
&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
I have no idea if this story is true (never let the facts stand in the way of a good story), my source is a half-remembered parable written by Franz Kafka.  In my limited understanding of Chinese history, the story is a half-truth: the Great Wall was assembled a bit more organically out of a series of smaller fortifications.
&lt;/p&gt;&lt;p&gt;
I was a little hesitant to tell this story as I think the metaphor can be easily misinterpreted.  I&apos;m not suggesting that large scale systems be built by teams with only local knowledge of the overall system.  Nor am I suggesting that if &quot;isolated towers&quot; aren&apos;t useful to you (or your customer) that this approach is a good one.  (This latter case is an example of where the reality makes a better metaphor than the story.  In practice Shih huang-ti connected a number of existing, independently useful fortifications to form the Great Wall.)  In fact, I think laying out a grand vision of the project and working on little bits here and there is a remarkably bad way to approach the development unless those little bits are useful to you in isolation.  Otherwise you&apos;re likely to end up with bits that aren&apos;t useful to you at all.  But with a little bit of discipline about which &quot;towers&quot; to build first, I think this serves as a useful metaphor for an effective (and not uncommon) development practice.  We&apos;re implementing a large and complex system via a series of user stories.  Rather than building out a major subsystem in its entirety and then moving on to the next one, we&apos;re implementing the skeleton of the end-to-end system, to which we will add meat (that is, complexity) in subsequent iterations.  We know any given story describes an incomplete subsystem at this stage, but each describes an cohesive unit of functionality, to which we can add complexity and functionality to fill out the walls between the towers.
&lt;/p&gt;</description>
			<guid isPermaLink="false">http://radio.weblogs.com/0122027/categories/tech/2003/07/23.html#a63</guid>
			<pubDate>Wed, 23 Jul 2003 18:25:07 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=122027&amp;amp;p=63&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0122027%2F2003%2F07%2F23.html%23a63</comments>
			</item>
		<item>
			<title>Curly braces, Pipes, Escape and other characters on the Zaurus</title>
			<link>http://radio.weblogs.com/0122027/2003/07/21.html#a59</link>
			<description>&lt;p&gt;
If you&apos;ve ever tried to type code, pseudo-code or shell scripts on the Sharp &lt;a href=&quot;http://www.zaurus.com/&quot; title=&quot;Zaurus.com: Sharp&apos;s Zaurus site&quot;&gt;Zaurus&lt;/a&gt;, you may have noticed that the little slide-out keyboard is missing some useful keys.  If you&apos;ve done much typing with this thumb-keyboard, you may have noticed that when you fat-finger a couple of keys, you can get some of those extra characters.  For my reference as much as yours, here&apos;s a short list:
&lt;/p&gt;
&lt;table border=&quot;1&quot; cellpadding=&quot;2&quot; cellspacing=&quot;0&quot;&gt;
&lt;tr&gt;
 &lt;th&gt;keys&lt;/th&gt;
 &lt;th&gt;character&lt;/th&gt;
 &lt;th&gt;unicode value&lt;/th&gt;
 &lt;th&gt;name&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
 &lt;td&gt;[Fn]+z&lt;/td&gt;
 &lt;td&gt;&amp;nbsp;&lt;/td&gt;
 &lt;td&gt;0x005A(?)&lt;/td&gt;
 &lt;td&gt;undo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
 &lt;td&gt;[Fn]+[Shift]+c&lt;/td&gt;
 &lt;td&gt;&amp;#x20AC;&lt;/td&gt;
 &lt;td&gt;0x20AC&lt;/td&gt;
 &lt;td&gt;euro symbol&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
 &lt;td&gt;[Fn]+[Shift]+[Backspace]&lt;/td&gt;
 &lt;td&gt;&amp;#x5B;&lt;/td&gt;
 &lt;td&gt;0x005B&lt;/td&gt;
 &lt;td&gt;left square bracket&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
 &lt;td&gt;[Fn]+[Shift]+,&lt;/td&gt;
 &lt;td&gt;&amp;#x5D;&lt;/td&gt;
 &lt;td&gt;0x005D&lt;/td&gt;
 &lt;td&gt;right square bracket&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
 &lt;td&gt;[Fn]+[Shift]+.&lt;/td&gt;
 &lt;td&gt;&amp;#x7B;&lt;/td&gt;
 &lt;td&gt;0x007B&lt;/td&gt;
 &lt;td&gt;left curly brace&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
 &lt;td&gt;[Fn]+[Shift]+[Enter]&lt;/td&gt;
 &lt;td&gt;&amp;#x7D;&lt;/td&gt;
 &lt;td&gt;0x007D&lt;/td&gt;
 &lt;td&gt;right curly brace&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
 &lt;td&gt;[Fn]+[Shift]+&apos;&lt;/td&gt;
 &lt;td&gt;&amp;#x5E;&lt;/td&gt;
 &lt;td&gt;0x005E&lt;/td&gt;
 &lt;td&gt;caret/circumflex&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
 &lt;td&gt;[Fn]+[Shift]+[Space]&lt;/td&gt;
 &lt;td&gt;&amp;#x60;&lt;/td&gt;
 &lt;td&gt;0x0060&lt;/td&gt;
 &lt;td&gt;tick/backquote&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
 &lt;td&gt;[Shift]+[Space]&lt;/td&gt;
 &lt;td&gt;&amp;#x7C;&lt;/td&gt;
 &lt;td&gt;0x007C&lt;/td&gt;
 &lt;td&gt;pipe&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
 &lt;td&gt;[Shift]+[Tab]&lt;/td&gt;
 &lt;td&gt;&amp;#x5C;&lt;/td&gt;
 &lt;td&gt;0x005C&lt;/td&gt;
 &lt;td&gt;backslash (note that this is listed incorrectly in the sharp doc)&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;
In the table above, &quot;[Fn]&quot; means the purple &quot;function&quot; key, &quot;[Shift]&quot; means the arrow-up &quot;shift&quot; key, &quot;[Backspace] means the white back-arrow/delete key, &quot;[Enter]&quot; means the purple &quot;return&quot; key, &quot;[Space]&quot; means the space bar, &quot;[Tab]&quot; means the purple tab key, and a &quot;+&quot; means hit these keys in combination, typically by holding down the &quot;meta&quot; keys first.
&lt;/p&gt;&lt;p&gt;
Also notice that the &quot;Cancel&quot; button works like &quot;Escape&quot;, which makes VI usable without resorting to the on-screen (virtual) keyboard.
&lt;/p&gt;&lt;p&gt;
There&apos;s &lt;a href=&quot;http://www.zaurus.com/dev/support/downloads/sl5600_keycode_v091.pdf&quot; title=&quot;Keycode for Java/Qtopia Applications&quot;&gt;a full keycode mapping table&lt;/a&gt; available on Sharp&apos;s site.
&lt;/p&gt;</description>
			<guid isPermaLink="false">http://radio.weblogs.com/0122027/categories/tech/2003/07/21.html#a59</guid>
			<pubDate>Mon, 21 Jul 2003 18:56:30 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=122027&amp;amp;p=59&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0122027%2F2003%2F07%2F21.html%23a59</comments>
			</item>
		<item>
			<title>LGPL and Java: More confused than ever</title>
			<link>http://radio.weblogs.com/0122027/2003/07/18.html#a57</link>
			<description>&lt;p&gt;
After &lt;a href=&quot;http://linuxintegrators.com/hl30/blog/technology/?permalink=LGPL+in+Java.html&amp;page=comments&quot; title=&quot;comments on Andy&apos;s &apos;LGPL in Java&apos;&quot;&gt;reading&lt;/a&gt; &lt;a href=&quot;http://www.rollerweblogger.org/comments/roller/Weblog/for_java_lgpl_is_viral&quot; title=&quot;comments on Dave&apos;s &apos;For Java, LGPL is viral.&apos;&quot;&gt;the&lt;/a&gt; &lt;a href=&quot;http://www.intertwingly.net/blog/1519.html&quot; title=&quot;comments on Sam&apos;s &apos;Two paths&apos;&quot;&gt;various&lt;/a&gt; &lt;a href=&quot;http://radiocomments2.userland.com/comments?u=122027&amp;p=56&quot; title=&quot;comments on Rod&apos;s &apos;The [L]GPL, Java and Asymmetry&apos;&quot;&gt;comment&lt;/a&gt; &lt;a href=&quot;http://developers.slashdot.org/developers/03/07/17/2257224.shtml&quot; title=&quot;comments on Slashdot&apos;s &apos;LGPL is Viral for Java&apos;&quot;&gt;threads&lt;/a&gt;, and seeing Andy and David&apos;s exchange in &lt;a href=&quot;http://superlinksoftware.com/text/lgpl.txt&quot;&gt;a bit more context&lt;/a&gt;, I&apos;m more confused than ever.
&lt;/p&gt;&lt;p&gt;
As quoted by Andy, Roy wrote:
&lt;/p&gt;
&lt;blockquote&gt;What the FSF needs to say is that inclusion of the external interface names (methods, filenames, imports, etc. defined by an LGPL jar file, so that a non-LGPL jar can make calls to the LGPL jar&apos;s implementation, does not cause the including work to be derived from the LGPL work even though java uses late-binding by name (requiring that names be copied into the derived executable), and thus does not (in and of itself) cause the package as a whole to be restricted to distribution as (L)GPL or as open source per section 6 of the LGPL.&lt;/blockquote&gt;
&lt;p&gt;
and Andy asked:
&lt;/p&gt;
&lt;blockquote&gt;Is this statement true with regards to the use of LGPL Java libraries by non-LGPL Java libraries?&lt;/blockquote&gt;
&lt;p&gt;
To which David replied:
&lt;/p&gt;
&lt;blockquote&gt;If I understand the statement correctly, yes -- that&apos;s exactly what section 6 is for.&lt;/blockquote&gt;
&lt;p&gt;
Seen in context, my reading is that LGPL does not infect Java code that simply references, invokes methods of, or extends an LGPL&apos;ed class.  Brad Kuhn&apos;s comments mentioned in the slashdot &quot;update&quot; seem to be reiterating that position.  I see this as saying all of my &lt;a href=&quot;http://radio.weblogs.com/0122027/2003/04/07.html#a12&quot; title=&quot;7 April 2003: A Question on Applying the LGPL to Java&quot;&gt;examples&lt;/a&gt; are not infectious.  Joe&apos;s &lt;a href=&quot;http://radiocomments2.userland.com/comments?u=122027&amp;p=12&quot; title=&quot;comments on &apos;A Question on Applying the LGPL to Java&apos;&quot;&gt;comments&lt;/a&gt; on that post focus on the word &quot;distribute&quot; in what may be a clarifying way (i.e., the in-memory, late-bound version of code that combines LGPL and non-LGPL code is not distributed, it is assembled at runtime, and therefore not in violation).
&lt;/p&gt;&lt;p&gt;
I hesitate to ask but the question seems inevitable: what does it mean to apply aspects to LGPL&apos;ed code?  If I hook in code to a cut-point in some LGPL&apos;ed code, is my cut-point code infected?  Does it matter if my AOP-system is implemented with byte-code manipulation, reflection or composition?  Does it matter if this happens at runtime or at compile time?  It seems that it would, and that feels like a fairly arbitrary distinction in some ways.
&lt;/p&gt;&lt;p&gt;
IANAL and this makes my head spin.  I&apos;m going back to writing code.  Someone let me know when there&apos;s a clear answer here.  (Unfortunately I think it may take a court to decide that.  Let&apos;s hope it never comes to that.)
&lt;/p&gt;</description>
			<guid isPermaLink="false">http://radio.weblogs.com/0122027/categories/tech/2003/07/18.html#a57</guid>
			<pubDate>Fri, 18 Jul 2003 17:35:52 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=122027&amp;amp;p=57&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0122027%2F2003%2F07%2F18.html%23a57</comments>
			</item>
		<item>
			<title>The [L]GPL, Java and Asymmetry</title>
			<link>http://radio.weblogs.com/0122027/2003/07/16.html#a56</link>
			<description>&lt;p&gt;
&lt;a href=&quot;http://linuxintegrators.com/hl30/blog/&quot; title=&quot;Andy Oliver&apos;s Blog&quot;&gt;Andy&lt;/a&gt; has finally &lt;a href=&quot;http://article.gmane.org/gmane.comp.jakarta.poi.devel/5900&quot; title=&quot;poi-dev@jakarta.apache.org: Re: [Followup] RE: Possibly Include HTMLParser Jar in contribcode?&quot;&gt;tracked down&lt;/a&gt; some answers on &lt;a href=&quot;http://linuxintegrators.com/hl30/blog/technology/?permalink=LGPL+in+Java.html&quot; title=&quot;LGPL in Java&quot;&gt;applying the LGPL to Java&lt;/a&gt;.  &lt;a href=&quot;http://www.rollerweblogger.org/page/roller/20030716#for_java_lgpl_is_viral&quot; title=&quot;For Java, LGPL is viral&quot;&gt;Dave&lt;/a&gt; and &lt;a href=&quot;http://www.intertwingly.net/blog/1519.html&quot; title=&quot;Two paths&quot;&gt;Sam&lt;/a&gt; had some additional comments.
&lt;/p&gt;&lt;p&gt;
A few points:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;In his &lt;a href=&quot;http://www.rollerweblogger.org/comments/roller/Weblog/for_java_lgpl_is_viral&quot; title=&quot;Comments on For Java, LGPL is viral&quot;&gt;comment thread&lt;/a&gt; Dave suggests that &quot;Class.forName() might also be a workaround&quot;, echoing &lt;a href=&quot;http://radio.weblogs.com/0122027/2003/04/07.html#a12&quot; title=&quot;7 April 2003: A Question on Applying the LGPL to Java&quot;&gt;questions on the LGPL in Java I previously mentioned&lt;/a&gt;.  The answers to those questions still aren&apos;t entirely clear to me, although the position of simply steering clear of LGPL/GPL code for Java is seems increasingly rational.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Sam writes &quot;An example of something that does solve the issue: JDBC&quot; but I&apos;m not sure I follow.  Does this mean Class.forName?  In other words, I can use a LGPL&apos;d database code as long as I never directly invoke the LGPL code?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Andy writes &quot;Thus we need a license for Java that guarantees contributors will donate back to the library that does not infect the outside code.&quot;&lt;/p&gt;
&lt;p&gt;Do we?  Why?  I think there is sufficient incentive to release most derivative works anyway, and if someone doesn&apos;t, who cares?  The open source project still gets more users, more support, more field testing, mo&apos; better, than it otherwise would.  If you make a few bucks selling proprietary extensions to my open source code, more power to you.  (You run the threat, of course, of the community re-implementing your proprietary extensions in an open source fashion, thus destroying your business model.  This disincentive to selling proprietary derivatives augments the incentives for releasing those derivatives to the community for further extension, testing, maintenance and support.)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
A big issue I have with the [L]GPL is the asymmetry of the license.  If Company X releases code under the [L]GPL, I&apos;m less troubled by the need to similarly open my derivative works (although the people who sign my paycheck quite reasonably have a different perspective on that--there is some work that is best kept proprietary, if only because it pays the bills) than by the fact that Company X, typically acting as the &quot;umbrella&quot; copyright holder (to both their original work and my contributions) now has more rights to my contributions than I do.  Under the viral GPL, I &lt;i&gt;cannot&lt;/i&gt; use the larger work under any terms but those provided by the GPL, and in isolation my contributions are probably pretty much useless.  Yet Company X (as the holder of the collective copyright) is free to take my (donated) work and theirs and release (or sell) it under whatever terms they choose.  I wonder if Stallman had foreseen this consequence when constructing the GPL.
&lt;/p&gt;&lt;p&gt;
The &quot;umbrella&quot; copyright holder on a BSD- or ASF-type license has the same rights of course, but the license grants me the ability to do pretty much whatever I want with the larger work, short of claiming it all to be my own.  There is very little that the copyright holder can do that I, as a user let alone contributor, cannot also do.  It seems to me that the license with the least restrictive terms is the one that is most &quot;free&quot;.
&lt;/p&gt;</description>
			<guid isPermaLink="false">http://radio.weblogs.com/0122027/categories/tech/2003/07/16.html#a56</guid>
			<pubDate>Wed, 16 Jul 2003 17:35:04 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=122027&amp;amp;p=56&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0122027%2F2003%2F07%2F16.html%23a56</comments>
			</item>
		<item>
			<title>my pet bug, or another example of how sun doesn&apos;t get community development</title>
			<link>http://radio.weblogs.com/0122027/2003/07/15.html#a54</link>
			<description>&lt;p&gt;
I&apos;ve submitted &lt;a href=&quot;http://developer.java.sun.com/developer/bugParade/bugs/4292531.html&quot; title=&quot;Bug Id 4292531: RFE: Undeprecate java.util.Date(String)&quot;&gt;a&lt;/a&gt; &lt;a href=&quot;http://developer.java.sun.com/developer/bugParade/bugs/4354100.html&quot; title=&quot;Bug Id 4354100: Repackage sun.net.www.content.* Classes (java.net.ContentHandler)&quot;&gt;few&lt;/a&gt;
insignificant bugs to Sun&apos;s &lt;a href=&quot;http://developer.java.sun.com/developer/bugParade/&quot; title=&quot;Sun&apos;s Java Bug Database&quot;&gt;Bug Parade&lt;/a&gt; over the years, most recently &lt;a href=&quot;http://developer.java.sun.com/developer/bugParade/bugs/4890211.html&quot; title=&quot;Bug Id 4890211&quot;&gt;&quot;Collections.ReverseOrder.equals method is lacking&quot;&lt;/a&gt;, which I submitted back in January of 2003 and was finally accepted yesterday (14 July).
&lt;/p&gt;&lt;p&gt;
This isn&apos;t a critical bug, of course: It&apos;s easy to work around (that is, replace) and frankly it&apos;s been an annoyance but not a real problem in my development efforts.  Moreover, it seems like Sun has been pretty busy over the last few months working on &lt;a href=&quot;http://java.net/&quot; title=&quot;java.net&quot;&gt;other things&lt;/a&gt;.  Nevertheless, this whole experience has been frustrating.
&lt;/p&gt;&lt;p&gt;
First, in my limited and anecdotal experience the time to respond to bug reports is getting much worse.  It took six months for the Java team to acknowledge this simple, and if I may say reasonably well documented (including a &quot;patch&quot; and unit test), bug.
&lt;/p&gt;&lt;p&gt;
Second, this is a good if trivial example of how Sun&apos;s community efforts fail in execution.  Here&apos;s a trivially simple (it&apos;s clear from inspection alone) and readily demonstrated (a complete unit test is provided) defect.  A trivially simple (one line, two if you add hashCode()) patch is provided, and yet it took six months to get the issue acknowledged.  Now I&apos;ll wait an indeterminate amount of time to see the problem fixed.  All that and this problem could have been analyzed, patched and regression tested in less time than it took me to write this post.  Even the slowest moving of open source projects would have had this problem patched, if not released, in a matter of weeks.  If Sun can&apos;t find a way to move more quickly (and &lt;a href=&quot;http://jcp.org/en/jsr/detail?id=176&quot; title=&quot;JSR 176: J2SE 1.5 (Tiger) Release Contents&quot;&gt;stop chasing the most superficial features of C#&lt;/a&gt;) Java seems destined to be eclipsed by community developed languages.
&lt;/p&gt;&lt;p&gt;
I&apos;ll uncharacteristically paraphrase Jerry Seinfeld here: &quot;Sun knows how to take community input, they just don&apos;t know what to do with it.  And that&apos;s really the most important part of community: the doing.&quot; (&lt;a href=&quot;http://tomsquotes.amhosting.net/sitcom/seinfeld/jerry/jerry2.htm&quot;&gt;text&lt;/a&gt;, &lt;a href=&quot;http://tomsquotes.amhosting.net/sitcom/seinfeld/jerry/reserve.wav&quot; title=&quot;.wav file&quot;&gt;audio&lt;/a&gt;)
&lt;/p&gt;
&lt;p&gt;
PS: Also note that the second bug I linked to above, &lt;a href=&quot;http://developer.java.sun.com/developer/bugParade/bugs/4354100.html&quot; title=&quot;Bug Id 4354100&quot;&gt;&quot;Repackage sun.net.www.content.* Classes (java.net.ContentHandler)&quot;&lt;/a&gt;, was already addressed by the time I submitted it, I personally added a comment to this effect nearly two years ago, and yet the bug sits marked &quot;In progress&quot; (and with 3 votes, none of them mine).
&lt;/p&gt;</description>
			<guid isPermaLink="false">http://radio.weblogs.com/0122027/categories/tech/2003/07/15.html#a54</guid>
			<pubDate>Tue, 15 Jul 2003 20:02:07 GMT</pubDate>
			<comments>http://radiocomments2.userland.com/comments?u=122027&amp;amp;p=54&amp;amp;link=http%3A%2F%2Fradio.weblogs.com%2F0122027%2F2003%2F07%2F15.html%23a54</comments>
			</item>
		</channel>
	</rss>
