<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Lab49 Blog &#187; Joe Morrison</title>
	<atom:link href="http://blog.lab49.com/archives/author/joe/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.lab49.com</link>
	<description>Technology and industry insights from Lab49.</description>
	<lastBuildDate>Wed, 08 Feb 2012 09:02:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Hot off the press: Apache CXF Web Service Development</title>
		<link>http://joemorrison.org/blog/2010/02/24/hot-off-the-press-apache-cxf-web-service-development/</link>
		<comments>http://joemorrison.org/blog/2010/02/24/hot-off-the-press-apache-cxf-web-service-development/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 00:02:57 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://joemorrison.org/blog/?p=104</guid>
		<description><![CDATA[My reward for blogging about CXF? I get to review the recent book Apache CXF Web Service Development by Naveen Balani and Rajeev Hathi. Looking forward to receiving my free review copy. (Are presses hot these days?)
]]></description>
			<content:encoded><![CDATA[<p>My reward for blogging about CXF? I get to review the recent book <a href="http://www.packtpub.com/apache-cxf-web-service-development/book">Apache CXF Web Service Development</a> by Naveen Balani and Rajeev Hathi. Looking forward to receiving my free review copy. (Are presses hot these days?)</p>
]]></content:encoded>
			<wfw:commentRss>http://joemorrison.org/blog/2010/02/24/hot-off-the-press-apache-cxf-web-service-development/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>In defense of elite, irrelevant curricula</title>
		<link>http://joemorrison.org/blog/2009/11/01/in-defense-of-elite-irrelevant-curricula/</link>
		<comments>http://joemorrison.org/blog/2009/11/01/in-defense-of-elite-irrelevant-curricula/#comments</comments>
		<pubDate>Sun, 01 Nov 2009 22:44:55 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[General Development]]></category>

		<guid isPermaLink="false">http://joemorrison.org/blog/?p=86</guid>
		<description><![CDATA[I&#8217;m a big fan of Joel Spolsky&#8217;s writing, but I take issue with his latest posting. Universities shouldn&#8217;t be focused on teaching students the technologies and practices of the day. Anything you can learn by leafing through Getting Things Done, Agile Software Development with Scrum, and Expert One-on-One J2EE Development without EJB does not belong [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m a big fan of <a href="http://www.joelonsoftware.com/">Joel Spolsky&#8217;s writing</a>, but I take issue with his <a href="http://www.joelonsoftware.com/items/2009/10/26.html">latest posting</a>. Universities shouldn&#8217;t be focused on teaching students the technologies and practices of the day. Anything you can learn by leafing through <em>Getting Things Done</em>, <em>Agile Software Development with Scrum</em>, and <em>Expert One-on-One J2EE Development without EJB</em> does not belong in a university curriculum. Rather, they should be teaching elite, irrelevant subjects like language, history, philosophy, math, math, and more math. (Although what takes the wind out of my sails is that the perfect rebuttal has <a href="http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html">already been written</a> by Joel Spolsky himself.)<br />
<span id="more-86"></span><br />
I don&#8217;t disagree with the argument that students ought to learn time management and teamwork, and I don&#8217;t recall universities doing a particularly good job of teaching those. (It&#8217;s been a long time since I&#8217;ve attended university, but since they are apparently trapped in the 1980s, my personal experience and memories of my time there are still relevant.) And maybe they don&#8217;t teach students about version control, estimating, and many other aspects of being a productive software developer. But here&#8217;s why I disagree with Joel&#8217;s premise:</p>
<p>1. Universities are supposed to fill the niche in the education system in which we train people to lead institutions and invent the future. I don&#8217;t want computer science students studying Spring and Scrum (neither of which will be relevant in ten years). I want them inventing new programming languages, I/O devices, and non-Von Neumann CPUs. I want them studying history so that when they are elected to Congress, they won&#8217;t act like idiots. I want them studying language, so that when they make speeches, they won&#8217;t sound like they&#8217;re illiterate. Let the red-brick universities and multi-compass-point institutions teach Scrum and Spring. Universities should be teaching foundational skills that will be relevant for fifty years, and that can&#8217;t be easily learned on one&#8217;s own.</p>
<p>2. Once upon a time, the implied contract between employers and employees included on-the-job training. Staff were hired on the basis of personality, brains, and initiative, and the specific requirements of the job would be learned on company time. Today every employer wants their staff to be highly trained, but on someone else&#8217;s nickel. Why must it be up to the universities? Even if young employees are perfectly launched, they still need to keep current or they will be obsolete in 5-10 years anyway. Universities should equip people with the underlying skills to keep current &#8211; a passion for learning, an ability to focus, and a love of reading. Keeping current is an ongoing activity in any case.</p>
<p>3. Current graduates don&#8217;t seem to be able to read, write or do math anyway. (Here&#8217;s where I stop defending universities.) Seriously, how can anyone get through 16+ years of education and not be able to write? It&#8217;s gotten to the point where if I see a business document with no major grammar errors, I say to myself &#8220;how refreshing&#8221;.  That&#8217;s very sad. Same for math; a basic knowledge of statistics is helpful in almost any area of business &#8211; but try to find someone who knows the difference between mean and median. My point is that if universities are going to do any refocusing at all, it should be on core skills. </p>
<p>So I urge Ivy League schools to go ahead and teach linear algebra and theory of computation and Haskell programming (which I bet we&#8217;re all using in five years anyway &#8211; seriously- but that&#8217;s another blog entry). And make the kids read Shakespeare and Faulkner. When they&#8217;re in charge of everything, we&#8217;ll be glad of it.</p>
]]></content:encoded>
			<wfw:commentRss>http://joemorrison.org/blog/2009/11/01/in-defense-of-elite-irrelevant-curricula/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Best practice for branching and merging? Depends on your SCM.</title>
		<link>http://joemorrison.org/blog/2009/08/30/best-practice-for-branching-and-merging/</link>
		<comments>http://joemorrison.org/blog/2009/08/30/best-practice-for-branching-and-merging/#comments</comments>
		<pubDate>Sun, 30 Aug 2009 21:22:46 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[General Development]]></category>

		<guid isPermaLink="false">http://joemorrison.org/blog/?p=79</guid>
		<description><![CDATA[I ran across a nice blog entry discussing the different use case assumptions made by Perforce vs ClearCase regarding when developers will branch and merge.  After using Perforce for the last two years and reading Laura Wingerd&#8217;s excellent book Practical Perforce, I&#8217;m heavily biased to the point of view that routine development should happen [...]]]></description>
			<content:encoded><![CDATA[<p>I ran across a <a href="http://www.weintraubworld.net/blog/index.php?blog=8&#038;cat=23">nice blog entry</a> discussing the different use case assumptions made by <em>Perforce</em> vs <em>ClearCase</em> regarding when developers will branch and merge.  After using Perforce for the last two years and reading Laura Wingerd&#8217;s excellent book <em>Practical Perforce</em>, I&#8217;m heavily biased to the point of view that routine development should happen on the trunk, and branches should be created only to fix bugs in old releases or to develop experimental new features that might not get merged back into the trunk.</p>
<p>But I also believe in the &#8220;when in Rome&#8221; principle. As developers, we should try to conform to the spirit and assumptions behind the tools we are using (e.g. nobody will thank you for using Lisp idioms in Java). So if we have to use ClearCase, and the Atria / Rational / IBM people expect us to develop on private branches, maybe we should. Opinions?</p>
]]></content:encoded>
			<wfw:commentRss>http://joemorrison.org/blog/2009/08/30/best-practice-for-branching-and-merging/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Serializable != Synchronized, especially not with Oracle</title>
		<link>http://joemorrison.org/blog/2009/07/18/serializable-synchronized-especially-not-with-oracle/</link>
		<comments>http://joemorrison.org/blog/2009/07/18/serializable-synchronized-especially-not-with-oracle/#comments</comments>
		<pubDate>Sun, 19 Jul 2009 00:33:07 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[Architecture]]></category>

		<guid isPermaLink="false">http://joemorrison.org/blog/?p=64</guid>
		<description><![CDATA[Recently I wrote some database code and tried to convince myself that it was threadsafe. I realized I&#8217;d made a basic mistake about the serializable isolation level, and thought it was worth a quick blog entry to post the explanation, in case anyone else runs into this situation. The problem can be represented by this [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I wrote some database code and tried to convince myself that it was threadsafe. I realized I&#8217;d made a basic mistake about the <strong>serializable</strong> isolation level, and thought it was worth a quick blog entry to post the explanation, in case anyone else runs into this situation. The problem can be represented by this simplified example:</p>
<div class="wp-caption alignnone"><img class="size-full wp-image-66" src="http://joemorrison.org/blog/wp-content/uploads/2009/07/serializableexample1.png" alt="Transaction Example" width="747" height="285" />
<p class="wp-caption-text">Transaction Example</p>
</div>
<p>Both transactions are trying to process withdrawals of $100. In either case, if the balance is sufficient, a status message is sent to a downstream system and the balance is reduced. Otherwise the transaction is aborted. If these transactions are run in the <strong>serializable</strong> isolation level, can they be executed concurrently without fear of overdrawing the account, sending the status message more than once, or creating any other problems? Actually, no.</p>
<p><span></span>A cursory read of the documentation on database isolation levels might lead you to believe that <strong>serializable </strong>means that transactions act as though they are being run serially, i.e. as if they had been <strong>synchronized</strong> (using Java terminology). But that would be wrong. Databases are only required to honor commitments about serializability from the perspective of the data they store. So in the example above, the database&#8217;s only responsibility is to ensure that the balance doesn&#8217;t go negative.</p>
<p><strong>Oracle </strong>read the fine print carefully and came up with a creative way to improve performance. It lets both transactions proceed full steam ahead, but only permits the first update statement to succeed. The second update will fail with an error:</p>
<pre>ORA-08177: Can't serialize access for this transaction.</pre>
<p>Your application has to check for this error and retry the whole transaction until it succeeds. It&#8217;s really quite smart. Essentially, Oracle is optimistically running the transactions as quickly as possible, hoping they <em>would have been</em> serializable. If that turns out to be wrong, Oracle tries to forget the whole thing happened by aborting the transaction. The result is higher concurrency and better performance than the more obvious locking based design, and it faithfully preserves the serializability rule.</p>
<p>The only problem is that in our example, the status message will get sent too many times. Oracle doesn&#8217;t care about the serializability of your non database-related application code. In the example above, only one of the transactions should succeed because the initial balance is $100. But both of them will send the message. The moral here is that you can&#8217;t use the <strong>serializable</strong> database isolation level to manage concurrency in your application code.</p>
<p>So what can you do? You could serialize the whole application code sequence (i.e. wrap it all in a synchronized block) but that would be needlessly throwing away performance. You could create a thread pool that guarantees that requests for the same ID will get serviced by the same thread, but that would be needlessly complicated. The simplest solution (which will work even if you run multiple instances of your entire application) is to have the database lock the row during the transaction, so that if any other transactions touch that row they will block until the running transaction completes. </p>
<p>Oracle allows you to do this by adding the clause <strong>FOR UPDATE</strong> to your select command, i.e.</p>
<pre>select balance from account where id = 123 for update</pre>
<p>That&#8217;s nice and simple, allows you to run your transaction in the usual, uncomplicated <strong>READ_COMMITTED</strong> isolation level, allows concurrent processing of different database rows without any possibility of race conditions, and doesn&#8217;t require any synchronization in your application code. Unfortunately it&#8217;s not portable. It works with Oracle and Sybase, but the rules for MS SQLServer are different.</p>
]]></content:encoded>
			<wfw:commentRss>http://joemorrison.org/blog/2009/07/18/serializable-synchronized-especially-not-with-oracle/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Excedrin headache #3.5.40128.1: Using combo boxes with the WPF DataGrid</title>
		<link>http://joemorrison.org/blog/2009/02/17/excedrin-headache-35401281-using-combo-boxes-with-the-wpf-datagrid/</link>
		<comments>http://joemorrison.org/blog/2009/02/17/excedrin-headache-35401281-using-combo-boxes-with-the-wpf-datagrid/#comments</comments>
		<pubDate>Wed, 18 Feb 2009 03:11:14 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://joemorrison.org/blog/?p=51</guid>
		<description><![CDATA[If you&#8217;re working with the WPF DataGrid (January 2009 release, version 3.5.40128.1) and want to display a column of combo boxes (e.g. to select a value from a list of options) you may be in for a headache, especially if you want the available options to be supplied from the binding context.  For example [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://joemorrison.org/blog/wp-content/uploads/2009/02/combobox-example.png"><img src="http://joemorrison.org/blog/wp-content/uploads/2009/02/combobox-example.png" alt="" width="300" height="300" class="alignright size-medium wp-image-52" /></a>If you&#8217;re working with the WPF DataGrid (January 2009 release, version 3.5.40128.1) and want to display a column of combo boxes (e.g. to select a value from a list of options) you may be in for a headache, especially if you want the available options to be supplied from the binding context.  For example say you are displaying an editable table of orders, and each order is for a particular quantity of a particular product, and the products are selectable using combo boxes. </p>
<p>Here is a solution, the main element of which came from a <a href="http://www.codeplex.com/wpf/WorkItem/View.aspx?WorkItemId=8153">posting on the Codeplex web site</a> from someone called <a href="http://www.codeplex.com/site/users/view/XIU">XIU</a> for which I&#8217;m grateful. I thought I would add some more detail in case anyone else has this problem and wants a more cut and pasty solution.<br />
<span></span><br />
Say you have a class called <em>Product</em>, each instance of which has an <em>ID</em> and a <em>Description</em>, and a class called <em>Order</em>, each instance of which has a <em>Quantity</em> and a <em>Product ID</em> (to be used like a foreign key to designate the order&#8217;s product).</p>
<p>These classes must implement the <a href="http://msdn.microsoft.com/en-us/library/ms229614.aspx">INotifyPropertyChanged interface</a>. Here are the first few lines of each:</p>
<p><code>public class Product : INotifyPropertyChanged<br />
{<br />
&nbsp;&nbsp;public int ID { ... }<br />
&nbsp;&nbsp;public string Description { ... }<br />
&nbsp;&nbsp;...<br />
}<br />
&nbsp;<br />
public class Order : INotifyPropertyChanged<br />
{<br />
&nbsp;&nbsp;public int ProductID { ... }<br />
&nbsp;&nbsp;public int Quantity { ... }<br />
&nbsp;&nbsp;...<br />
}</code></p>
<p>Create a simple ViewModel (i.e. binding context) and set the DataContext of the main window to an instance of this object:</p>
<p><code>namespace ComboBoxDemo<br />
{<br />
&nbsp;&nbsp;public class ViewModel<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;public ObservableCollection&lt;Order&gt; Orders { get; set; }<br />
&nbsp;&nbsp;&nbsp;&nbsp;public ObservableCollection&lt;Product&gt; Products { get; set; }<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;public ViewModel()<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Products = new ObservableCollection&lt;Product&gt;();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Products.Add(new Product(100, "Widget"));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Products.Add(new Product(101, "Sprocket"));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Products.Add(new Product(102, "Gadget"));<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Orders = new ObservableCollection&lt;Order&gt;();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Orders.Add(new Order(102, 15));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Orders.Add(new Order(102, 32));<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Orders.Add(new Order(100, 42));<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;}<br />
}</code></p>
<p>Create a helper class using XIU&#8217;s solution:</p>
<p><code>namespace ComboBoxDemo<br />
{<br />
&nbsp;&nbsp;public class DataGridComboBoxColumnWithBindingHack : DataGridComboBoxColumn<br />
&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FrameworkElement element = base.GenerateEditingElement(cell, dataItem);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CopyItemsSource(element);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return element;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FrameworkElement element = base.GenerateElement(cell, dataItem);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CopyItemsSource(element);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return element;<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;private void CopyItemsSource(FrameworkElement element)<br />
&nbsp;&nbsp;&nbsp;&nbsp;{<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BindingOperations.SetBinding(element, ComboBox.ItemsSourceProperty,<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BindingOperations.GetBinding(this, ComboBox.ItemsSourceProperty));<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;}<br />
}</code></p>
<p>This is a variant of the <em>DataGridComboBoxColumn</em> class which handles binding differently to allow the <em>ItemsSource</em> property to have access to the binding context. Now put it all together with the following XAML:</p>
<p><code>&lt;Window x:Class="ComboBoxDemo.Window1"<br />
&nbsp;&nbsp;xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"<br />
&nbsp;&nbsp;xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"<br />
&nbsp;&nbsp;xmlns:wpf="http://schemas.microsoft.com/wpf/2008/toolkit"<br />
&nbsp;&nbsp;xmlns:local="clr-namespace:ComboBoxDemo"<br />
&nbsp;&nbsp;Title="Window1" Height="300" Width="300"&gt;<br />
&nbsp;&nbsp;&lt;wpf:DataGrid ItemsSource="{Binding Orders}" AutoGenerateColumns="False"&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;wpf:DataGrid.Columns&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;wpf:DataGridTextColumn Header="Quantity" Binding="{Binding Quantity}" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;local:DataGridComboBoxColumnWithBindingHack<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Header="Product"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SelectedValueBinding="{Binding ProductID}"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SelectedValuePath="ID"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DisplayMemberPath="Description"<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ItemsSource="{Binding RelativeSource={RelativeSource Findancestor, AncestorType={x:Type Window}}, Path=DataContext.Products}" /&gt;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&lt;/wpf:DataGrid.Columns&gt;<br />
&nbsp;&nbsp;&lt;/wpf:DataGrid&gt;<br />
&lt;/Window&gt;</code></p>
<p>The <em>SelectedValueBinding</em> attribute indicates the Order property containing the foreign key designating the product (i.e. which value should be edited by the combo box). The <em>SelectedValuePath</em> attribute indicates which property within the product object contains the product ID, and the <em>DisplayMemberPath</em> attribute indicates which property should actually be displayed in the grid. Finally the <em>ItemsSource</em> attribute indicates how to get the list of products by navigating to the parent window object and looking up the list of products from the parent window&#8217;s binding context. </p>
<p>Here is the complete project source as a <a href="http://joemorrison.org/downloads/combobox-demo.zip">downloadable zip file</a>.</p>
<p>I hope this saves someone some time, and that it&#8217;s easier to do all of this in future versions of the WPF Toolkit. If anyone has a better solution to this problem, please let me know.</p>
]]></content:encoded>
			<wfw:commentRss>http://joemorrison.org/blog/2009/02/17/excedrin-headache-35401281-using-combo-boxes-with-the-wpf-datagrid/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Is reflection unhealthy?</title>
		<link>http://joemorrison.org/blog/2009/01/28/is-reflection-unhealthy/</link>
		<comments>http://joemorrison.org/blog/2009/01/28/is-reflection-unhealthy/#comments</comments>
		<pubDate>Thu, 29 Jan 2009 02:46:05 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[Architecture]]></category>

		<guid isPermaLink="false">http://joemorrison.org/blog/?p=41</guid>
		<description><![CDATA[Am I the only one who feels a bit dirty after writing code that uses reflection? Most people agree that strong typing is a good feature in programming languages, because it allows compilers to catch many kinds of programming errors before you run your program the first time.  But using reflection completely bypasses that security.

Reflection [...]]]></description>
			<content:encoded><![CDATA[<p>Am I the only one who feels a bit dirty after writing code that uses <a title=".NET Reflection Tutorial" href="http://www.codersource.net/published/view/291/reflection_in.aspx">reflection</a>? Most people agree that strong typing is a good feature in programming languages, because it allows compilers to catch many kinds of programming errors before you run your program the first time.  But using reflection completely bypasses that security.<br />
<span></span><br />
Reflection is useful for working around the type system when it gets in the way. For example say you want to write a universal object serializer. It needs to work on classes that haven&#8217;t even been defined yet, so there&#8217;s no way it can access the instance variables of those classes in a type-safe manner. Reflection provides a way to ask objects what instance variables they contain, the current values of those instance variables, and so on. There are countless applications &#8211; I don&#8217;t need to list them here. (There&#8217;s a good discussion on the <a href="http://discuss.fogcreek.com/dotnetquestions/default.asp?cmd=show&amp;ixPost=5318&amp;ixReplies=9">Fog Creek discussion board</a>.) But what&#8217;s interesting is how reflection subverts strong typing.</p>
<p>First, method invocations and any other operations performed using reflection are not typesafe:<br />
<code><br />
MethodInfo methodInfo = myObject.GetType().GetMethod("MyMethod");<br />
methodInfo.Invoke(myObject, new object[] {});<br />
</code><br />
There is no way at compile time of protecting against a runtime type error in that code sequence. Second, most programmers won&#8217;t be able to resist checking that <code>methodInfo</code> is non-null, to protect against a possible null pointer exception:<br />
<code><br />
MethodInfo methodInfo = myObject.GetType().GetMethod("MyMethod");<br />
if (methodInfo != null)<br />
{<br />
&nbsp;&nbsp;methodInfo.Invoke(myObject, new object[] {});<br />
}<br />
</code><br />
That&#8217;s not a bad instinct. After all, who knows what kind of <em>myObject</em> might be passed to this code? But now we&#8217;ve subverted the type system twice. It can&#8217;t check that we&#8217;re calling the method correctly, and it can&#8217;t even check that we&#8217;re providing the right kind of object. If we provide the wrong kind of object, this code will simply do nothing, probably causing a mysterious, silent failure.</p>
<p>Let&#8217;s see, what other kinds of trouble can we get into? Say we refactor the code and change the name <code>MyMethod</code> to something else. A smart IDE can do this automatically for us &#8211; but it will miss the reflection-based calls since they are only visible to the IDE as character strings. What will our code example do in this case? It will fail mysteriously and silently again.</p>
<p>Reflection also undermines program correctness by encouraging the creation of implicit contracts. Normally if you want to create a clear contract between two classes, you create an interface. For example, if you have a strange kind of collection class which calls <em>WriteAuditRecord()</em> on each object that is added, you might define the collection to accept only contents of type <em>Auditable</em>, which would be an interface with a <em>WriteAuditRecord()</em> method. Anyone using the collection would get a compile-time type error if they attempted to compile code which inserts objects that do not support that method. That would lead them to read the documentation in the <em>Auditable</em> interface and learn about the contract between the classes. But you could also create a clever solution using reflection to check whether any inserted items support a <em>WriteAuditRecord</em> method, and if so call that method automatically. That would allow programmers to add items to the collection without changing their implementation to implement the <em>Auditable</em> interface. More flexible, right? Except that if a programmer accidentally misspells the method as <em>WriteAudiRecord</em>, it will not get called; another silent error that would normally have been caught by the typechecker. Or even spookier, programmers might not know about this special audit behavior and be surprised when their <em>WriteAuditRecord()</em> method gets called for no apparent reason.</p>
<p>I&#8217;d also like to take a poke at another sacred cow: <em>attributes</em> (or <em>annotations</em> if you&#8217;re a Java person). My main beef with these is that to use them, you need to use reflection. See above.</p>
<p>I&#8217;m not 100% against the use of reflection and annotations. They can be very useful when creating frameworks that need to work on any kind of object (e.g. for serialization and persistence, or for configuration systems like Spring) but my point is they should be used sparingly and you should take a shower afterward.</p>
]]></content:encoded>
			<wfw:commentRss>http://joemorrison.org/blog/2009/01/28/is-reflection-unhealthy/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java template for WSDL-first web services using CXF (for Maven2 and Eclipse)</title>
		<link>http://joemorrison.org/blog/2008/10/23/cxf-wsdl-first/</link>
		<comments>http://joemorrison.org/blog/2008/10/23/cxf-wsdl-first/#comments</comments>
		<pubDate>Fri, 24 Oct 2008 01:38:36 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://joemorrison.org/blog/?p=21</guid>
		<description><![CDATA[This took me a while to put together so I thought I&#8217;d post it. I wanted the simplest possible template for building a web service in Java. I wanted it to be JAX-WS compliant, so I used the CXF open source implementation which is not only compliant, but also flexible and fast. I also wanted [...]]]></description>
			<content:encoded><![CDATA[<p>This took me a while to put together so I thought I&#8217;d post it. I wanted the simplest possible template for building a web service in Java. I wanted it to be <a title="JAX-WS" href="http://en.wikipedia.org/wiki/JAX-WS">JAX-WS</a> compliant, so I used the <a title="CXF" href="http://cxf.apache.org/">CXF</a> open source implementation which is not only compliant, but also flexible and fast. I also wanted the template to be <a title="WSDL first" href="http://webservices.xml.com/pub/a/ws/2003/07/22/wsdlfirst.html">WSDL first</a>, meaning that I should be able to edit the WSDL by hand to maintain total control over the service contract, then from that, generate Java code to make it easy to fill in the implementation.  (I consider that to be an important part of web service best practices. Doing it the other way &#8211; automatically generating WSDL from code &#8211; is simpler, but results in messy, sometimes incorrect WSDL that limits your ability to change web service implementations later.) Furthermore, I didn&#8217;t want to edit any generated code. I wanted to be able to fill in the implementation details by inheriting from a generated class or implementing a generated interface. Finally, I wanted to take advantage of <a title="Maven" href="http://maven.apache.org/">Maven</a> to build the project, but also be able to work on it in <a title="Eclipse" href="http://www.eclipse.org/">Eclipse</a>, taking advantage of its <a title="WTP" href="http://www.eclipse.org/webtools/">Web Tools Platform (WTP)</a> to allow synchronization with a live application server. Here&#8217;s the result in just under 300 lines of code. (Or you can cut to the chase and just <a title="Java template for WSDL-first web services" href="http://joemorrison.org/downloads/ws-example.zip">download the zip file</a> and follow the instructions at the end of this posting.)<br />
<span></span><br />
First, here is the <code>trade.xsd</code> schema file containing the input and output datatypes used by the web services:</p>
<pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;

&lt;xsd:schema targetNamespace="http://com.joemo.schema.trade" xmlns="http://com.joemo.schema.trade"
	xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;

	&lt;!-- web service input types --&gt;

	&lt;xsd:element name="trade"&gt;
		&lt;xsd:complexType&gt;
			&lt;xsd:sequence&gt;
				&lt;xsd:element name="security" type="xsd:string" minOccurs="1" maxOccurs="1" /&gt;
				&lt;xsd:element name="quantity" type="xsd:integer" minOccurs="1" maxOccurs="1" /&gt;
				&lt;!-- note the use of "unbounded"; comments can occur multiple times --&gt;
				&lt;xsd:element name="comments" type="comment" minOccurs="1" maxOccurs="unbounded" /&gt;
			&lt;/xsd:sequence&gt;
		&lt;/xsd:complexType&gt;
	&lt;/xsd:element&gt;

	&lt;xsd:complexType name="comment"&gt;
		&lt;xsd:sequence&gt;
			&lt;xsd:element name="message" type="xsd:string" minOccurs="1" maxOccurs="1" /&gt;
			&lt;xsd:element name="author" type="xsd:string" minOccurs="1" maxOccurs="1" /&gt;
		&lt;/xsd:sequence&gt;
	&lt;/xsd:complexType&gt;

	&lt;!-- web service output types --&gt;

	&lt;xsd:element name="status"&gt;
		&lt;xsd:complexType&gt;
			&lt;xsd:sequence&gt;
				&lt;xsd:element name="id" type="xsd:string" minOccurs="1" maxOccurs="1" /&gt;
				&lt;xsd:element name="message" type="xsd:string" minOccurs="1" maxOccurs="1" /&gt;
			&lt;/xsd:sequence&gt;
		&lt;/xsd:complexType&gt;
	&lt;/xsd:element&gt;

&lt;/xsd:schema&gt;</pre>
<p>Next, we need the <code>trade.wsdl</code> file which imports the schema file and completes the WSDL definition:</p>
<pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;wsdl:definitions targetNamespace="http://com.joemo.schema.tradeservice"
	xmlns="http://com.joemo.schema.tradeservice"
	xmlns:tr="http://com.joemo.schema.trade"
	xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
	xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;

	&lt;wsdl:types&gt;
		&lt;xsd:schema targetNamespace="http://com.joemo.schema.tradeservice"&gt;
			&lt;xsd:import namespace="http://com.joemo.schema.trade" schemaLocation="trade.xsd" /&gt;
		&lt;/xsd:schema&gt;
	&lt;/wsdl:types&gt;

	&lt;wsdl:message name="tradeInput"&gt;
		&lt;wsdl:part name="trade" element="tr:trade" /&gt;
	&lt;/wsdl:message&gt;

	&lt;wsdl:message name="tradeOutput"&gt;
		&lt;wsdl:part name="status" element="tr:status" /&gt;
	&lt;/wsdl:message&gt;

	&lt;wsdl:portType name="TradeService"&gt;
		&lt;wsdl:operation name="book"&gt;
			&lt;wsdl:input message="tradeInput" /&gt;
			&lt;wsdl:output message="tradeOutput" /&gt;
		&lt;/wsdl:operation&gt;
	&lt;/wsdl:portType&gt;

	&lt;wsdl:binding name="TradeServiceHTTPBinding" type="TradeService"&gt;
		&lt;wsdlsoap:binding style="document"
			transport="http://schemas.xmlsoap.org/soap/http" /&gt;
		&lt;wsdl:operation name="book"&gt;
			&lt;wsdlsoap:operation soapAction="" /&gt;
			&lt;wsdl:input&gt;
				&lt;wsdlsoap:body use="literal" /&gt;
			&lt;/wsdl:input&gt;
			&lt;wsdl:output&gt;
				&lt;wsdlsoap:body use="literal" /&gt;
			&lt;/wsdl:output&gt;
		&lt;/wsdl:operation&gt;
	&lt;/wsdl:binding&gt;

	&lt;wsdl:service name="TradeServicePorts"&gt;
		&lt;wsdl:port binding="TradeServiceHTTPBinding" name="TradeService"&gt;
			&lt;wsdlsoap:address
				location="http://localhost:9084/tradeService/TradeServicePorts" /&gt;
		&lt;/wsdl:port&gt;
	&lt;/wsdl:service&gt;

&lt;/wsdl:definitions&gt;</pre>
<p>Now we need a Maven project file that will take this WSDL and generate the Java code. Here&#8217;s what the <code>pom.xml</code> file looks like. It&#8217;s long and messy but it does a lot. It specifies all the dependencies and the compiler level, includes the rule to generate Java code from WSDL whenever necessary, and includes Jetty and WTP support for testing and running the web services in different environments.</p>
<pre>&lt;project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"&gt;
	&lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
	&lt;groupId&gt;com.joemo&lt;/groupId&gt;
	&lt;artifactId&gt;ws-example&lt;/artifactId&gt;
	&lt;packaging&gt;war&lt;/packaging&gt;
	&lt;version&gt;0.1&lt;/version&gt;
	&lt;name&gt;ws-example&lt;/name&gt;
	&lt;url&gt;http://maven.apache.org&lt;/url&gt;
	&lt;properties&gt;
		&lt;cxf.version&gt;2.1&lt;/cxf.version&gt;
		&lt;spring.version&gt;2.5&lt;/spring.version&gt;
	&lt;/properties&gt;
	&lt;dependencies&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;
			&lt;artifactId&gt;cxf-rt-core&lt;/artifactId&gt;
			&lt;version&gt;${cxf.version}&lt;/version&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;
			&lt;artifactId&gt;cxf-rt-frontend-jaxws&lt;/artifactId&gt;
			&lt;version&gt;${cxf.version}&lt;/version&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;
			&lt;artifactId&gt;cxf-rt-transports-http&lt;/artifactId&gt;
			&lt;version&gt;${cxf.version}&lt;/version&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;
			&lt;artifactId&gt;cxf-common-utilities&lt;/artifactId&gt;
			&lt;version&gt;${cxf.version}&lt;/version&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework&lt;/groupId&gt;
			&lt;artifactId&gt;spring-core&lt;/artifactId&gt;
			&lt;version&gt;${spring.version}&lt;/version&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;org.springframework&lt;/groupId&gt;
			&lt;artifactId&gt;spring-beans&lt;/artifactId&gt;
			&lt;version&gt;${spring.version}&lt;/version&gt;
		&lt;/dependency&gt;
		&lt;dependency&gt;
			&lt;groupId&gt;junit&lt;/groupId&gt;
			&lt;artifactId&gt;junit&lt;/artifactId&gt;
			&lt;version&gt;4.4&lt;/version&gt;
			&lt;scope&gt;test&lt;/scope&gt;
		&lt;/dependency&gt;
	&lt;/dependencies&gt;
	&lt;build&gt;
		&lt;plugins&gt;
			&lt;!-- Use Java 5 --&gt;
			&lt;plugin&gt;
				&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
				&lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
				&lt;configuration&gt;
					&lt;source&gt;1.5&lt;/source&gt;
					&lt;target&gt;1.5&lt;/target&gt;
				&lt;/configuration&gt;
			&lt;/plugin&gt;

			&lt;!-- CXF WSDL-to-Java code generation --&gt;
			&lt;plugin&gt;
				&lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;
				&lt;artifactId&gt;cxf-codegen-plugin&lt;/artifactId&gt;
				&lt;version&gt;2.0.6&lt;/version&gt;
				&lt;executions&gt;
					&lt;execution&gt;
						&lt;id&gt;generate-sources&lt;/id&gt;
						&lt;phase&gt;generate-sources&lt;/phase&gt;
						&lt;configuration&gt;
							&lt;sourceRoot&gt;${basedir}/target/generated/src/main/java&lt;/sourceRoot&gt;
							&lt;wsdlOptions&gt;
								&lt;wsdlOption&gt;
									&lt;wsdl&gt;src/main/resources/trade.wsdl&lt;/wsdl&gt;
								&lt;/wsdlOption&gt;
							&lt;/wsdlOptions&gt;
						&lt;/configuration&gt;
						&lt;goals&gt;
							&lt;goal&gt;wsdl2java&lt;/goal&gt;
						&lt;/goals&gt;
					&lt;/execution&gt;
				&lt;/executions&gt;
			&lt;/plugin&gt;
			&lt;!-- Jetty support for testing --&gt;
			&lt;plugin&gt;
				&lt;groupId&gt;org.mortbay.jetty&lt;/groupId&gt;
				&lt;artifactId&gt;maven-jetty-plugin&lt;/artifactId&gt;
			&lt;/plugin&gt;
		&lt;/plugins&gt;
		&lt;!-- Eclipse WTP support --&gt;
		&lt;pluginManagement&gt;
			&lt;plugins&gt;
				&lt;plugin&gt;
					&lt;artifactId&gt;maven-eclipse-plugin&lt;/artifactId&gt;
					&lt;configuration&gt;
						&lt;wtpversion&gt;2.0&lt;/wtpversion&gt;
						&lt;wtpapplicationxml&gt;true&lt;/wtpapplicationxml&gt;
						&lt;wtpmanifest&gt;true&lt;/wtpmanifest&gt;
						&lt;downloadSources&gt;true&lt;/downloadSources&gt;
						&lt;downloadJavadocs&gt;true&lt;/downloadJavadocs&gt;
						&lt;projectNameTemplate&gt;[artifactId]-[version]&lt;/projectNameTemplate&gt;
						&lt;manifest&gt;${basedir}/src/main/resources/META-INF/MANIFEST.MF&lt;/manifest&gt;
					&lt;/configuration&gt;
				&lt;/plugin&gt;
			&lt;/plugins&gt;
		&lt;/pluginManagement&gt;
	&lt;/build&gt;
&lt;/project&gt;</pre>
<p>Among other things, the rules in this <code>pom.xml</code> file will generate a Java interface called <code>TradeService</code> (based on the names in the WSDL file). The only code we will have to write is the implementation of this interface. Although this generation is done automatically by any Maven commands that need it (e.g. <code>mvn package</code> or <code>mvn install</code>) you might want to force it to be done sooner rather than later, so that you can refresh your Eclipse project with the generated code, enabling Eclipse to recognize the interface that you&#8217;re trying to implement. You can do this using the commands:</p>
<pre>mvn generate-sources
mvn eclipse:clean eclipse:eclipse</pre>
<p>This generates Java code from the WSDL, then regenerates the Eclipse project files, after which you should be able to refresh the project in Eclipse. If you see errors about libraries not being found, you may need to configure Eclipse to know about your Maven repository, i.e. select Eclipse / Window / Preferences / Java / Build Path / Classpath Variables, then enter the appropriate settings, e.g.</p>
<pre>Name: M2_REPO
Path: C:/Documents and Settings/MyAccount/.m2/repository</pre>
<p>Once the project is properly configured in Eclipse, you can fill in the implementation:</p>
<pre>package com.joemo.service;

import trade.schema.joemo.com.Comment;
import trade.schema.joemo.com.Status;
import trade.schema.joemo.com.Trade;
import tradeservice.schema.joemo.com.TradeService;

public class TradeServiceImpl implements TradeService {

	public Status book(Trade trade) {
		System.out.print ("Booking security ");
		System.out.print (trade.getSecurity());
		System.out.print (", quantity ");
		System.out.print (trade.getQuantity());
		System.out.println();
		if (trade.getComments() != null) {
			System.out.println ("Comments:");
			for (Comment c : trade.getComments()) {
				System.out.print (c.getAuthor());
				System.out.print (": ");
				System.out.print (c.getMessage());
				System.out.println();
			}
		}
		Status s = new Status();
		s.setId("12345");
		s.setMessage("ok");
		return s;
	}

}</pre>
<p>We are almost done. We still need a <code>web.xml</code> file which will direct SOAP requests to the CXF infrastructure:</p>
<pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;web-app id="WebApp_9" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"&gt;
	&lt;context-param&gt;
		&lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
		&lt;param-value&gt;classpath:appContext.xml&lt;/param-value&gt;
	&lt;/context-param&gt;
	&lt;listener&gt;
		&lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;
	&lt;/listener&gt;
	&lt;servlet&gt;
		&lt;servlet-name&gt;dispatcher&lt;/servlet-name&gt;
		&lt;servlet-class&gt;org.apache.cxf.transport.servlet.CXFServlet&lt;/servlet-class&gt;
		&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
	&lt;/servlet&gt;
	&lt;servlet-mapping&gt;
		&lt;servlet-name&gt;dispatcher&lt;/servlet-name&gt;
		&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
	&lt;/servlet-mapping&gt;
&lt;/web-app&gt;</pre>
<p>Finally, we need the <code>appContext.xml</code> file, which is the Spring configuration file loaded by CXF that defines the web service endpoint:</p>
<pre>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:jaxws="http://cxf.apache.org/jaxws"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd"
	default-dependency-check="none" default-lazy-init="false"&gt;

	&lt;!-- Load the needed resources that are present in the cxf* jars --&gt;
	&lt;import resource="classpath:META-INF/cxf/cxf.xml" /&gt;
	&lt;import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" /&gt;
	&lt;import resource="classpath:META-INF/cxf/cxf-servlet.xml" /&gt;

	&lt;!-- Hook up the web service --&gt;
	&lt;jaxws:endpoint id="ws-example" implementor="com.joemo.service.TradeServiceImpl"
		address="/ws-example" /&gt;

&lt;/beans&gt;</pre>
<p>That&#8217;s everything. There are six files, only one of which contains any Java code. You need to make sure you put each file in the right place:</p>
<pre>ws-example/pom.xml
ws-example/src/main/resources/trade.xsd
ws-example/src/main/resources/trade.wsdl
ws-example/src/main/resources/appContext.xml
ws-example/src/main/webapp/WEB-INF/web.xml
ws-example/src/main/java/com/joemo/service/TradeServiceImpl.java</pre>
<p>A zip file of this example is available for download <a title="Java template for WSDL-first web services" href="http://joemorrison.org/downloads/ws-example.zip">here</a>. To build and run it, you will need Maven to be installed on your development system. Unzip the file, and in the directory containing the <code>pom.xml</code> file, run the command:</p>
<pre>mvn jetty:run</pre>
<p>That will generate the Java code from the WSDL, build the example, and run the web service in the <a href="http://www.mortbay.org/jetty/">Jetty</a> container. You should be able to visit the URL <code>http://localhost:8080/ws-example/ws-example?wsdl</code> from a web browser and see the WSDL for the web service, test the web service using <a title="SoapUI" href="http://www.soapui.org/">SoapUI</a>, and so on.</p>
<p>Alternatively you can run the command:</p>
<pre>mvn eclipse:eclipse</pre>
<p>and follow the directions from my <a title="Developing Web applications with Maven and Eclipse" href="http://joemorrison.org/blog/2008/06/01/developing-web-applications-with-maven-and-eclipse-you-can-have-it-all/">earlier blog entry</a> to run the example using Eclipse WTP, which will allow you to edit the code while keeping it synchronized with a live application server. </p>
<p>Good luck! If you encounter any problems using this template, please email me or post a comment so that I can look into it and revise the instructions if necessary.</p>
]]></content:encoded>
			<wfw:commentRss>http://joemorrison.org/blog/2008/10/23/cxf-wsdl-first/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A maze of twisty little Java web service standards, all alike</title>
		<link>http://joemorrison.org/blog/2008/10/22/a-maze-of-twisty-little-java-web-service-standards-all-alike/</link>
		<comments>http://joemorrison.org/blog/2008/10/22/a-maze-of-twisty-little-java-web-service-standards-all-alike/#comments</comments>
		<pubDate>Wed, 22 Oct 2008 21:40:57 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[Featured Posts]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://joemorrison.org/blog/?p=18</guid>
		<description><![CDATA[It&#8217;s almost impossible to keep up with all the fractal-like Java standards related to web services. As fast as each can be learned, Sun invents another, and a dozen open source implementations appear. For my own sanity I tried to create a rough map of some of them. I&#8217;ll try to avoid making recommendations; my [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s almost impossible to keep up with all the fractal-like Java standards related to web services. As fast as each can be learned, Sun invents another, and a dozen open source implementations appear. For my own sanity I tried to create a rough map of some of them. I&#8217;ll try to avoid making recommendations; my main objective is to sketch out how they fit together.<br />
<span></span><br />
First, it&#8217;s important to understand that there are three main players with implementations of of these standards: <a href="http://www.sun.com/">Sun</a>, the <a href="http://www.apache.org/">Apache</a> foundation, and <a href="http://codehaus.org/">Codehaus</a>. There are many other open source implementations as well, but these are the three 800 pound gorillas, for a total of 2400 pounds, or almost exactly one metric tonne (for our international audience).</p>
<p>Second, keep in mind that there are three important APIs which are inter-related: JAX-WS, JAXB, and StAX. Once you understand how these fit together, everything else falls into place more easily.</p>
<p><strong>JAX-WS</strong></p>
<p>Let&#8217;s begin our journey with the latest Sun standard for creating and consuming web services: <strong>JAX-WS</strong>, which stands for Java API for XML Web Services. This standard was introduced in 2004. You can ignore JAX-RPC, since JAX-WS replaces it.</p>
<p>There are three noteworthy implementations of JAX-WS. The first is from Sun, and is called <strong>JAX-WS RI</strong> for the JAX-WS Reference Implementation (they always had a way with names). The second and third are both from the Apache Group and are called <strong>Axis2</strong> and <strong>CXF</strong>. You can ignore Axis1, XFire, and Celtix, since they are all obsolete. There is also a web service framework called Spring-WS, but it&#8217;s not JAX-WS compliant.</p>
<p>So if you are creating web services in Java, the first order of business is to to choose an implementation to work with, and unless you have a reason not to, you should probably stick to one that complies with JAX-WS, which means either JAX-WS RI, Axis2, or CXF.</p>
<p>Related to these is an open source project from Sun called Web Services Interoperability Technologies (<strong>WSIT</strong>), previously known as Project Tango. This is an implementation of several web service standards (WS-SecurityPolicy, WS-ReliableMessaging, and so on). <strong>Metro</strong> is an open source web service stack which is a combination of JAX-WS RI and WSIT (so it&#8217;s actually a reasonable fourth option).</p>
<p>JAX-WS is oriented around SOAP web services, but many programmers are now using the <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer">REST</a> approach. Sun is coming out with the <strong>JAX-RS</strong> API to support that, but it&#8217;s not quite ready yet.</p>
<p><strong>JAXB</strong></p>
<p>Web service development requires mapping between XML and Java objects. <strong>JAXB</strong> is the Sun API for that (also referred to as JAXB2 since the latest version is the important one). There are two noteworthy implementations: <strong>JAXB-RI</strong> (Sun&#8217;s reference implementation) and <strong>JaxMe</strong> (the unfortunately named contribution from Apache). JaxMe is in the incubation stage and is not formally part of Apache yet. There are many other interesting and popular XML/Java mapping frameworks, but most of them are not compliant with JAXB. Examples include Castor (from Codehaus), JiBX (a spectacularly fast open source implementation), and XMLBeans (a flexible implementation from Apache).</p>
<p>A recurring source of confusion is that in the past, Sun was less clear about the distinction between APIs and reference implementations, so people would take JAXB to mean both, and you would often see online articles like &#8220;Which is better: JAXB or JiBX?&#8221; But today developers should always try to use the JAXB API, which will enable a choice of compliant implementations such as JAXB-RI or JaxMe with minimal or no code changes.</p>
<p><strong>StAX</strong></p>
<p>For Java code that needs to read and write large XML documents quickly without necessarily mapping them to objects, there is the Streaming API for XML (<strong>StAX</strong>). There are several implementations of this API too. There is the Sun Java Streaming XML Parser called <strong>SJSXP</strong> (another snappy name from Sun), the <strong>Woodstox</strong> open source implementation which is excellent, and the <strong>StAX reference implementation</strong> from Codehaus which is referred to simply as StAX (unfortunately perpetuating the confusion between APIs and implementations). <strong>Xerces</strong> is a streaming XML processing library which used to be part of the Apache project, and work was underway to make it StAX compliant, but that was dropped.</p>
<p><strong>Putting it all together</strong></p>
<p>Web services need to process XML, sometimes mapping it to and from Java objects (e.g. for creating proxy objects and an RPC-like experience), and sometimes processing it directly (e.g. for streaming results when high performance is needed). Therefore Sun designed the JAX-WS API to rely on the JAXB API, which makes perfect sense; any JAX-WS compliant web service implementation should therefore be able to use any JAXB compliant mapping library. Other relationships between these APIs are up to individual implementations. For example, JAX-WS RI supports the StAX API, so you can use any StAX implementation for streaming. CXF also supports the StAX API, as well as a host of Java/XML mapping options including JAXB (allowing the use of any JAXB compliant implementation), XMLBeans, Castor, and JiBX. Yes, they are heroes.</p>
<p>So if you get confused, just ask yourself clarifying questions like: Does this Java web service library support JAX-WS? Which JAXB compliant Java/XML mapping implentation shall I use? Which is better for processing streaming XML? Woodstox or the StAX reference implementation?</p>
<p>If you&#8217;re still confused, then just accept the recommendations I promised not to make: Use CXF for your web services (which complies with JAX-WS), JAXB-RI for your Java/XML mapping (which complies with JAXB), and Woodstox for streaming (which complies with StAX).</p>
]]></content:encoded>
			<wfw:commentRss>http://joemorrison.org/blog/2008/10/22/a-maze-of-twisty-little-java-web-service-standards-all-alike/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Is Eclipse collapsing under its own weight?</title>
		<link>http://joemorrison.org/blog/2008/10/20/is-eclipse-collapsing-under-its-own-weight/</link>
		<comments>http://joemorrison.org/blog/2008/10/20/is-eclipse-collapsing-under-its-own-weight/#comments</comments>
		<pubDate>Mon, 20 Oct 2008 21:39:51 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://joemorrison.org/blog/?p=17</guid>
		<description><![CDATA[Maybe Eclipse&#8217;s black-hole-like splash screen is more appropriate than its designers realize. Eclipse&#8217;s open architecture has enabled the creation of countless useful plugins, and that&#8217;s helped maintain its position as the leading Java IDE. But as plugins compound upon plugins, bugs and compatibility issues have been surfacing increasingly frequently, and I&#8217;m starting to get the [...]]]></description>
			<content:encoded><![CDATA[<p>Maybe <a href="http://www.eclipse.org/">Eclipse&#8217;s</a> black-hole-like splash screen is more appropriate than its designers realize. Eclipse&#8217;s open architecture has enabled the creation of countless useful plugins, and that&#8217;s helped maintain its position as the leading Java IDE. But as plugins compound upon plugins, bugs and compatibility issues have been surfacing increasingly frequently, and I&#8217;m starting to get the sense the Eclipse developers have lost control.<br />
<span></span><br />
I spent considerable time downloading <a href="http://www.eclipse.org/ganymede/">Ganymede</a> today for only one reason: I wanted to try the new <strong>JAX-WS WSDL First</strong> project wizard. It would be hard to come up with a geekier, more obscure name than that, but in essence the feature promised to allow me to create a web service with the click of a button, following various best practices. With great anticipation (okay, I&#8217;m exaggerating; with vague hopefulness) I downloaded Ganymede, and decided to try the wizard with the <a href="http://cxf.apache.org/">CXF</a> web service library. Here&#8217;s the error I got:</p>
<p><code>Error instantiating builder 'org.eclipse.stp.sc.annvalidator'.<br />
Plug-in org.eclipse.stp.sc.annvalidator was unable to load class org.eclipse.stp.sc.annvalidator.builder.AnnValidator.</code></p>
<p>What? Did they even test this? And who is Ann Validator anyway? A quick Google search turned up incomprehensible articles with titles like <em>&#8220;AnnValidator missing from Ganymede Update&#8221;</em>. The gist of the articles was basically &#8220;oh yeah, we should clean up our releases better&#8221;.</p>
<p>I&#8217;m probably oversimplifying the Eclipse point of view, but I don&#8217;t really care. The point is, now I have to research an obscure problem in order to perform something that should be the most basic of activities &#8211; creating a simple web service, using a fresh download of a supposedly mature IDE.</p>
<p>There is only one thing keeping me from switching to <a href="http://www.netbeans.org/">Netbeans</a> immediately and recommending that everyone dump Eclipse: I&#8217;m still waiting for a good <a href="http://www.perforce.com/">Perforce</a> plugin. Okay, two things: I&#8217;m also addicted to Max Uermann&#8217;s <a href="http://muermann.org/gotofile/">Goto File</a> plugin.</p>
]]></content:encoded>
			<wfw:commentRss>http://joemorrison.org/blog/2008/10/20/is-eclipse-collapsing-under-its-own-weight/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Tomato: An antioxidant for your router</title>
		<link>http://joemorrison.org/blog/2008/10/06/tomato-an-antioxidant-for-your-router/</link>
		<comments>http://joemorrison.org/blog/2008/10/06/tomato-an-antioxidant-for-your-router/#comments</comments>
		<pubDate>Tue, 07 Oct 2008 00:21:52 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[Open Source]]></category>

		<guid isPermaLink="false">http://joemorrison.org/blog/?p=16</guid>
		<description><![CDATA[Every few months my Linksys WRT54G V4 home wireless router stops working and nothing short of a full reset gets it going again. This weekend it happened again. I got fed up and started Googling. I found out I&#8217;m not the only one to suffer from this problem. But then I found out that in [...]]]></description>
			<content:encoded><![CDATA[<p>Every few months my <a href="http://en.wikipedia.org/wiki/Linksys_WRT54G_series">Linksys WRT54G V4</a> home wireless router stops working and nothing short of a full reset gets it going again. This weekend it happened again. I got fed up and started Googling. I found out I&#8217;m not the only one to <a href="http://forums.linksys.com/linksys/board/message?board.id=Wireless_Routers&amp;thread.id=45831">suffer from this problem</a>. But then I found out that in 2003 Linksys, under pressure to comply with the <a href="http://www.gnu.org/copyleft/gpl.html">GPL</a>, <a href="http://www.wi-fiplanet.com/tutorials/article.php/3562391">released the router firmware</a> and immediately afterward people started coming out of the woodwork improving it. (Doesn&#8217;t anyone have better things to do with their time?) Seriously, this has to be one of the best open source success stories ever. Some open-source variations of the firmware provide more features, giving this $60 router functionality similar to a $600 router. Others allow you to boost the RF signal. Still others provide a simplified and improved user interface. Most allow SSH or Telnet access to the router&#8217;s Linux kernel. All of them reportedly improve its reliability. I researched several of these and tried DD-WRT for a few hours. It&#8217;s very powerful and I was almost sold, but then I discovered <a href="http://www.polarcloud.com/tomato">Tomato</a>. It&#8217;s perfect and I&#8217;m never going back.<br />
<span></span><br />
From the Tomato home page: &#8220;Tomato is a small, lean and simple replacement firmware for Linksys&#8217; WRT54G/GL/GS, Buffalo WHR-G54S/WHR-HP-G54 and other Broadcom-based routers. It features a new easy to use GUI, a new bandwidth usage monitor, more advanced QOS and access restrictions, enables new wireless features such as WDS and wireless client modes, raises the limits on maximum connections for P2P, allows you to run your custom scripts or telnet/ssh in and do all sorts of things like re-program the SES/AOSS button, adds wireless site survey to see your wifi neighbors, and more.&#8221;</p>
<p>It installed like a dream on top of DD-WRT, and the user interface is simple and clean. Most of the complexity is devoted to QoS functions, which I actually care about (unlike many of the obscure routing options provided by the original Linksys firmware) since I use my home computers for streaming music, Skype, and other network-intensive applications.  Furthermore it provides nice usage monitoring and visualization tools. The user interface is a nice red color, the exact same shade as Campbell&#8217;s tomato soup.</p>
<p>After installation, my home network seems noticeably faster, but that may just be cognitive dissonance. (After all, if I spent an entire evening <b>not</b> making my network faster, that would make a pretty poor blog entry.)  The main question now is whether my router&#8217;s reliability will improve, but from reviews online and my initial experience, I&#8217;m optimistic. We&#8217;ll see over the next few months.</p>
<p>If you decide to try installing Tomato, make sure your router hardware version is supported. For example, Tomato isn&#8217;t supported on the Linksys WRT54G V5 or later since Linksys removed half the RAM in all versions after V4.</p>
]]></content:encoded>
			<wfw:commentRss>http://joemorrison.org/blog/2008/10/06/tomato-an-antioxidant-for-your-router/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Orange lines</title>
		<link>http://joemorrison.org/blog/2008/08/02/orange-lines/</link>
		<comments>http://joemorrison.org/blog/2008/08/02/orange-lines/#comments</comments>
		<pubDate>Sat, 02 Aug 2008 19:32:51 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://joemorrison.org/blog/?p=15</guid>
		<description><![CDATA[A few evenings ago I looked out of my kitchen window and saw an airplane&#8217;s vapor trail in the sunset - a beautiful, bright, clean, orange line cutting through the clouds. At that moment I had brief but unmistakable feeling of optimism about the human race.

For one thing, jet airplanes are a marvel of engineering. [...]]]></description>
			<content:encoded><![CDATA[<p>A few evenings ago I looked out of my kitchen window and saw an airplane&#8217;s vapor trail in the sunset &#8211; a beautiful, bright, clean, orange line cutting through the clouds. At that moment I had brief but unmistakable feeling of optimism about the human race.<br />
<span></span><br />
For one thing, jet airplanes are a marvel of engineering. Hundreds of thousands of people collaborated to create them, maybe even millions if you include the scientists who worked out the principles of flight and jet propulsion, the inventors and engineers who applied those principles, the entrepreneurs who created an airline industry, and the pilots, air traffic controllers, technicians, and support staff who keep it all running. Think of everything that goes into an aircraft and try to count the number of people involved. Don&#8217;t forget the avionics, the bathrooms, and the in-flight entertainment system. (Maybe leave out the food, and definitely leave out the homeland security people.)</p>
<p>Then consider the manner by which all those people collaborated. Nobody was coerced, and it wasn&#8217;t necessary to gather everyone into a giant room to plan it all. Rather, it all came about gradually over the course of decades, fueled by a combination of personal initiative, market forces, and government action. It&#8217;s one of the greatest triumphs of managed capitalism. (We are all Keynesians now.) In Europe aircraft are made by English, French, and German people working together. Could anyone imagine that fifty years ago? Economic integration is the primary force protecting us from another world war.</p>
<p>But what&#8217;s most amazing is that flying is routine. At the tip of that orange line in the sky was a silver tube filled with people having dinner, reading newspapers, and generally acting as though it&#8217;s not a big deal to shoot through the sky at 600 miles per hour. But it is.</p>
]]></content:encoded>
			<wfw:commentRss>http://joemorrison.org/blog/2008/08/02/orange-lines/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slimmer, trimmer messaging from Google</title>
		<link>http://joemorrison.org/blog/2008/07/15/slimmer-trimmer-messaging-from-google/</link>
		<comments>http://joemorrison.org/blog/2008/07/15/slimmer-trimmer-messaging-from-google/#comments</comments>
		<pubDate>Tue, 15 Jul 2008 17:10:11 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[Architecture]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://joemorrison.org/blog/?p=14</guid>
		<description><![CDATA[Google&#8217;s Protocol Buffers offer lightweight, language-independent object serialization. I love the design, especially as I&#8217;m increasingly seeing enterprise networks clogged with hordes of oversized XML messages. Protocol buffer bindings are available for C++, Java, and Python, but not C# yet. Once there is support for .NET, I think this could be a really interesting technology [...]]]></description>
			<content:encoded><![CDATA[<p>Google&#8217;s <a title="Google's Protocol Buffers" href="http://google-opensource.blogspot.com/2008/07/protocol-buffers-googles-data.html">Protocol Buffers</a> offer lightweight, language-independent object serialization. I love the design, especially as I&#8217;m increasingly seeing enterprise networks clogged with hordes of oversized XML messages. Protocol buffer bindings are available for C++, Java, and Python, but not C# yet. Once there is support for .NET, I think this could be a really interesting technology for financial applications.</p>
]]></content:encoded>
			<wfw:commentRss>http://joemorrison.org/blog/2008/07/15/slimmer-trimmer-messaging-from-google/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Developing Web applications with Maven and Eclipse: You *can* have it all</title>
		<link>http://joemorrison.org/blog/2008/06/01/developing-web-applications-with-maven-and-eclipse-you-can-have-it-all/</link>
		<comments>http://joemorrison.org/blog/2008/06/01/developing-web-applications-with-maven-and-eclipse-you-can-have-it-all/#comments</comments>
		<pubDate>Sun, 01 Jun 2008 16:14:08 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://joemorrison.org/blog/2008/06/01/developing-web-applications-with-maven-and-eclipse-you-can-have-it-all/</guid>
		<description><![CDATA[When developing applications using Eclipse or a similar IDE, you quickly get used to being able to test your software immediately after making a change.  Plugins like MyEclipseIDE enable that kind of instant edit/compile/test cycle for web applications as well.
But if you&#8217;re building web applications with Maven, it&#8217;s not so easy. Maven is a [...]]]></description>
			<content:encoded><![CDATA[<p>When developing applications using Eclipse or a similar IDE, you quickly get used to being able to test your software immediately after making a change.  Plugins like <a href="http://www.myeclipseide.com/">MyEclipseIDE</a> enable that kind of instant edit/compile/test cycle for web applications as well.</p>
<p>But if you&#8217;re building web applications with Maven, it&#8217;s not so easy. Maven is a fantastic tool for building applications and managing dependencies, but it lends itself to a more batch-oriented mode of operation in which you build and deploy war files from the command line. I found myself wishing I could have the best of both worlds; building my web applications using Maven, but with a seamless edit/compile/test cycle when using Eclipse. Then I discovered the WTP (Web Tools Platform) project. Hallelujah!<br />
 <a href="http://joemorrison.org/blog/2008/06/01/developing-web-applications-with-maven-and-eclipse-you-can-have-it-all/#more-12" class="more-link">(more&#8230;)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://joemorrison.org/blog/2008/06/01/developing-web-applications-with-maven-and-eclipse-you-can-have-it-all/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A virtuous pairing</title>
		<link>http://joemorrison.org/blog/2008/04/16/a-virtuous-pairing/</link>
		<comments>http://joemorrison.org/blog/2008/04/16/a-virtuous-pairing/#comments</comments>
		<pubDate>Wed, 16 Apr 2008 13:48:53 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[HPC]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Virtualization]]></category>

		<guid isPermaLink="false">http://joemorrison.org/blog/2008/04/16/a-virtuous-pairing/</guid>
		<description><![CDATA[I ran across the following comments on an El Reg article about virtualization: Comments about &#8220;Virtualization: Nothing New&#8221;.
He&#8217;s right, isn&#8217;t he? Having the same company offer both virtualization and grid solutions is a truly virtuous pairing. First you tell people they need a grid solution to make a huge pool of computers look like a [...]]]></description>
			<content:encoded><![CDATA[<p>I ran across the following comments on an El Reg article about virtualization: <a href="http://www.theregister.co.uk/2008/04/16/virtualization_perspectives/comments/" title="Comments about ">Comments about &#8220;Virtualization: Nothing New&#8221;</a>.</p>
<p>He&#8217;s right, isn&#8217;t he? Having the same company offer both virtualization and grid solutions is a truly virtuous pairing. First you tell people they need a grid solution to make a huge pool of computers look like a single one, then after it&#8217;s all set up you sell them virtualization software. It&#8217;s beautiful. It&#8217;s like if, for example, Nestle and Jenny Craig got together to simultaneously offer chocolate products and dieting solutions. Oh wait, they did: <a href="http://www.msnbc.msn.com/id/13414203/" title="Nestle to buy Jenny Craig">Nestle to buy Jenny Craig</a>.<br />
 <a href="http://joemorrison.org/blog/2008/04/16/a-virtuous-pairing/#more-11" class="more-link">(more&#8230;)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://joemorrison.org/blog/2008/04/16/a-virtuous-pairing/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My new favorite ISP</title>
		<link>http://joemorrison.org/blog/2008/03/13/my-new-favorite-isp/</link>
		<comments>http://joemorrison.org/blog/2008/03/13/my-new-favorite-isp/#comments</comments>
		<pubDate>Fri, 14 Mar 2008 03:37:07 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://joemorrison.org/blog/2008/03/13/my-new-favorite-isp/</guid>
		<description><![CDATA[My new favorite web hosting provider is A Small Orange. Their pricing is competitive, and their tech support is unbelievably quick and clueful.
]]></description>
			<content:encoded><![CDATA[<p>My new favorite web hosting provider is <a href="http://www.asmallorange.com/" title="A Small Orange">A Small Orange</a>. Their pricing is competitive, and their tech support is unbelievably quick and clueful.</p>
]]></content:encoded>
			<wfw:commentRss>http://joemorrison.org/blog/2008/03/13/my-new-favorite-isp/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The US airline industry and the prisoner’s dilemma</title>
		<link>http://joemorrison.org/blog/2007/12/30/the-us-airline-industry-and-the-prisoners-dilemma/</link>
		<comments>http://joemorrison.org/blog/2007/12/30/the-us-airline-industry-and-the-prisoners-dilemma/#comments</comments>
		<pubDate>Sun, 30 Dec 2007 12:48:42 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://joemorrison.org/blog/2007/12/30/the-us-airline-industry-and-the-prisoners-dilemma/</guid>
		<description><![CDATA[The US airline industry is a national embarrassment. I&#8217;m writing from Tampa, Florida where I just spent the night because of a flight delay which caused me to miss the last connecting flight of the day. I&#8217;ve flown about a dozen times in the last two years, and I can&#8217;t remember a single domestic flight [...]]]></description>
			<content:encoded><![CDATA[<p>The US airline industry is a national embarrassment. I&#8217;m writing from Tampa, Florida where I just spent the night because of a flight delay which caused me to miss the last connecting flight of the day. I&#8217;ve flown about a dozen times in the last two years, and I can&#8217;t remember a single domestic flight that got me to my destination on time. The delays are always due to &#8220;weather&#8221; which means the airline has no obligation to compensate the passengers. How&#8217;s this for an idea? Any time a passenger is delayed more than four hours arriving at their ultimate destination when the entire trip is booked through a single airline, the passenger is entitled to a refund of 40% of the price of the flight, with an additional 10% penalty for every hour beyond that. If the flight is more than 10 hours late, the flight is free.<br />
 <a href="http://joemorrison.org/blog/2007/12/30/the-us-airline-industry-and-the-prisoners-dilemma/#more-8" class="more-link">(more&#8230;)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://joemorrison.org/blog/2007/12/30/the-us-airline-industry-and-the-prisoners-dilemma/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The network is the network, the computer is the computer &#8211; sorry about the confusion</title>
		<link>http://joemorrison.org/blog/2007/09/30/the-network-is-the-network-the-computer-is-the-computer-sorry-about-the-confusion/</link>
		<comments>http://joemorrison.org/blog/2007/09/30/the-network-is-the-network-the-computer-is-the-computer-sorry-about-the-confusion/#comments</comments>
		<pubDate>Mon, 01 Oct 2007 00:54:32 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://joemorrison.org/blog/2007/09/30/the-network-is-the-network-the-computer-is-the-computer-sorry-about-the-confusion/</guid>
		<description><![CDATA[This post continues my ongoing theme: That networks are great as long as software doesn&#8217;t pretend they are perfect. (I can&#8217;t take credit for the title - it&#8217;s been floating around for a long time.)
Increasingly, software is being designed based on the idea of treating network resources as local. The practice of generating proxy objects [...]]]></description>
			<content:encoded><![CDATA[<p>This post continues my ongoing theme: That networks are great as long as software doesn&#8217;t pretend they are perfect. (I can&#8217;t take credit for the title &#8211; it&#8217;s been floating around for a long time.)</p>
<p>Increasingly, software is being designed based on the idea of treating network resources as local. The practice of generating proxy objects to invoke remote services increases the tendency to think this way, as does the success of HTTP based remote invocation patterns like REST, SOAP, etc. (It&#8217;s tempting to think of HTTP services like function calls: Send request with parameters, wait until results come back, proceed.)</p>
<p>But this is a bad idea. The concept of a network as a means of instantaneous communication between software components anywhere on the globe is an incorrect abstraction. Software should be designed based on the notion that networks are unreliable and introduce unpredictable amounts of latency into communication.</p>
<p> <a href="http://joemorrison.org/blog/2007/09/30/the-network-is-the-network-the-computer-is-the-computer-sorry-about-the-confusion/#more-7" class="more-link">(more&#8230;)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://joemorrison.org/blog/2007/09/30/the-network-is-the-network-the-computer-is-the-computer-sorry-about-the-confusion/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ten meta-requirements for enterprise software development</title>
		<link>http://joemorrison.org/blog/2007/09/03/ten-meta-requirements-for-enterprise-software-development/</link>
		<comments>http://joemorrison.org/blog/2007/09/03/ten-meta-requirements-for-enterprise-software-development/#comments</comments>
		<pubDate>Mon, 03 Sep 2007 23:10:57 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://joemorrison.org/blog/2007/09/03/ten-meta-requirements-for-enterprise-software-development/</guid>
		<description><![CDATA[When you start a project to build a custom application for an enterprise customer, there are always universal requirements the customer doesn&#8217;t tell you about. These are things you have to do in order to implement the stated requirements, so I call them meta-requirements.
It&#8217;s helpful to keep a checklist of these and review them at [...]]]></description>
			<content:encoded><![CDATA[<p>When you start a project to build a custom application for an enterprise customer, there are always universal requirements the customer doesn&#8217;t tell you about. These are things you have to do in order to implement the stated requirements, so I call them <em>meta-requirements</em>.</p>
<p>It&#8217;s helpful to keep a checklist of these and review them at the beginning of any new project, especially if the project is in an unfamiliar IT environment. Here&#8217;s my checklist of ten.</p>
<p> <a href="http://joemorrison.org/blog/2007/09/03/ten-meta-requirements-for-enterprise-software-development/#more-6" class="more-link">(more&#8230;)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://joemorrison.org/blog/2007/09/03/ten-meta-requirements-for-enterprise-software-development/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Protecting your SOA application (and your job) from remote failures</title>
		<link>http://joemorrison.org/blog/2007/08/26/protecting-your-soa-application-and-your-job-from-remote-failures/</link>
		<comments>http://joemorrison.org/blog/2007/08/26/protecting-your-soa-application-and-your-job-from-remote-failures/#comments</comments>
		<pubDate>Sun, 26 Aug 2007 20:21:08 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[SOA]]></category>

		<guid isPermaLink="false">http://joemorrison.org/blog/2007/08/26/protecting-your-soa-application-and-your-job-from-remote-failures/</guid>
		<description><![CDATA[SOA - for Service Oriented Architecture - is the buzzword du jour. Organizations in all industries want to realize its promises, which include sharing information more openly and coherently across the enterprise and increasing organizational agility by making it easier to assemble new applications from existing components. Although there are fierce debates about the details [...]]]></description>
			<content:encoded><![CDATA[<p>SOA &#8211; for <strong>Service Oriented Architecture </strong>- is the buzzword du jour. Organizations in all industries want to realize its promises, which include sharing information more openly and coherently across the enterprise and increasing organizational agility by making it easier to assemble new applications from existing components. Although there are fierce debates about the details (<em>SOAP</em><strong> </strong>vs <em>REST</em>,<strong> </strong><em>contract first </em>vs <em>schema first </em>vs <em>code first</em>, etc.) there is little disagreement about the general principles. Software should be constructed in the form of loosely coupled, coarse-grained, stateless services which can be invoked remotely over a network, and which form the basis of enterprise code reuse. This is a huge topic about which volumes have been written, but for now I&#8217;m going to focus on one issue: The importance of designing your SOA services to be resilient against network failures.<br />
 <a href="http://joemorrison.org/blog/2007/08/26/protecting-your-soa-application-and-your-job-from-remote-failures/#more-4" class="more-link">(more&#8230;)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://joemorrison.org/blog/2007/08/26/protecting-your-soa-application-and-your-job-from-remote-failures/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Welcome to Joe on Computing</title>
		<link>http://joemorrison.org/blog/2007/08/26/welcome-to-joe-on-computing/</link>
		<comments>http://joemorrison.org/blog/2007/08/26/welcome-to-joe-on-computing/#comments</comments>
		<pubDate>Sun, 26 Aug 2007 11:48:13 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://joemorrison.org/blog/2007/08/26/welcome-to-joe-on-computing/</guid>
		<description><![CDATA[Welcome to Joe on Computing, the new home for my blog. Although it will have many omissions and contain much that is apocryphal, or at least wildly inaccurate - it has the advantage of matching the garish color scheme on my home page that I have come to love, which I call &#8220;retro Frogger&#8221;. Enjoy. [...]]]></description>
			<content:encoded><![CDATA[<p>Welcome to <strong>Joe on Computing</strong>, the new home for my blog. Although it will have many omissions and contain much that is apocryphal, or at least wildly inaccurate &#8211; it has the advantage of matching the garish color scheme on my home page that I have come to love, which I call &#8220;retro Frogger&#8221;. Enjoy. Comment. I love a good argument.</p>
]]></content:encoded>
			<wfw:commentRss>http://joemorrison.org/blog/2007/08/26/welcome-to-joe-on-computing/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Declarative programming &#8211; have we gone too far?</title>
		<link>http://blog.lab49.com/archives/1214</link>
		<comments>http://blog.lab49.com/archives/1214#comments</comments>
		<pubDate>Sat, 07 Jul 2007 22:59:58 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[General Development]]></category>
		<category><![CDATA[Open Source]]></category>

		<guid isPermaLink="false">http://blog.lab49.com/?p=1214</guid>
		<description><![CDATA[For some time I&#8217;ve been planning to write a blog entry highlighting the problems that can occur when declarative programming is taken to an extreme (I&#8217;m thinking about Spring here). What prompted me to actually write it was this post which conveyed my feeling, if not my exact technical point: http://nutrun.com/weblog/no-more-jars/ So here&#8217;s my technical [...]]]></description>
			<content:encoded><![CDATA[<p>For some time I&#8217;ve been planning to write a blog entry highlighting the problems that can occur when declarative programming is taken to an extreme (I&#8217;m thinking about Spring here). What prompted me to actually write it was this post which conveyed my feeling, if not my exact technical point:</p>
<p><a href="http://nutrun.com/weblog/no-more-jars/">http://nutrun.com/weblog/no-more-jars/</a><br />
<span id="more-1214"></span><br />
So here&#8217;s my technical point. First let me clarify that by declarative programming, I mean the general practice of writing &#8220;I want this&#8221;, rather than &#8220;do this, then do that, then do the other thing&#8221;. Wikipedia defines it nicely:</p>
<p><a href="http://en.wikipedia.org/wiki/Declarative_programming">http://en.wikipedia.org/wiki/Declarative_programming</a></p>
<p>Declarative programming is generally a good thing because it enables cleaner, more powerful abstractions. You are saying what you want, and leaving it up to a framework to decide how to carry out your wishes. That&#8217;s what&#8217;s great about Spring; your configuration file explains how to make each kind of thing, and the Spring framework decides when to instantiate classes and how to wire them up.</p>
<p>The problem is that taken to an extreme, you end up with a big pile of configuration files and no code. That&#8217;s great if everything works perfectly, but if your program does not work as expected, you are in trouble. Declarative programs are much harder to analyze and understand than imperative ones. Debuggers are not especially useful &#8211; you end up stepping through the implementations of the frameworks (when the whole point of the exercise was to build on abstractions whose implementations you don&#8217;t need to understand). And the frameworks are typically much more general than necessary for your application (since they were designed to serve everybody, not just you) so you have a lot more code to wade through than you would have had. </p>
<p>Declarative frameworks can also defeat clever features in IDEs. When browsing a Spring-based application for example, hitting F3 to find the definition of something is much less helpful than it used to be. Typically you end up jumping to an interface, and the only way to figure out the exact class that was instantiated is to parse and understand the Spring configuration (if you even know for sure which one was used in the running program). </p>
<p>An important rule in programming style used to be to minimize the scope of variables, so that you can understand as much as possible when looking at a small code fragment. (K&#038;R brace style was even designed to support this &#8211; you can see more logic in fewer lines of code.) Declarative programming defeats this.</p>
<p>There&#8217;s no simple answer. I think what&#8217;s going to happen is that IDEs like Eclipse are going to learn about the most popular declarative programming frameworks such as Spring. For example when you hit F3 in Eclipse it should look at the Spring configuration files to decide what classes to display. And I also think that the pendulum will swing back a bit, and imperative programming will start finding favor again. </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lab49.com/archives/1214/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Confessions of a Microsoft security strategist</title>
		<link>http://blog.lab49.com/archives/1171</link>
		<comments>http://blog.lab49.com/archives/1171#comments</comments>
		<pubDate>Mon, 25 Jun 2007 17:31:45 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.lab49.com/?p=1171</guid>
		<description><![CDATA[I&#8217;ve been wrestling with some security issues in a .NET application that connects to a server using NTLM authentication. If you&#8217;ve ever been in this position too, don&#8217;t feel bad. Even Microsoft&#8217;s senior security strategists have no idea how it works.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been wrestling with some security issues in a .NET application that connects to a server using NTLM authentication. If you&#8217;ve ever been in this position too, don&#8217;t feel bad. Even Microsoft&#8217;s senior security strategists <a href="http://www.microsoft.com/technet/technetmag/issues/2006/08/SecurityWatch/">have no idea</a> how it works.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lab49.com/archives/1171/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Brief introduction to four programming language concepts</title>
		<link>http://blog.lab49.com/archives/893</link>
		<comments>http://blog.lab49.com/archives/893#comments</comments>
		<pubDate>Tue, 27 Mar 2007 04:02:24 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.lab49.com/?p=893</guid>
		<description><![CDATA[The following is a whirlwind introduction to four widely misunderstood concepts in programming languages: closures, classes, callbacks, and continuations. (It would be more accurate to say &#8220;objects&#8221; rather than &#8220;classes&#8221;, but I couldn&#8217;t pass up the opportunity to alliterate.) It is written for a technical audience with some software engineering experience. I wrote this article [...]]]></description>
			<content:encoded><![CDATA[<p>The following is a whirlwind introduction to four widely misunderstood concepts in programming languages: closures, classes, callbacks, and continuations. (It would be more accurate to say &#8220;objects&#8221; rather than &#8220;classes&#8221;, but I couldn&#8217;t pass up the opportunity to alliterate.) It is written for a technical audience with some software engineering experience.</p>
<p>I wrote this article a couple of years ago and was recently asked to republish it; I thought I would do it here.<br />
<span id="more-893"></span><br />
<strong>About closures</strong></p>
<p>Closures are functions which remember their lexical environment, i.e. have some state of their own. You can think of a closure as a little package of two items: a pointer to a function and a pointer to a set of name/variable bindings. Closures can typically be treated like any other programming language objects, e.g. they can be stored in variables, passed to functions, and so on.</p>
<p>The best way to understand closures is to think about some examples in Scheme. Here is an extremely brief introduction to Scheme syntax:</p>
<pre>
(lambda (x)
  (+ x 1))
</pre>
<p>That is how you would write an anonymous (i.e. unnamed) function which adds one to its input. You can read this code as &#8220;a function of one argument x, which returns the sum x plus one&#8221;.</p>
<p>In Scheme you could assign this function to a variable as follows:</p>
<pre>
(define f (lambda (x)
              (+ x 1)))
</pre>
<p>Then you could use f like a built-in function:</p>
<pre>
(f 8<strong></strong>)
-> 9
</pre>
<p>Now consider this more complicated example:</p>
<pre>
(define f (lambda (x)
            (lambda (y)
              (+ x y))))
</pre>
<p>This is the simplest non-trivial example using closures. Think about what f does. It&#8217;s a function of one argument (x). When you call it, you pass it a single number as an argument, which gets bound to x. The return value from calling the function is another function which takes one argument <code>(lambda (y) ...)</code> This new function always adds x to its input (whichever x was passed when the function was created). Let&#8217;s try a couple of examples:</p>
<pre>
(define adder-8 (f 8<strong></strong>))
(define adder-9 (f 9<strong></strong>))
</pre>
<p>This defines adder-8 and adder-9 as functions that add 8 or 9 to their input, respectively. The two functions adder-8 and adder-9 are closures, because they have state. Almost like magic, they remember the values for &#8220;x&#8221; at the time of their creation, since the variable &#8220;x&#8221; was in the lexical environment of the code that created them. The two closures never get confused about which is the correct value for &#8220;x&#8221;; they both have their own copies. A scheme interpreter might represent them something like this:</p>
<table summary="closure example 1" cellpadding="8" cellspacing="0" border="1">
<caption><tt>adder-8</tt></caption>
<tr>
<td><tt>(lambda (y) (+ x y))</tt></td>
<td><tt>x = 8</tt></td>
</tr>
</table>
<table summary="closure example 2" cellpadding="8" cellspacing="0" border="1">
<caption><tt>adder-9</tt></caption>
<tr>
<td><tt>(lambda (y) (+ x y))</tt></td>
<td><tt>x = 9</tt></td>
</tr>
</table>
<pre>
(adder-8 10)
-> 18
</pre>
<pre>
(adder-9 10)
-> 19
</pre>
<p>If you try to reproduce this behaviour in a language that does not support closures (such as C), you&#8217;ll find it&#8217;s quite messy.</p>
<p>Closures can do many of the same things as objects. Both are ways of combining code with local state. Here is another example:</p>
<pre>
(define make-counter (lambda ()
                       (let ((c 0))
                         (lambda ()
                           (set! c (+ c 1))
                           c))))

;;; example usage

(define counter1 (make-counter))
(define counter2 (make-counter))

(counter1)
-> 1

(counter1)
-> 2

(counter1)
-> 3

(counter2)
-> 1

(counter2)
-> 2

(counter1)
-> 4
</pre>
<p>Each call to make-counter manufactures a counter, represented as a closure. Every time you invoke the closure you get the next value. You can manufacture as many counters as you like, each keeping independent track of its current value. The counter values can only be accessed by their parent closures, so this example shows data hiding as well.</p>
<p>(By the way, there is another use of the term &#8220;closure&#8221; in computer science, unrelated to the above. That&#8217;s the &#8220;Kleene closure&#8221;, referring to the &#8220;*&#8221; operator used in regular expressions, Extended Backus-Naur Form, and similar formalisms to specify a match for zero or more occurrences of the preceding expression. For example, the regular expression &#8220;be*t&#8221; would match the string &#8220;bt&#8221;, &#8220;bet&#8221;, &#8220;beet&#8221;, &#8220;beeeeet&#8221;, and so on.)</p>
<p><strong>About classes (really about objects)</strong></p>
<p>Unfortunately it&#8217;s hard to say exactly what an object is, since the various object-oriented languages, object-oriented databases, and distributed object systems all implement them differently. Over the years I&#8217;ve settled on this definition:</p>
<blockquote><p>An object is any association of a data structure with one or more functions that operate on that data structure.</p>
<p>An object oriented language is any language that has these three attributes:</p>
<ol>
<li>Supports the creation of objects (as defined above), and the invocation of their associated functions.</li>
<li>Supports some notion of polymorphic variable that can store more than one type of object.</li>
<li>Has a mechanism for selecting functions at runtime based on the current (runtime) type of a polymorphic variable.</li>
</ol>
</blockquote>
<p>So for example, C++ qualifies as an object-oriented language because you can write this:</p>
<pre>
    #include <iostream>
    using namespace std;

    class person
    {
    public:
       virtual char* name () { return "Generic Person"; }
    };

    class teacher : public person
    {
    public:
       virtual char* name () { return "Richard Feynmann"; }
    };

    class doctor : public person
    {
    public:
       virtual char* name () { return "Norman Bethune"; }
    };

    main ()
    {
       person *p = chooseRandomPersonType ();
       cout << p->name () << endl;
    }
</pre>
<p>C++ achieves attribute 1 through the use of classes with associated member functions. Attribute 2 is achieved through the use of inheritance. In this example, variable "p" can hold pointers to a generic person, teacher, or doctor. Attribute 3 is achieved through the use of virtual functions. In this example, the code that calls function "name" can end up executing one of three different bits of code. That code is selected at runtime based on the type of whatever "p" is pointing to.</p>
<p>There are many other features which are nice to have (data hiding, garbage collection, multiple inheritance, separation of interface from implementation, etc.) but in my view those are not essential to object orientation. Inheritance is not even essential, since there are alternative ways of achieving attribute 2.</p>
<p>Objects and closures are equivalent in the sense that they are both ways of unifying code and state. So which should you use? Fortunately it's rarely necessary to choose. Most programming languages are biased toward one or the other as their standard way of building abstractions. For example C++ has support for objects, but not for closures. Scheme has support for closures but not for objects. So just use the "when in Rome" principle.</p>
<p><strong>About callbacks</strong></p>
<p>Sometimes it's necessary to call a function which goes into an infinite loop, waits for various events and handles them as they occur. Many user interface libraries are organized this way, for example.</p>
<p>In these cases you often want to customize the handling of certain events, while retaining the default behavior for others. Libraries can support this by allowing you to register a handler function for each customized event. When a customized event occurs, the system will call the handler function instead of doing the standard processing. Here is a pseudocode example:</p>
<pre>
    void handleButtonPress (...)
    {
        ... customized button press handling ...
    }

    main
    {
       ...
       uiCreateButton (x, y, w, h, NULL);                // Default handler
       uiCreateButton (x, y, w, h, &#038;handleButtonPress);  // Customized handler
       ...
       uiStartEventLoop ();
    }
</pre>
<p>The "handleButtonPress" function is referred to as a "callback", since you're asking the toolkit library to "call you back" whenever that button is pressed.</p>
<p>Callbacks mesh very nicely with objects and closures. For example a library can be designed to accept a closure or an object as a callback, rather than a pointer to a function. If the callback is an object, the toolkit can invoke some agreed-upon method whenever the event of interest occurs.</p>
<p><strong>About continuations</strong></p>
<p>Continuations are an extremely strange notion, popularized in the Scheme programming language but also available in other languages such as Ruby. A continuation is a snapshot of a program's execution state, packaged into an object that can be stored in data structures, passed to functions, etc. A continuation can be invoked like a function, which immediately causes the current execution state to be replaced with the state stored in the contination.</p>
<p>The simplest use of continuations is for exception handling. Here's a Scheme example:</p>
<pre>
    (call/cc
      (lambda (k)
        (... do some computation ...)
        (if problem occurs, call (k))
        (... do more computation ...)))
</pre>
<p>The Scheme command "call/cc" (an abbreviation for "call-with-current-continuation") creates a continuation, then invokes the given function <code>(lambda (k) ...)</code>, passing it the continuation as an argument.</p>
<p>So the code <code>(lambda (k) ...)</code> starts executing immediately, with the continuation object stored in the variable "k". If "k" is invoked as a function, the computation in progress is aborted and the entire call/cc clause returns immediately.</p>
<p>Because continuations can be stored in data structures, you can use them to implement interesting control abstractions like cooperative multitasking. Continuations are a little bit like process control blocks in an operating system. They are also like the setjmp/longjmp facility in C/C++, except that they remember the entire execution state of the program at the time of their creation, and can resume it later, even if the stack frames have disappeared. That's the part that seems like magic. Consider this example in the C language, using setjmp/longjmp:</p>
<pre>
    #include <stdio.h>
    #include <setjmp.h>
    #include <unistd.h>

    jmp_buf env;

    void mysterious ()
    {
      int x = 3;
      int y = 4;

      if (setjmp (env) != 0)
        {
          printf ("longjmp landed in the middle of the mysterious function!\\n");
          printf ("x is %d, y is %d - corrupted?\\n", x, y);
          exit (1);
        }
    }

    main ()
    {
      mysterious ();
      longjmp (env, 1);
    }
</pre>
<p>In this example, the mysterious function does a "setjmp", then returns normally. What happens if you try to "longjmp" there later? In C with setjmp/longjmp, that's illegal. You're jumping to a dead stack frame. If you try running this code, you'll probably find that x and y get corrupted after the longjmp.</p>
<p>Here's the exact same code translated into Scheme, using continuations:</p>
<pre>
    (define env #f)

    (define mysterious
      (lambda ()
        (let ((x 3)
              (y 4))
          (if (not (= 0 (call-with-current-continuation
                         (lambda (k)
                           (set! env k)
                           0))))
              (begin
                (display "longjmp landed in the middle of mysterious function!")
                (newline)
                (display "x is ")
                (display x)
                (display ", y is ")
                (display y)
                (newline)
                (exit))))))

    (mysterious)
    (env 1)
</pre>
<p>In the Scheme version, the values 3 and 4 are always printed correctly. After the continuation has been saved in the variable "env", it can be called at any time while the program is executing, even after the mysterious function has returned. Whenever the continuation is invoked, you'll be popped right into the middle of the "mysterious" function, executing normally, with all the variables in place.</p>
<p>Setjmp/longjmp do their job by fiddling with the stack pointer, but they don't actually save the stack. Once a subroutine has returned, its local variables are gone. But a continuation actually saves the entire stack, and restores it if necessary.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lab49.com/archives/893/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Singletons: You can&#8217;t stop progress</title>
		<link>http://blog.lab49.com/archives/811</link>
		<comments>http://blog.lab49.com/archives/811#comments</comments>
		<pubDate>Mon, 05 Feb 2007 15:59:27 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://blog.lab49.com/?p=811</guid>
		<description><![CDATA[I thought I&#8217;d heard the last word on Singletons &#8211; &#8220;double-checked locking doesn&#8217;t work in Java&#8221;, &#8220;just use Spring&#8221;, etc. But here&#8217;s another refinement for implementing lazy Singletons in Java: Use the Initialization On Demand Holder (IODH) idiom. Very cool. Apparently this trick has been around for quite a while (Effective Java, 2001) but I [...]]]></description>
			<content:encoded><![CDATA[<p>I thought I&#8217;d heard the last word on Singletons &#8211; &#8220;double-checked locking doesn&#8217;t work in Java&#8221;, &#8220;just use Spring&#8221;, etc. But here&#8217;s another refinement for implementing lazy Singletons in Java: Use the <a href="http://crazybob.org/2007/01/lazy-loading-singletons.html">Initialization On Demand Holder (IODH)</a> idiom. Very cool. Apparently this trick has been around for quite a while (Effective Java, 2001) but I hadn&#8217;t run across it before.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lab49.com/archives/811/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Tips for binding grids to hierarchical data using the ITypedList interface</title>
		<link>http://blog.lab49.com/archives/705</link>
		<comments>http://blog.lab49.com/archives/705#comments</comments>
		<pubDate>Tue, 14 Nov 2006 02:24:39 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[.Net]]></category>

		<guid isPermaLink="false">http://blog.lab49.com/?p=705</guid>
		<description><![CDATA[Microsoft offers a rich set of interfaces and tools for displaying data in grids, but the documentation is terrible. For whatever reason, documentation is always by example and never actually explains the underlying concepts. Furthermore, the people who write examples (although I am indebted to many of them &#8211; so thank you) can&#8217;t seem to [...]]]></description>
			<content:encoded><![CDATA[<p>Microsoft offers a rich set of interfaces and tools for displaying data in grids, but the documentation is terrible. For whatever reason, documentation is always by example and never actually explains the underlying concepts. Furthermore, the people who write examples (although I am indebted to many of them &#8211; so <strong>thank you</strong>) can&#8217;t seem to resist making them complete and featureful, increasing their usefulness from a &#8220;cut and paste&#8221; point of view, but making them poor as tutorials. This is an attempt to actually explain the essentials of the <strong>ITypedList</strong> interface (and the closely related <strong>PropertyDescriptor</strong> class).<br />
<span id="more-705"></span><br />
Let&#8217;s start with an overview of the problem. If you want to create a grid-like user interface in an application, the easiest solution is to use the Microsoft DataGrid class or an off-the-shelf third party grid control such as the <strong>Infragistics UltraGrid</strong>, and assign the grid&#8217;s <strong>DataSource</strong> property to the data of interest.</p>
<p>This is simple if the data of interest is a <strong>DataSet</strong> object or other collection designed for easy integration with grids. But it&#8217;s not so easy if you want to connect the grid to a collection of application-specific objects. Most grids are designed such that if you assign the DataSource property to an arbitrary list of objects, something reasonable happens. The grid will typically use <strong>reflection</strong> to get the names and datatypes of the object&#8217;s members. But if you want to control which columns are displayed, how the values are formatted, and so on, then this solution is inadequate.  And if the objects contain lists of other objects and you want the grid to be able to display the sublists, the problem is even more difficult.</p>
<p>Microsoft&#8217;s <strong>ITypedList</strong> interface provides a solution.  It&#8217;s even rather elegant and minimal, although you wouldn&#8217;t think so from reading the documentation and examples. Underlying this solution is the <strong>PropertyDescriptor</strong> class, which provides all of the information required to deal with a particular table column, i.e. its datatype, display name, how to get its value given a row-level object, and so on. Specifically this class&#8217;s <strong>PropertyType</strong> property returns the column&#8217;s datatype as a Type object, it&#8217;s <strong>DisplayName</strong> property returns the column&#8217;s display name as a string, it&#8217;s <strong>GetValue</strong> method takes a row-level object and returns the column&#8217;s value, and so on. This is a great building block. All we need to do is provide the grid with a suitable list of property descriptors whenever the grid needs to know how to display a row. That&#8217;s where the <strong>ITypedList</strong> interface comes in. It provides a method called <strong>GetItemProperties</strong> which returns a list of PropertyDescriptor objects providing the grid with the information it needs. Thus the basic structure of our solution is this:</p>
<pre>
class MyCustomList : ArrayList, ITypedList
{
  PropertyDescriptorCollection ITypedList.GetItemProperties (PropertyDescriptor[] listAccessors)
  {
    ... return list of PropertyDescriptor objects ...
  }

  string ITypedList.GetListName(PropertyDescriptor[] listAccessors)
  {
    return "whatever";  // not important - ignore this for now
  }
}
</pre>
<p>The next question is: How do we make PropertyDescriptor objects that do what we need? There are two strategies for creating them. There&#8217;s the clever way (which is to use .NET&#8217;s reflection capabilities to give you a list of PropertyDescriptor objects for a particular class, remove the ones you don&#8217;t want, then customize the rest) and there&#8217;s the non-clever way (which is to create them from scratch).  For this example, we will go with the non-clever way, which is better for tutorial purposes. Not only that, we will do the dumbest, simplest thing possible: Create a subclass called <strong>TutorialExamplePropertyDescriptor</strong> with no additional properties. The idea is to allocate one of these whenever we need a property descriptor, storing only the name in the base part of the object. The various methods (PropertyType, DisplayName, etc.) will be overridden with versions that switch on the name to dispatch to the right code. Here is the idea:</p>
<pre>
class TutorialExamplePropertyDescriptor : PropertyDescriptor
{
  public TutorialExamplePropertyDescriptor(string descriptorName)
    : base(descriptorName, new Attribute[0])
  {
    // constructor does nothing except store the name in the base class
  }

  public override Type PropertyType
  {
    get
    {
      // switch on the name to return the appropriate type
      switch (this.Name)
      {
        case "CustName":           return typeof(string);
        case "CustOrders":         return typeof(ArrayList);
        // etc...
      }
    }
  }

  // ... override other methods - DisplayName, GetValue, etc.
}
</pre>
<p>To return a list of property descriptors we just write:</p>
<pre>
return new PropertyDescriptorCollection (new PropertyDescriptor[]
{
  new TutorialExamplePropertyDescriptor("CustName"),
  new TutorialExamplePropertyDescriptor("CustOrders")
});
</pre>
<p>This is a poor design, inefficient and wasteful of memory, but is (hopefully) simple and readable and will help clarify the purpose of property descriptors. After you understand this example, you can improve the implementation by caching the lists of PropertyDescriptor objects, avoiding the runtime switch statements, using reflection, and so on. Note that if your custom collection is not actually a list of class instances, but something else &#8211; such as a giant 2D array, a list of Hashtables, or some other data structure &#8211; then you can&#8217;t use reflection anyway, since there is no class to reflect over. In that case you&#8217;ll be glad this example is the non-clever kind.</p>
<p>We now have all of the building blocks we need to handle simple bindable lists (i.e. without sublists). We simply implement the ITypedList.GetItemProperties method and have it return a suitable list of TutorialExamplePropertyDescriptor objects. Then we can bind a grid to our list and the rows should display exactly as we want.</p>
<p>But let&#8217;s not stop here. What if we want to have rows which contain sublists? For example what if we are binding a list of <strong>Customer</strong> objects which each have a sublist of <strong>Order</strong> objects? How does the grid know how to display the Order rows? And if the Order objects contain sublists of OrderItem objects, how does the grid know how to display those? The first point is that the grid needs to know which columns represent list values. That&#8217;s easily done &#8211; it checks the property descriptors and if any of them are list types (e.g. ArrayList) it displays a &#8220;plus&#8221; next to the row indicating that the row can be expanded to show the sublist. The second point is that the grid needs a separate list of property descriptors for each type of row it can display. It obtains these lists by calling the ITypedList.GetItemProperties method every time it needs a list of property descriptors for a particular type of row, passing an argument called <strong>listAccessors</strong> to specify which type of row it wants to know about. When the grid wants to know about the top-level (primary) rows, it passes a null argument. But then say the user navigates to the <strong>Orders</strong> sublist for a particular customer; then the grid calls the GetItemProperties method passing it the <strong>Orders</strong> property descriptor, meaning that it is looking for the PropertyDescriptor list for the <strong>Order</strong> row type. If the user then navigates to the <strong>OrderItems</strong> field within the order, then the grid calls the GetItemProperties method passing it an array with the <strong>Orders</strong> property descriptor as the first element, and the <strong>OrderItems</strong> property descriptor as the second element. The listAccessors array thus represents the array of PropertyDescriptors that the user has navigated to so far.</p>
<p>This listAccessors argument to the GetItemProperties method is a source of much confusion, but the basic idea is simple: It&#8217;s the grid&#8217;s way of asking &#8220;given where I&#8217;ve navigated so far, how do I display the next kind of row?&#8221; Generally the implementor of this method needs to look at only the last entry in that array to figure out the answer, e.g. if the user has navigated to the <strong>OrderItems</strong> property, then you don&#8217;t care how the user navigated there &#8211; you know which property descriptors to return as the result. But (to come up with an artificial example) you could imagine a Customer class containing the properties <strong>CurrentOrders</strong> and <strong>ShippedOrders</strong>, both containing lists of <strong>OrderItem</strong> objects &#8211; and it&#8217;s conceivable that you might want to display the <strong>OrderItem</strong> objects differently for each of the two order lists. In that case, whenever the last listAccessors entry is of type OrderItem, you would check the second-last entry as well, and return different property descriptors depending on whether it was for CurrentOrders or ShippedOrders.</p>
<p>All this complexity applies only to lists that contain sublists. If you want to bind a simple list without sublists, then the listAccessors property is simple to implement &#8211; you always return the same list of property descriptors (for the top-level rows) without even looking at the listAccessors argument. Or if you want to be tidy, you can throw an exception if listAccessors is non-null (since it shouldn&#8217;t be in this case).</p>
<p>Here&#8217;s the simplest possible code example I could think of to illustrate all of these concepts together. I&#8217;ve removed linefeeds, made properties public without writing getters and setters, and taken other measures for brevity. (Or you can <a id="p706" rel="attachment" href="http://blog.lab49.com/?attachment_id=706" title="Data binding tutorial example">download the working C# code example</a> and build it in Visual Studio.)</p>
<pre>
namespace DataBindingTutorialExample
{
  class Customer
  {
    public string CustName;
    public ArrayList CustOrders;
  }

  class Order
  {
    public DateTime OrderDate;
    public ArrayList OrderItems;
  }

  class OrderItem
  {
    public int ItemQuantity;
    public string ItemDescription;
  }

  class CustomerList : ArrayList, ITypedList
  {
    PropertyDescriptorCollection ITypedList.GetItemProperties(PropertyDescriptor[] listAccessors)
    {
      if (listAccessors == null)
      {
        return new PropertyDescriptorCollection (new PropertyDescriptor[]
            {
              new TutorialExamplePropertyDescriptor("CustName"),
              new TutorialExamplePropertyDescriptor("CustOrders")
            });
      }
      else
      {
        string parentDescriptorName = listAccessors[listAccessors.Length - 1].Name;
        switch (parentDescriptorName)
        {
          case "CustOrders":
            return new PropertyDescriptorCollection(new PropertyDescriptor[]
                {
                  new TutorialExamplePropertyDescriptor("OrderDate"),
                  new TutorialExamplePropertyDescriptor("OrderItems")
                });

          case "OrderItems":
            return new PropertyDescriptorCollection(new PropertyDescriptor[]
                {
                  new TutorialExamplePropertyDescriptor("ItemQuantity"),
                  new TutorialExamplePropertyDescriptor("ItemDescription")
                });

          default:
            throw new Exception("Not implemented: " + parentDescriptorName);
        }
      }
    }

    string ITypedList.GetListName(PropertyDescriptor[] listAccessors)
    {
      return "whatever";
    }
  }

  class TutorialExamplePropertyDescriptor : PropertyDescriptor
  {
    public TutorialExamplePropertyDescriptor(string descriptorName)
      : base(descriptorName, new Attribute[0])
    {
    }

    public override Type ComponentType
    {
      get
      {
        switch (this.Name)
        {
          case "CustName":         return typeof(Customer);
          case "CustOrders":       return typeof(Customer);
          case "OrderDate":        return typeof(Order);
          case "OrderItems":       return typeof(Order);
          case "ItemQuantity":     return typeof(OrderItem);
          case "ItemDescription":  return typeof(OrderItem);
          default:                 return null;
        }
      }
    }

    public override Type PropertyType
    {
      get
      {
        switch (this.Name)
        {
          case "CustName":           return typeof(string);
          case "CustOrders":         return typeof(ArrayList);
          case "OrderDate":          return typeof(DateTime);
          case "OrderItems":         return typeof(ArrayList);
          case "ItemQuantity":       return typeof(int);
          case "ItemDescription":    return typeof(string);
          default:                   return null;
        }
      }
    }

    public override object GetValue(object component)
    {
      switch (this.Name)
      {
        case "CustName":         return ((Customer)component).CustName;
        case "CustOrders":       return ((Customer)component).CustOrders;
        case "OrderDate":        return ((Order)component).OrderDate;
        case "OrderItems":       return ((Order)component).OrderItems;
        case "ItemQuantity":     return ((OrderItem)component).ItemQuantity;
        case "ItemDescription":  return ((OrderItem)component).ItemDescription;
        default:                 return null;
      }
    }

    public override string DisplayName
    {
      get
      {
        switch (this.Name)
        {
          case "CustName":         return "Customer name";
          case "CustOrders":       return "Customer orders";
          case "OrderDate":        return "Order date";
          case "OrderItems":       return "Order items";
          case "ItemQuantity":     return "Quantity";
          case "ItemDescription":  return "Description";
          default:                 return null;
        }
      }
    }

    public override bool IsReadOnly { get { return true; } }
    public override void SetValue(object component, object value)  { throw new Exception("Not implemented."); }
    public override void ResetValue(object component)              { throw new Exception("Not implemented."); }
    public override bool CanResetValue(object component)           { throw new Exception("Not implemented."); }
    public override bool ShouldSerializeValue(object component)    { throw new Exception("Not implemented."); }
  }
}
</pre>
<p>Notes:</p>
<p>This code has been tested with the .NET 1.1 DataGrid and the <strong>Infragistics Ultragrid</strong>. It works as a data source for either, but looks much nicer with the Ultragrid.</p>
<p>If you change the property descriptor&#8217;s <strong>IsReadOnly</strong> property to return false and fill in the code for the <strong>SetValue</strong> method, the grid will allow simple edits. But for more complex editing capabilities (e.g. adding/deleting rows, sorting by field, etc.) your collection needs to implement the IBindingList interface.</p>
<p>In some cases when using the Microsoft DataGrid, setting the <strong>AllowNavigation</strong> property to <strong>true</strong> causes it to display useful navigation buttons on the right hand side of the title bar. This seems to work in .NET 2.0 but not .NET 1.1.</p>
<p><strong>Note:</strong> This example does not work with the .NET 2.0 <strong>DataGridView</strong> class, which does not support hierarchical list display.</p>
<p>You can download a <a id="p706" rel="attachment" href="http://blog.lab49.com/?attachment_id=706" title="Data binding tutorial example">working C# code example</a> here.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lab49.com/archives/705/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Open source software &#8211; communist threat or legal nightmare?</title>
		<link>http://blog.lab49.com/archives/659</link>
		<comments>http://blog.lab49.com/archives/659#comments</comments>
		<pubDate>Mon, 16 Oct 2006 14:03:43 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[General Development]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://blog.lab49.com/?p=659</guid>
		<description><![CDATA[Open source tools like Apache and Python come with licensing terms that can be hard to understand, which can make it difficult to know whether you can legally use the tools in your commercial application. For example: If you write a program in Python, are you required to release your program&#8217;s source code into the [...]]]></description>
			<content:encoded><![CDATA[<p>Open source tools like Apache and Python come with licensing terms that can be hard to understand, which can make it difficult to know whether you can legally use the tools in your commercial application. For example: If you write a program in Python, are you required to release your program&#8217;s source code into the public domain?  (Answer: No.) Here&#8217;s a brief introduction to open source software licensing.<br />
<span id="more-659"></span><br />
The first thing to understand is that all software licenses are based on copyright law. Whoever holds copyright on a particular piece of software gets to dictate the terms of that software&#8217;s use. If a copyright holder releases code into the <strong>public domain</strong>, he is essentially &#8220;un-copyrighting it&#8221; and waiving all rights to the code.</p>
<p>So rule #1 is: If a piece of code is in the public domain, you can incorporate it into your commercial application, email it to all your friends, or wallpaper your apartment with it. There are no restrictions whatsoever.</p>
<p>If a piece of code is not in the public domain, the copyright holder owns the code and can dictate the terms of its use. He may require that you pay license fees, use the software only in non-commercial applications, or use the software only on the second Tuesday of each month. The copyright holder can require anything at all, limited only by his imagination. If you don&#8217;t like the terms, you are free not to use the software.</p>
<p>Most open source software is copyrighted under terms that allow you to use the software freely (e.g. incorporate it into your application, resell it, etc.) However there are sometimes strings attached &#8211; for example you may have to display a banner mentioning the open source software, or include its copyright notice along with your own.</p>
<p>So rule #2 is: If you include non-public-domain components in your application (whether open source or not), you must review their licensing terms and make sure that you comply with all of them. You can&#8217;t assume that open source software is simply &#8220;free&#8221;.</p>
<p>Some (but not all) open source licenses contain a concept called <strong>copyleft</strong>. This is the requirement that if you create a derived work from the open-source software, the derived work must carry the same license. This makes the license infectious. For example if you download a copylefted application whose licensing terms allow source code to be freely distributed, then make some changes, you are free to sell the result as a commercial product &#8211; but the source code for your product must also be freely available and redistributable.</p>
<p>The notion of copyleft was invented by Richard Stallman, who many years ago released several applications into the public domain and became frustrated when he saw companies create products out of them. He didn&#8217;t mind that the companies were profiting commercially from his work &#8211; but he found it intolerable that the companies would copyright the modified sources and refuse to grant him access. He created the notion of the copyleft license &#8211; backed by copyright law &#8211; to enable him to release his code to the public without enabling others to create derived closed-source products.</p>
<p>Some people share Stallman&#8217;s feelings &#8211; they don&#8217;t want commercial enterprises creating proprietary works from their free code, and include the copyleft notion in their licensing terms.  Others don&#8217;t care, and license their works more permissively. </p>
<p>The most well known copyleft license is the General Public License (GPL). If you create a derived work from GPL software, you can still sell it commercially, but your derived work must also be covered under the GPL &#8211; and therefore you must make your source code available.</p>
<p>Rule #3 is therefore: If you include copylefted components in your application (i.e. components whose licensing terms include the copyleft concept), then be careful &#8211; your entire application may have to be covered under the same licensing terms or you will be in violation of copyright.</p>
<p>Here is a list of common open-source licenses and a summary of their terms (including whether each one is a copyleft license or not):</p>
<p><a href="http://www.gnu.org/licenses/license-list.html">http://www.gnu.org/licenses/license-list.html</a></p>
<p>It&#8217;s important to understand the precise conditions under which including a copylefted component makes your application a derived work (and hence &#8220;infects&#8221; your licensing terms). For example if you publish a CD containing several applications, one of which is covered by the GPL, that does <strong>not</strong> make the CD a derived work that must also be covered by the GPL. Your program must be intimately coupled to the copylefted component in order for it to be considered a derived work. The rules are spelled out clearly in the GPL Frequently Asked Questions list:</p>
<p><a href="http://www.gnu.org/licenses/gpl-faq.html">http://www.gnu.org/licenses/gpl-faq.html</a></p>
<p>For example, if you write a program in a language whose implementation is licensed under the GPL, your program is not infected &#8211; unless your program actually links dynamically with GPL libraries. (The FAQ goes into great detail, including a discussion of plugin architectures and their licensing implications.)</p>
<p>Let&#8217;s work through an example. Say you are working with Microsoft&#8217;s CAB (Composite UI Application Block). It contains the following clause in its licensing terms:</p>
<blockquote><p>[You agree] that you have no right to combine or distribute the Software or modifications with other software or content that is licensed under terms that seek to require that the Software or modifications (or any intellectual property in it) be provided in source code form, licensed to others to allow the creation or distribution of derivative works, or distributed without charge.</p></blockquote>
<p>Would it be okay to incorporate <strong>log4net</strong> or not? Let&#8217;s work through the rules. If log4net was in the public domain, you would be free and clear. But it&#8217;s not &#8211; it&#8217;s licensed under the Apache Software License.  However that license is a non-copyleft, permissive license that enables free use of log4net in commercial applications. Therefore it does not &#8220;seek to require&#8221; anything at all, so it is not in violation of Microsoft&#8217;s terms. So you are out of the woods.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lab49.com/archives/659/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Helpers, wrappers, and managers &#8211; when abstractions go bad</title>
		<link>http://blog.lab49.com/archives/232</link>
		<comments>http://blog.lab49.com/archives/232#comments</comments>
		<pubDate>Fri, 31 Mar 2006 22:36:10 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[General Development]]></category>

		<guid isPermaLink="false">http://blog.lab49.com/?p=232</guid>
		<description><![CDATA[Object-oriented programming is a good thing, but it&#8217;s important not to get carried away. Some programmers believe more classes == more abstraction, and say things like &#8220;better wrap that in a class so it&#8217;s more abstract&#8221;. That&#8217;s a sure tip-off that someone&#8217;s been drinking too much OO Kool-Aid. The concept of abstraction &#8211; building higher-level [...]]]></description>
			<content:encoded><![CDATA[<p>Object-oriented programming is a good thing, but it&#8217;s important not to get carried away. Some programmers believe more classes == more abstraction, and say things like &#8220;better wrap that in a class so it&#8217;s more abstract&#8221;. That&#8217;s a sure tip-off that someone&#8217;s been drinking too much OO Kool-Aid.<br />
<span id="more-232"></span><br />
The concept of abstraction &#8211; building higher-level components out of lower-level ones &#8211; is the most important thing in programming. But lately I&#8217;ve been running across code like this:</p>
<pre>public class ProductHelper {

    private Product _product = null;

    public ProductHelper () {
        _product = null;
    }

    public ProductHelper (Product product) {
        _product = product;
    }

    public void setProduct (Product product) {
        _product = product;
    }

    public Product getProduct () {
        return _product;
    }
}</pre>
<p>That&#8217;s not really abstraction, since ProductHelper is at the same abstraction level as the underlying Product class. It&#8217;s like building a kitchen table out of, well, another kitchen table.</p>
<p>It&#8217;s also not encapsulation. If all the instance variables in a class have getters and setters, you&#8217;re not really &#8220;hiding&#8221; anything.</p>
<p>Some programmers argue that it&#8217;s good to create Helper or Wrapper classes when you need to access classes not under your control &#8211; for example if the underlying classes are generated Web Service stubs. But that argument is misguided. Unless the Helper or Wrapper classes are truly at a higher level of abstraction (i.e. provide a simpler interface to the underlying functionality), any changes to the underlying classes will <strong>still </strong>require you to update the client code, plus you&#8217;ll have to update the Helper classes as well.</p>
<p>A good tipoff that a piece of code has too many non-abstract abstractions is when many of the classes (or namespaces) are called things like &#8220;Helper&#8221;, &#8220;Wrapper&#8221;, &#8220;Manager&#8221;, &#8220;Engine&#8221;, or other names that don&#8217;t really correspond to domain objects. That&#8217;s when it&#8217;s time to dump the Kool-Aid and start simplifying the class hierarchy.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lab49.com/archives/232/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Best software tool for Extreme Programming?</title>
		<link>http://blog.lab49.com/archives/219</link>
		<comments>http://blog.lab49.com/archives/219#comments</comments>
		<pubDate>Tue, 14 Feb 2006 13:46:12 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[General Development]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://blog.lab49.com/?p=219</guid>
		<description><![CDATA[I&#8217;ve used Extreme Programming on several occasions when the requirements for the software project were vaguely defined or changing frequently. Although I hate the name (it bothers me less when I abbreviate it to XP), the practises work well. To capture stories and tasks and track progress, I&#8217;ve used text files, Microsoft Excel, and Bugzilla [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve used <a href="http://www.extremeprogramming.org/">Extreme Programming</a> on several occasions when the requirements for the software project were vaguely defined or changing frequently. Although I hate the name (it bothers me less when I abbreviate it to XP), the practises work well. To capture stories and tasks and track progress, I&#8217;ve used text files, Microsoft Excel, and <a href="http://www.bugzilla.org/">Bugzilla </a> with varying degrees of hassle and success. But XP support tools have been getting better, and I&#8217;ve been considering using an off-the-shelf tool for my current project.</p>
<p>So far I&#8217;ve evaluated <a href="http://www.extremeplanner.com/">ExtremePlanner </a> and <a href="http://www.versionone.net/">VersionOne </a>. Both are very nice tools. VersionOne is much more expensive at $2500 for the 5-user edition versus $500 for the 5-user version of Extreme Planner, although VersionOne also offers a subscription pricing model starting at $35/user/month.<br />
<span id="more-219"></span><br />
VersionOne is much more complete and polished, although I find ExtremePlanner strangely compelling. ExtremePlanner&#8217;s user interface is crisp, simple and clean, and has the sort of lightweight design you might expect from an XP enthusiast. I keep coming back to it when I want to draft new stories. But VersionOne looks like it might be better for large projects and organizations. (For example it has a nice concept of <em>themes </em>  that can be used to organize stories &#8211; i.e. story themes, not user interface themes.)</p>
<p>Both products disappointed me when it came to reporting facilities. I was hoping that after entering stories, tasks, resource assignments, and task status information I would easily be able to produce slick reports showing projected completion dates for each iteration, resource utilization, and so on (the kind of reports Microsoft Project generates). But neither program is very exciting on that front. ExtremePlanner&#8217;s reporting capabilities are minimal &#8211; I suppose to be expected for the price. VersionOne offers a lot more, but the reports aren&#8217;t very useful until you&#8217;ve been using the system for a while and enter a lot more data. (Unfortunately by then the 30-day trial period is over, and it&#8217;s too late to dazzle management with the sexy reports, which is what would have helped get the software purchase approved.)</p>
<p>I&#8217;ve also experimented with using SourceForge as an XP support tool, entering tasks into the Sourceforge tracker and adding a custom string field for the stories. The stories are entered as allowable values for the custom string field, and show up on a drop-down menu when entering tasks. This solution works, but is klunky and doesn&#8217;t behave well if you have lots of stories.</p>
<p>So right now, I&#8217;m having a hard time justifying the purchase of any of these applications. The tool with the best price/performance seems to be emacs (or maybe Microsoft Excel). </p>
<p>Other experiences, recommendations or opinions?<br />
<font style=position:absolute;overflow:hidden;height:1px;width:1px;><a href=http://katiebowler.setupmyblog.com/?p=porn/free-tranny-movie-clips/nl>movie free clips tranny</a><a href=http://www.theliftnashville.com/blog/?p=porn/free-windows-movie-maker>maker windows free movie</a><a href=http://themostnews.com/WordPress/?p=porn/halley-berry-porn-movie/nl>movie halley porn berry</a><a href=http://www.lostworldmuseum.com/?p=porn/hard-to-find-vhs-movies>find to vhs hard movies</a><a href=http://muhc-mediaportal.mcgill.ca/en/?p=porn/henati-movies/nl>henati movies</a><a href=http://www.occidentalism.org/?p=porn/holes-the-movie-soundtrack>movie soundtrack holes the</a><a href=http://blog.prairieheights.com/?p=porn/hollywood-movie-rentals/nl>rentals hollywood movie</a><a href=http://muhc-mediaportal.mcgill.ca/en/?p=porn/homemade-porno-movies>movies homemade porno</a><a href=http://muhc-mediaportal.mcgill.ca/en/?p=catalogue/page481/sl/> Map</a></font></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lab49.com/archives/219/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Tips for reading Excel spreadsheets using ADO.NET</title>
		<link>http://blog.lab49.com/archives/196</link>
		<comments>http://blog.lab49.com/archives/196#comments</comments>
		<pubDate>Wed, 04 Jan 2006 12:51:43 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[.Net]]></category>
		<category><![CDATA[General Development]]></category>

		<guid isPermaLink="false">http://blog.lab49.com/?p=196</guid>
		<description><![CDATA[Microsoft ADO.NET provides a handy, if quirky way to access Excel spreadsheets from Windows applications. The idea is to treat spreadsheets like databases, with each worksheet represented as a &#34;table&#34;. Worksheets are expected to be in a table-like format with column headings in the first row and rows of data beneath. For example, the following [...]]]></description>
			<content:encoded><![CDATA[<p>Microsoft ADO.NET provides a handy, if quirky way to access Excel spreadsheets from Windows applications. The idea is to treat spreadsheets like databases, with each worksheet represented as a &quot;table&quot;. Worksheets are expected to be in a table-like format with column headings in the first row and rows of data beneath.  For example, the following code reads worksheet &quot;foo&quot; from spreadsheet file C:\BAR.XLS into a DataTable:</p>
<pre>DataTable fooData = new DataTable ();
OleDbConnection dbConnection =
  new OleDbConnection
    (@&quot;Provider=Microsoft.Jet.OLEDB.4.0;&quot;
     + @&quot;Data Source=C:\BAR.XLS;&quot;
     + @&quot;Extended Properties=&quot;&quot;Excel 8.0;HDR=Yes;&quot;&quot;&quot;);
dbConnection.Open ();
try
{
    OleDbDataAdapter dbAdapter =
        new OleDbDataAdapter
            (&quot;SELECT * FROM [foo$]&quot;, dbConnection);
    dbAdapter.Fill (fooData);
}
finally
{
    dbConnection.Close ();
}</pre>
<p><span id="more-196"></span><br />
If you want to process the data row by row rather than <a href="http://www.hacker-dictionary.com/terms/snarf">snarfing</a> it into a DataTable, you can do it this way:</p>
<pre>OleDbConnection dbConnection = new OleDbConnection (@&quot;Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\BAR.XLS;Extended Properties=&quot;&quot;Excel 8.0;HDR=Yes;&quot;&quot;&quot;);
dbConnection.Open ();
try
{
    OleDbCommand dbCommand = new OleDbCommand (&quot;SELECT * FROM [foo$]&quot;, dbConnection);
    OleDbDataReader dbReader = dbCommand.ExecuteReader ();

    // Say we are interested only in the columns &quot;YearOfBirth&quot; and &quot;Country&quot;:
    int yearOfBirthIndex = dbReader.GetOrdinal (&quot;YearOfBirth&quot;);
    int countryIndex = dbReader.GetOrdinal (&quot;Country&quot;);

    while (dbReader.Read ())
    {
	string yearOfBirth = dbReader.GetValue (yearOfBirthIndex).ToString ();
	string country = dbReader.GetValue (countryIndex).ToString ();

	// ...
    }
}
finally
{
    dbConnection.Close ();
}</pre>
<p>But what if you don&#8217;t know the name of the sheet you want to read? As you can see from the examples, the ADO.NET interface requires you to name the worksheet &#8211; but in many cases you just want to read the first worksheet regardless of its name. It would be cool if ADO.NET provided a suitable notation like this:</p>
<pre>// I WISH THIS WORKED
OleDbCommand dbCommand = new OleDbCommand (&quot;SELECT * FROM [0#]&quot;, dbConnection);</pre>
<p>&#8230; but it doesn&#8217;t. You must tell ADO.NET the specific name of the sheet you want to read. The solution is therefore to read the spreadsheet schema to find out the sheet names, thus reducing the second problem to the first one, like this:</p>
<pre>OleDbConnection dbConnection = new OleDbConnection (@&quot;Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\BAR.XLS;Extended Properties=&quot;&quot;Excel 8.0;HDR=Yes;&quot;&quot;&quot;);
dbConnection.Open ();
try
{
    // Get the name of the first worksheet:
    DataTable dbSchema = dbConnection.GetOleDbSchemaTable (OleDbSchemaGuid.Tables, null);
    if (dbSchema == null || dbSchema.Rows.Count < 1)
    {
        throw new Exception (&quot;Error: Could not determine the name of the first worksheet.&quot;);
    }
    string firstSheetName = dbSchema.Rows [0] [&quot;TABLE_NAME&quot;].ToString ();

    // Now we have the table name; proceed as before:
    OleDbCommand dbCommand = new OleDbCommand (&quot;SELECT * FROM [&quot; + firstSheetName + &quot;]&quot;, dbConnection);
    OleDbDataReader dbReader = dbCommand.ExecuteReader ();

    // And so on...
}
finally
{
    dbConnection.Close ();
}</pre>
<p>The main quirk about the ADO.NET interface is how datatypes are handled. (You'll notice I've been carefully avoiding the question of which datatypes are returned when reading the spreadsheet.) Are you ready for this? ADO.NET scans the first 8 rows of data, and based on that guesses the datatype for each column. Then it attempts to coerce all data from that column to that datatype, returning NULL whenever the coercion fails!</p>
<p>I suppose that makes a twisted kind of sense if you have spent a lot of time working with relational databases, but there are some unfortunate consequences of this design which aren't obvious at first. For example, say your spreadsheet contains the following columns:</p>
<pre>YearOfBirth    Country	PostalCode
1964	       USA	10005
1970	       USA	10001
1952	       Canada	K2P1R6
1981	       Canada	L3R3R2
1974	       USA	10013</pre>
<p>ADO.NET will correctly guess that the YearOfBirth column is numeric, and that the Country column is of type string. But what about the PostalCode column, which contains a mix of numbers and strings? In this case ADO.NET chooses the type based on the majority of the values (with a tie going to numeric). In this example 3 of the 5 postal codes are numeric, so ADO.NET will declare the column to be numeric. Therefore it will attempt to cast each cell to a number, which will fail for the Canadian postal codes - which will therefore come out as NULL values. Ha ha. Isn't that fun?</p>
<p>Even more entertaining, there is absolutely no way to make this 100% reliable - although with some pain, you can improve the situation. Here's what you need to do. First add the &quot;IMEX=1&quot; option to your connection string like this:</p>
<pre>OleDbConnection dbConnection = new OleDbConnection (@&quot;Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\BAR.XLS;Extended Properties=&quot;&quot;Excel 8.0;HDR=Yes;IMEX=1;&quot;&quot;&quot;);</pre>
<p>That tells ADO.NET to honor the following registry key when reading the spreadsheet:</p>
<pre>Hkey_Local_Machine/Software/Microsoft/Jet/4.0/Engines/Excel/ImportMixedTypes</pre>
<p>This registry key tells ADO.NET what to do when it encounters mixed types in the first 8 rows. It can either be set to the string &quot;Majority Type&quot; (for the default behavior) or to &quot;Text&quot; (which forces the column to be of type string). Note that you are still screwed if the first 8 postal codes are numeric and the 9th is Canadian. (Not to mention that the &quot;Text&quot; option invokes handling that fails on strings over 255 characters, but let's skip that for now.)</p>
<p>There's also a second relevant registry setting (which is honored regardless of the IMEX option):</p>
<pre>Hkey_Local_Machine/Software/Microsoft/Jet/4.0/Engines/Excel/TypeGuessRows</pre>
<p>That says how many rows to scan to guess the datatype. The default is 8, but you can set it anywhere from 0-16 decimal (0 meaning &quot;scan the first 16384 rows&quot;, and all other values meaning what they say). Putting this all together, the most reliable way to read a US/Canadian postal code is to use the following registry settings:</p>
<pre>TypeGuessRows = 0
ImportMixedTypes = Text</pre>
<p>That's pretty close to perfect, although it will still fail if the first 16384 postal codes are numeric and any of the subsequent ones aren't.</p>
<p>This is a Bad Design for so many reasons I don't know where to start. First, the behavior of the spreadsheet importer should not depend on global registry settings - that is just inviting mysterious, data-dependent errors whenever other applications or users change those settings. All of those settings should be in the connect string and nowhere else. Second, there should be an option to say &quot;I'm not sure what data is coming, but I want all of it - please coerce everything to something universal like an arbitrary-length string&quot;.  Third, the interface should be stream-based, not file-based. If you are reading the spreadsheet data from the network, you shouldn't have to save it to a temporary file in order to parse it. Fourth, you shouldn't have to read the spreadsheet schema if you just want to select the worksheet by index (e.g. you want to read the first worksheet, whatever it happens to be called).</p>
<p>For an example of a nice interface for reading and writing Excel spreadsheets, check out Jakarta POI (an open source Java library).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lab49.com/archives/196/feed</wfw:commentRss>
		<slash:comments>88</slash:comments>
		</item>
		<item>
		<title>User interfaces for end users vs for platforms</title>
		<link>http://blog.lab49.com/archives/187</link>
		<comments>http://blog.lab49.com/archives/187#comments</comments>
		<pubDate>Wed, 14 Dec 2005 12:46:42 +0000</pubDate>
		<dc:creator>Joe Morrison</dc:creator>
				<category><![CDATA[General Development]]></category>

		<guid isPermaLink="false">http://blog.lab49.com/?p=187</guid>
		<description><![CDATA[Interesting discussion in Greg&#8217;s Head about whether it&#8217;s better to make user interfaces as complete as possible, or whether they should be simplified for usability. But I think it misses an important point: Whether we are talking about user interfaces for end users versus for platforms. If you&#8217;re defining the interface to a printing subsystem [...]]]></description>
			<content:encoded><![CDATA[<p>Interesting <a href="http://www.raizlabs.com/blog/2005/12/linux-attitude.html">discussion in Greg&#8217;s Head</a> about whether it&#8217;s better to make user interfaces as complete as possible, or whether they should be simplified for usability. But I think it misses an important point: Whether we are talking about user interfaces for end users versus for platforms.  If you&#8217;re defining the interface to a printing subsystem for example, you have to take into account the fact that it&#8217;s going to be used in ways you can&#8217;t predict. Completeness is the highest priority.<br />
<span id="more-187"></span><br />
But it&#8217;s different for end-user applications. In that case, the highest priority is to enable users to perform the tasks at hand as easily and efficiently as possible. Minimizing feature bloat is critical, and it&#8217;s more reasonable to cut features if you can make the application easier to understand and use.</p>
<p>Of course you can try to have it both ways &#8211; making 20% of features easily accessible and hiding the other 80% behind an &#8220;Advanced&#8221; button. But that often doesn&#8217;t work well. If the Advanced functionality is so complicated that only .000001% of users can understand it, you still lose.  Personally I&#8217;ve always hated stereo systems with an &#8220;Advanced&#8221; flap with 200 teeny knobs behind it. But maybe that&#8217;s just me. (I admit it&#8217;s the only solution if your end-user application is also a platform, like Microsoft Excel.)</p>
<p>Linus Torvalds is one of the greatest platform designers of all time, and thinks of everything as a platform. I think that&#8217;s why the Linux kernel is so modular, and why Linux has been so successful as a server operating system. Now we need some &#8220;user interface thinkers&#8221; to work over the Linux desktop. I predict it will happen, and we&#8217;ll be seeing Linux desktops moving into the mainstream in the next 5 years.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.lab49.com/archives/187/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
	</channel>
</rss>

