<?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>let x=x &#187; java</title>
	<atom:link href="http://www.crazymcphee.net/x/tag/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.crazymcphee.net/x</link>
	<description>programming idiom and methodology</description>
	<lastBuildDate>Tue, 13 Jul 2010 21:56:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Dynamically loading Spring contexts from the classpath at runtime</title>
		<link>http://www.crazymcphee.net/x/2010/04/29/dynamically-loading-spring-contexts-from-the-classpath-at-runtime/</link>
		<comments>http://www.crazymcphee.net/x/2010/04/29/dynamically-loading-spring-contexts-from-the-classpath-at-runtime/#comments</comments>
		<pubDate>Thu, 29 Apr 2010 06:45:11 +0000</pubDate>
		<dc:creator>Scot Mcphee</dc:creator>
				<category><![CDATA[infrastructure and frameworks]]></category>
		<category><![CDATA[tools and techniques]]></category>
		<category><![CDATA[applicationcontext]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[PathMatchingResourcePatternResolver]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://www.crazymcphee.net/x/?p=540</guid>
		<description><![CDATA[Using these three Spring features will enable us to be able to place a JAR file containing an interface implementation, and a Spring context XML file matching a particular pattern, into the classpath of our WAR, and on restart, we can dynamically pick up the newly inserted features into our application installation.]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m just going to document a way I&#8217;ve found to use Spring ApplicationContext to dynamically load other context XML configurations that it find in the classpath. We have a requirement to do this coming up on a product we&#8217;re building. Let me describe the sort of problem we are trying to solve (with many specifics omitted or glossed over):</p>
<blockquote><p>There is a web service inside a component, let&#8217;s call that component a &#8216;Node&#8217;, that receives something like (but not identical to!) an Event on its interface. Inside the Event is some data that the Node does not particularly care about (and actually has no access to &#8211; it&#8217;s just a <em>byte[]</em> as far as the Node can tell). However, the Node contains a Registry which enables components, lets call them Event Handlers, to register themselves with the Node, as available to process certain Events (i.e. decode that <em>byte[]</em> and do something with it) according to criteria which the EventHandler injects into the Node&#8217;s Registry.  EventHandler is an interface with a handful of simple methods related to handling the Event, and also registration with the Registry.</p>
<p>So, the process flow looks something like this: The Node first records the reception of the Event at the interface in a log. Then it tells the Registry about the Event, and the Registry produces the EventHandler(s) it needs to use.  The Registry gives the Node back the instances of the EventHandler interface. The Node then hands off the Event to the EventHandler, which does whatever it does unbeknownst to the Node, and returns a fairly simple EventResponse object. The Node records the EventResponse object in its log (i.e. a database) and returns it as the response to the web service call.</p>
<p>Consider the Node service method as looking something like this (you&#8217;ll have to excuse the Java 1.4-ness of this code, the WordPress code highlighting plugin apparently hates Java 5) :</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">List</span> receive<span style="color: #009900;">&#40;</span><span style="color: #003399;">Event</span> event<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003399;">List</span> responses <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">ArrayList</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>EventHandler handler <span style="color: #339933;">:</span> <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">registry</span>.<span style="color: #006633;">lookup</span><span style="color: #009900;">&#40;</span>event.<span style="color: #006633;">getMetadata</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      Response response <span style="color: #339933;">=</span> handler.<span style="color: #006633;">handle</span><span style="color: #009900;">&#40;</span>event<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      saveResponse<span style="color: #009900;">&#40;</span>response, event, handler<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      responses.<span style="color: #006633;">add</span><span style="color: #009900;">&#40;</span>response<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
    <span style="color: #000000; font-weight: bold;">return</span> responses<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p>To enable the wiring, the Registry has a method:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">  <span style="color: #000066; font-weight: bold;">void</span> register<span style="color: #009900;">&#40;</span>EventMetadata metadata, EventHandler handler<span style="color: #009900;">&#41;</span></pre></div></div>

<p>and among other methods the EventHandler interface defines:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">  <span style="color: #000066; font-weight: bold;">void</span> setRegistry<span style="color: #009900;">&#40;</span><span style="color: #003399;">Registry</span> registry<span style="color: #009900;">&#41;</span></pre></div></div>

<p>Currently the WAR file imports the Node.JAR and a group of EventHandler.JAR files which are specific implementations for handling different kinds of Events. We configure it in Spring currently so that the specific EventHandler is injected with the Registry object (from the Node.JAR). The EventHandler implementation then registers itself with the Registry in a call-back operation, telling it what sort of Events it will handle<em>.</em></p></blockquote>
<p><span style="text-decoration: underline;">This all works just fine at the moment</span>. The <span style="text-decoration: underline;">problem</span> with what we have is that it is all currently statically compiled into the WAR file.The WAR file specifies a Spring application context XML file which in turn loads the Spring configuration for the Node and Registry component, and every Spring application context for each Handler JAR included inside the WAR file&#8217;s <em>WEB-INF/lib</em> directory.</p>
<p>Now, we now don&#8217;t want every deployed instance of every Node to handle every possible Event. Currently we&#8217;ve got a small <em>.properties</em> file that actually tells another Spring component which EventHandlers are be to be instantiated or not. This is working fine when we only desire some Nodes to handle maybe one or two of a larger group of related Events. That is, where we currently don&#8217;t mind that the WAR file is identical in every respect on every Node &#8212; it&#8217;s just that each node contains a <em>.properties</em> file in its classpath that tells it which EventHandlers it is allowed to load and use (and therefore what Events it is capable of receiving, bearing in mind that when I say &#8216;Events&#8217; there is really only one concrete type of Event, I mean the encrypted data which is held <span style="text-decoration: underline;">within</span> the Event which is actually consumed by the Handler).</p>
<p>However, we are now in a situation where we want to use this same architecture for a completely different group of Events. We definitely don&#8217;t want to have to compile and assemble a new WAR file for different Nodes based on the Event cluster. We want to deploy a standardized <em>Node.WAR</em> which has available on its classpath a dynamic set of <em>XxxEventHandler.JAR</em> which can dynamically register themselves with the Node&#8217;s registry. There may be also a requirement for some related custom extension points in the future.</p>
<p>Initially we considered OSGi as the technology to enable this. After some discussion yesterday with people who know better about OSGi, this approach was rejected as impractical for the moment. Therefore last night I set out tooling about with the Spring 2.5.6 ApplicationContext and its related objects to see what could be done to enable dynamically-loaded JAR files within a parent Spring application context. Here is what I&#8217;ve discovered we can do, with only some small restrictions on developers writing the individual EventHandler implementations.</p>
<p>The first issue is, we need to locate a set of Spring application context XML file which should be on the classpath but not yet instantiated into any live Spring context.</p>
<p>Assuming we&#8217;re in a bean that&#8217;s <em>ContextAware</em> or otherwise has access to the Spring application context which is loading it, after the parent context has loaded and initialized (there are method hooks for this sort of thing) we can use the <em>org.springframework.core.io.support.PathMatchingResourcePatternResolver</em> class to search the classpath for a resource:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">  PathMatchingResourcePatternResolver pmrl <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> PathMatchingResourcePatternResolver<span style="color: #009900;">&#40;</span>context.<span style="color: #006633;">getClassLoader</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  Resource<span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> resources <span style="color: #339933;">=</span> pmrl.<span style="color: #006633;">getResources</span><span style="color: #009900;">&#40;</span>
    <span style="color: #0000ff;">&quot;classpath*:/net/crazymcphee/dynamiccontext/*/Crazy*DynamicContext.xml&quot;</span>
  <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Looking at the Spring 2.5.6 source code we found that the String passed to the <em>getResources()</em> method isn&#8217;t a proper regular expression, which is a pity. So you can&#8217;t do something like look for <em>**/Crazy*DynamicContext.xml</em> and expect to match a file <em>Crazy*DynamicContext.xml</em> in any package. Also we found that it had to prefixed with that <em>classpath*:</em> &#8230; yes, the asterix, literally &#8230; else it wouldn&#8217;t search the classpath, as opposed to the file path. So we&#8217;re restricted in the above example to a file called <em>Crazy&lt;something&gt;DynamicContext.xml </em>in a package exactly one deep from <em>net.crazymcphee.dynamiccontext</em> &#8230; e.g. <em>net.crazymcphee.dynamiccontext.package.CrazyMcpheeDynamicPackage.xml</em> matches but <em>net.crazymcphee.dynamiccontext.package.sub.CrazySubDynamicPackage.xml </em>and <em>net.crazymcphee.dynamiccontext.CrazySuperDynamicPackage.xml </em>do not. Therefore we will have a restriction on what package the dynamic context can be in and what it&#8217;s name will be. I don&#8217;t think that&#8217;s too onerous on our developers &#8211; we just have to pick a sensible standard.</p>
<p>The next part of the problem is that we have to load the &#8216;Resource&#8217; thus found into a Spring context. This is pretty easy:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"> <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>Resource r <span style="color: #339933;">:</span> resources<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
   GenericApplicationContext createdContext <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> GenericApplicationContext<span style="color: #009900;">&#40;</span>context<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   XmlBeanDefinitionReader reader <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> XmlBeanDefinitionReader<span style="color: #009900;">&#40;</span>createdContext<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> reader.<span style="color: #006633;">loadBeanDefinitions</span><span style="color: #009900;">&#40;</span>r<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
 <span style="color: #009900;">&#125;</span></pre></div></div>

<p>The<em> int i</em> will be set to the number of beans found in the <em>createdContext</em>. The <em>createdContext</em> will have the original <em>context</em> as its parent context, so it can gain access to any beans defined there (and also, although we are yet to test this (!), it should also be intercepted by the AOP-based transaction interceptors in the parent, and so forth).</p>
<p>The only other part of the puzzle may be to query the <em>createdContext</em> to see if it has any target beans within it, luckily for us an ApplicationContext has a method <em>getBeansOfType(Class clazz)</em> which will load all the beans of a particular type:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">  <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span>Resource r <span style="color: #339933;">:</span> resources<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    GenericApplicationContext createdContext <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> GenericApplicationContext<span style="color: #009900;">&#40;</span>context<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    XmlBeanDefinitionReader reader <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> XmlBeanDefinitionReader<span style="color: #009900;">&#40;</span>createdContext<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">int</span> i <span style="color: #339933;">=</span> reader.<span style="color: #006633;">loadBeanDefinitions</span><span style="color: #009900;">&#40;</span>r<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #003399;">Map</span> map <span style="color: #339933;">=</span> createdContext.<span style="color: #006633;">getBeansOfType</span><span style="color: #009900;">&#40;</span>EventHandler.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Object</span> o <span style="color: #339933;">:</span> map.<span style="color: #006633;">keySet</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      EventHandler handler <span style="color: #339933;">=</span> <span style="color: #009900;">&#40;</span>EventHandler<span style="color: #009900;">&#41;</span> createdContext.<span style="color: #006633;">getBean</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#41;</span> o<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #666666; font-style: italic;">// do some programmatic manipulation with the EventHandler that we found here</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span></pre></div></div>

<p>Using these three Spring features will enable us to be able to place a JAR file containing an interface implementation, and a Spring context XML file matching a particular pattern, into the classpath of our WAR, and on restart, we can dynamically pick up the newly inserted features into our application installation. I&#8217;ll report back when we get an actual production prototype together that can do this. Hopefully it will be OK to put the code in the blog too (if we make it generic enough).</p>
<p>If you have any further ideas or refinements to this idea, please leave them in the comments!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.crazymcphee.net/x/2010/04/29/dynamically-loading-spring-contexts-from-the-classpath-at-runtime/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java + WebDAV &#8230; a solution for the PITA</title>
		<link>http://www.crazymcphee.net/x/2010/04/20/java-webdav-a-solution-for-the-pita/</link>
		<comments>http://www.crazymcphee.net/x/2010/04/20/java-webdav-a-solution-for-the-pita/#comments</comments>
		<pubDate>Tue, 20 Apr 2010 06:33:50 +0000</pubDate>
		<dc:creator>Scot Mcphee</dc:creator>
				<category><![CDATA[tools and techniques]]></category>
		<category><![CDATA[apache httpd]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[library]]></category>
		<category><![CDATA[webdav]]></category>

		<guid isPermaLink="false">http://www.crazymcphee.net/x/?p=533</guid>
		<description><![CDATA[Spent the day tooling about with Java web DAV libraries and the Apache httpd server on a Centos machine. First, just let me start by saying that if your webDAV installation on Apache ain&#8217;t working as it should and you&#8217;re on a Redhat-style installation, have a good look at what SELinux is doing. If I&#8217;d [...]]]></description>
			<content:encoded><![CDATA[<p>Spent the day tooling about with Java web DAV libraries and the Apache httpd server on a <a href="http://www.tuxoz.com/2009/10/how-to-setup-webdav-on-centos/" target="_blank">Centos machine</a>. First, just let me start by saying that if your webDAV installation on Apache ain&#8217;t working as it should and you&#8217;re on a Redhat-style installation, have a good look at <a href="http://www.crypt.gen.nz/selinux/disable_selinux.html" target="_blank">what SELinux is doing</a>. If I&#8217;d looked sooner it would have saved me a couple of hours!</p>
<p>But the bigger headache was the Java libraries for handling WebDAV. There is the now-abandoned <a href="http://jakarta.apache.org/slide/" target="_blank">Apache Slide</a>, the based-on-Slide <a href="http://sourceforge.net/projects/webdavclient4j/" target="_blank">webdavclient4j</a>, and the way-more-complex-than-it-needs-to-be <a href="http://jackrabbit.apache.org/" target="_blank">Jackrabbit</a>. Slide and webdavclient4J have the appearance and feel of crusty, molten code from 2004. Jackrabbit is a full-featured <em>server</em> product &#8230; to quote, it is a <em>&#8220;hierarchical content store with support for structured and unstructured  content, full text search, versioning, transactions, observation&#8221;</em> &#8230; and I&#8217;m sure that&#8217;s real nice if that&#8217;s what you want, but I just need to automate push a file onto an Apache HTTPD instance and tell another service what URL it now lives at. It&#8217;s not rocket science. Jackrabbit has too many features, and too little simple documentation, to be truly useful for what I need.</p>
<p>Enter the easy to use WebDAV client, <a href="http://sardine.googlecode.com/">Sardine</a>. Here is the <a href="http://lookfirst.com/2010/01/sardine-very-partial-webdav-client-for.html" target="_blank">author&#8217;s post announcing it</a>.  It&#8217;s very simple to use:</p>
<pre>Sardine sardine = SardineFactory.begin();
List&lt;DavResource&gt; resources = sardine.getResources("http://yourdavserver.com/adirectory/");
for (DavResource res : resources)
{
     System.out.println(res);
}</pre>
<p>Anyway, simplicity &#8230; just the sort of thing I was looking for. Recommended.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.crazymcphee.net/x/2010/04/20/java-webdav-a-solution-for-the-pita/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Glassfish is doomed in the &#8216;department&#8217;</title>
		<link>http://www.crazymcphee.net/x/2010/02/04/glassfish-is-doomed-in-the-department/</link>
		<comments>http://www.crazymcphee.net/x/2010/02/04/glassfish-is-doomed-in-the-department/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 10:25:18 +0000</pubDate>
		<dc:creator>Scot Mcphee</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[infrastructure and frameworks]]></category>
		<category><![CDATA[rants]]></category>
		<category><![CDATA[technical]]></category>
		<category><![CDATA[glassfish]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[Sun]]></category>
		<category><![CDATA[weblogic]]></category>

		<guid isPermaLink="false">http://www.crazymcphee.net/x/?p=508</guid>
		<description><![CDATA[There&#8217;s been lots of discussion the past six months about the fate of MySQL under the ownership of Oracle. Now that the purchase of Sun is complete, I&#8217;m much more concerned about the fate of the excellent JEE platform Glassfish. For example some people think that superior technology will prove to Oracle that Glassfish is [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s been lots of discussion the past six months about the fate of MySQL under the ownership of Oracle. Now that the purchase of Sun is complete, I&#8217;m much more concerned about the fate of the excellent JEE platform <a href="http://glassfish.dev.java.net/">Glassfish</a>. For example some people think that superior technology will prove to Oracle that Glassfish is worth pursuing (see the <a href="http://java.dzone.com/news/oh-yes-sun-not-set-yet">comments on this dZone thread about Kenai.com</a>).</p>
<p>The problem for Glassfish, as <a href="http://www.theserverside.com/news/thread.tss?thread_id=59317">the  second sentence of this ServerSide article states</a> (see it straight from Oracle&#8217;s mouth <a href="http://blogs.sun.com/arungupta/entry/glassfish_strategy_by_oracle_sun">here</a>, and see also <a href="http://www.infoworld.com/d/open-source/oracle-reveals-strategy-glassfish-mysql-openoffice-and-solaris-914">here</a>) is that Oracle  view it as being used for &#8220;non-mission critical department apps&#8221;. Glassfish&#8217;s superior technology (or otherwise) just doesn&#8217;t come into it. It&#8217;s not a factor (as it rarely every is).</p>
<p>Not so long ago Oracle spent a <em>big</em> wad of money acquiring an app server (Weblogic) and then a stack of <em>more</em> money porting all its other products into it and branding the resulting <span style="text-decoration: line-through;">mess</span> platform &#8220;Oracle Fusion Middleware 11g&#8221;. Now not only do they have their <em>third</em> app server (OC4J/OAS, Weblogic and Glassfish), but the Sun product suite includes products that compete with various Fusion Middleware 11g products (portals, ESBs, and so on).   So on one hand you&#8217;ve got a &#8220;departmental&#8221; application server, which you can either licence for free by downloading the open-source version, or buy support for the fancier &#8216;Enterprise&#8217; version, and on the other, an expensive, full-stack-integrated (all the way to the IDE), fully-branded <em>strategic platform</em> that Oracle just invested a vast amount of money into, and have been pushing like crazy onto customers the past six months. And it is the same sales team that will sell both this licensed &#8220;departmental&#8221; Glassfish. Therefore if you say the magic words like &#8220;need a cluster&#8221; or maybe &#8220;we might build a portal&#8221;, or &#8220;we are considering adopting a service-orientated architecture&#8221;, lo and behold you&#8217;ll find the molto-dinero &#8220;Fusion Middleware&#8221; based solution installed all over your sorry arse quicker than you can say &#8220;<em>can you please explain this per-core with special CPU-architecture-loading-factor licencing schema to me once again and why is it a different price if I upgrade my hardware without adding any additional cores???</em>&#8220;.</p>
<p>Let&#8217;s dissect those &#8220;key points&#8221; of Oracle&#8217;s strategy announcement:</p>
<blockquote>
<table cellpadding="10">
<tr>
<th width="50%">
Key Point
</th>
<th width="50%">
What they meant to say
</th>
</tr>
<tr>
</tr>
<tr valign="top">
<td>GlassFish continues as the Java EE reference implementation and as an open source project.</td>
<td>
We see it as the way to dominate the direction of Java EE for at least two years, but for Larry&#8217;s sake don&#8217;t try to use it <em>in production</em>.
</td>
</tr>
<tr valign="top">
<td>Oracle&#8217;s strategic application server, Oracle WebLogic Server, together with GlassFish, provide world class Java EE infrastructure.</td>
<td>
Oracle&#8217;s strategic application server, Oracle WebLogic Server something something something provide world-class something something infrastructure.
</td>
</tr>
<tr valign="top">
<td>GlassFish Enterprise Server and WebLogic Server expected to share core components.</td>
<td>
We are the Borg. Resistance is futile. You will be assimilated.
</td>
</tr>
<tr valign="top">
<td>Oracle plans to add GlassFish Enterprise Server all WebLogic offerings.</td>
<td>
Hey, look at this cute free &#8220;reference implementation&#8221; thingy that comes free with Weblogic! You could use that to run your departmental Wiki instead of having to pay us another fortune for more Weblogic licences. Did you say &#8220;WIKI&#8221;? Did we tell you all about the great wiki-like Enterprise 2.0 features available in the Oracle Fusion Middleware 11g offering? How many test environments did you say you needed licences for?
</td>
</tr>
<tr valign="top">
<td>GlassFish Web Stack maintained for existing customers.</td>
<td>
Not available for sale.
</td>
</tr>
<tr valign="top">
<td>GlassFish Message Queue remains as the GlassFish messaging infrastructure.</td>
<td>
We&#8217;re not expecting to sell any licences of this. Just use Oracle Fusion Middleware&#8217;s SOA Suite 11g already. We&#8217;re fairly sure that&#8217;s got a message queue in it.
</td>
</tr>
<tr valign="top">
<td>Oracle plans to license GlassFish Enterprise Server and Java System Web Server with all WebLogic Server offerings.</td>
<td>
See above.
</td>
</tr>
<tr valign="top">
<td>GlassFish also available as standalone offering.</td>
<td>
Are you sure you didn&#8217;t mean to say &#8220;Weblogic&#8221;? No? Can you call back next Thursday at 2pm and ask for Fred? We&#8217;re reasonably certain he might know something about that Glassthingy.
</td>
</tr>
<tr valign="top">
<td>GlassFish will continue to be supported and maintained for an extended time period for customers current on support.</td>
<td>
Well, the lawyers said we had to. We know how to do this. Ask any 10g customer.
</td>
</tr>
<tr valign="top">
<td>GlassFish open source projects thrive</td>
<td>
As long as we will let them.</td>
</tr>
</table>
</blockquote>
<p>I know I&#8217;m a completely cynical bastard about these things, but I will wager within a few months that even if you deliberately ask for Glassfish Enterprise <em>directly</em> that you&#8217;ll have to fight off the Weblogic borg absolutely <em>tooth and nail to the last man</em> as they repeatedly try to board your IT department brandishing their integrated-wizard-driven <em>Red Stack</em>. I predict that, basically, after a year of not even <em>trying</em> to sell any Glassfish licences &#8211; because if you ask for any of the features that are in the licenced version and not the open-source one, you&#8217;ll be pushed to Weblogic (and anyway, at ten times the price they&#8217;ll prefer to sell you Weblogic as a default position, after all &#8220;Glassfish comes free with Weblogic&#8221;) &#8211; Oracle will announce, &#8220;there&#8217;s no sales in it&#8221;, then probably ditch the licenced Glassfish version completely, leaving only the open source version. Finally sometime after that they&#8217;ll cut the open source funding off and it will have to limp along without hardly any of the resources it formerly had. Maybe they&#8217;ll donate it to the ghetto of an Apache incubator project where it can die unnoticed a couple of years after that.  It&#8217;s a pity because IMHO Glassfish is ten thousand times a better app server than anything Oracle ever produced, or even bought before this.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.crazymcphee.net/x/2010/02/04/glassfish-is-doomed-in-the-department/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>ORM-is-Dead meme</title>
		<link>http://www.crazymcphee.net/x/2009/10/19/orm-is-dead-meme/</link>
		<comments>http://www.crazymcphee.net/x/2009/10/19/orm-is-dead-meme/#comments</comments>
		<pubDate>Mon, 19 Oct 2009 07:31:32 +0000</pubDate>
		<dc:creator>Scot Mcphee</dc:creator>
				<category><![CDATA[architecture]]></category>
		<category><![CDATA[infrastructure and frameworks]]></category>
		<category><![CDATA[technical]]></category>
		<category><![CDATA[tools and techniques]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[dao]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jpa]]></category>
		<category><![CDATA[orm]]></category>
		<category><![CDATA[persistence]]></category>

		<guid isPermaLink="false">http://www.crazymcphee.net/x/?p=488</guid>
		<description><![CDATA[I agree with Stephan, and  Aldo; ORMs increasingly get in the way. Collection mapping is one of those &#8220;hello world&#8221; problems. (The &#8220;hello world&#8221; example in the doco looks totally trivial and completely ideal [which is the problem], but suck-in-the-galaxy-greet-it-and-then-map-all-the-stars problem, which is more like what your real app looks like, is far less than [...]]]></description>
			<content:encoded><![CDATA[<p>I agree with <a href="http://codemonkeyism.com/orms/">Stephan</a>, and  <a href="http://www.hatfulofhollow.com/posts/code/farewell-to-orms.html">Aldo</a>; ORMs increasingly get in the way.</p>
<p>Collection mapping is one of those &#8220;hello world&#8221; problems. (The &#8220;hello world&#8221; example in the doco looks totally trivial and completely ideal [which is the problem], but suck-in-the-galaxy-greet-it-and-then-map-all-the-stars problem, which is more like what your real app looks like, is far less than trivial and not so easily achieved with the demonstrated toolkit). In my experience, collection mapping is the cause of all sorts of pain and performance perfidy.</p>
<p>Here&#8217;s a further situation where I find that they <em>really</em> get in the way. Consider integration with existing systems that use highly-normalised database schemas (designed by advanced SQL programmers who know what they are doing in that language).</p>
<p>This is not an uncommon scenario &#8211; we have this system &#8216;A&#8217; which (let&#8217;s say) has all our customer shipping, product, warehousing data in it. We don&#8217;t want to replace it. But we need to extend it so that e.g. available to web systems. Or maybe it needs to be integrated into the big fancy off-the-shelf CRM we&#8217;re installing. Something like that. We need to build some sort of service layer around this system &#8216;A&#8217; so that other systems can access its data and/or functions. It&#8217;s common to think that an ORM around that big complex database schema is going to help, but in my experience, it doesn&#8217;t for many of the reasons Stephan and Aldo list. That sort of highly-normal database schema in my experiences completely kills ORM object representations stone cold. You end up with so many LazyInitialisationExceptions and various other problems it sucks productivity out the developers and performance out of the system.</p>
<p>Also, I get a bit annoyed about ORM abstractions leaking into the web tier, this is especially prevalent with using annotations rather than ORM mapping files.</p>
<p>Different sorts of approaches are sometimes needed to be applied with careful thought in that scenario. Perhaps you need to model the &#8220;intermediate&#8221; domain you need directly, and then use, for example, simple DAO layers which operate directly on the domain you&#8217;ve defined. These DAO layers then might call functions (stored procs) in the database that do the problematic mapping in an efficent relational language (after all it&#8217;s the direct representation of the target data format).</p>
<p>I&#8217;m not saying that you have to do the above in every case, or that an ORM is always wrong, but anyway the point is, ORM isn&#8217;t a magic bullet like any other technology you have to consider carefully. Your application doesn&#8217;t always need one by default.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.crazymcphee.net/x/2009/10/19/orm-is-dead-meme/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Tapestry 5 web framework</title>
		<link>http://www.crazymcphee.net/x/2009/08/26/tapestry-5-web-framework/</link>
		<comments>http://www.crazymcphee.net/x/2009/08/26/tapestry-5-web-framework/#comments</comments>
		<pubDate>Wed, 26 Aug 2009 12:09:18 +0000</pubDate>
		<dc:creator>Scot Mcphee</dc:creator>
				<category><![CDATA[infrastructure and frameworks]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[technical]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[opensource]]></category>
		<category><![CDATA[tapestry]]></category>
		<category><![CDATA[tapestry5]]></category>
		<category><![CDATA[web]]></category>
		<category><![CDATA[web framework]]></category>

		<guid isPermaLink="false">http://www.crazymcphee.net/x/?p=443</guid>
		<description><![CDATA[Lately I&#8217;ve been writing a Tapestry 5 based web application. I&#8217;ve used it before for a smaller application but this is the first time I&#8217;ve used it on a larger project. In a number of ways it is a very powerful framework to write web applications. The basics of Tapestry is that it is a [...]]]></description>
			<content:encoded><![CDATA[<p>Lately I&#8217;ve been writing a <a href="http://tapestry.apache.org/tapestry5/" target="_blank">Tapestry 5</a> based web application. I&#8217;ve used it before for a smaller application but this is the first time I&#8217;ve used it on a larger project. In a number of ways it is a very powerful framework to write web applications.</p>
<p>The basics of Tapestry is that it is a component-based web framework. Just about everything, including web pages, are components. Components may contain other components. The way it works is very simple and quite elegant, once you get used to it and weaned off the big-XML-file style of configuring a web application.</p>
<p>When you start, you have two main Java packages that are created for you (if you use the maven archetype, otherwise you will create these packages yourself). If your package root is say &#8220;net.crazymcphee.webapp&#8221;, then your two packages are &#8220;net.crazymcphee.webapp.pages&#8221; and &#8220;net.crazymcphee.webapp.components&#8221;. To configure a Tapestry 5 project with maven <a href="http://tapestry.apache.org/tapestry5/quickstart/">use this command</a> and answer the prompts:</p>
<pre>mvn archetype:generate \</pre>
<pre>    -DarchetypeCatalog=http://tapestry.formos.com/maven-snapshot-repository</pre>
<p>Don&#8217;t use the one in the <a href="http://tapestry.apache.org/tapestry5/tutorial1/first.html">tutorial</a> as it will not work! This is an excellent illustration of the first and most serious problem that Tapestry 5 has: the documentation not only has massive lacunas, it is also sometimes wrong and not updated.</p>
<p>Now, any class that you create in the &#8220;pages&#8221; package will automatically become a page in your application. But these classes need not be very complex at all. For example:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">net.crazymcphee.webapp.pages</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.Collections</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.util.List</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.tapestry5.annotations.Persist</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.tapestry5.annotations.Property</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.apache.tapestry5.ioc.annotations.Inject</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">net.crazymcphee.webapp.model.Person</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">net.crazymcphee.webapp.services.PersonService</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> Persons <span style="color: #009900;">&#123;</span>
&nbsp;
    @Inject
    <span style="color: #000000; font-weight: bold;">private</span> PersonService personService<span style="color: #339933;">;</span>
    @Property
    @Persist
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">List</span> persons<span style="color: #339933;">;</span>
    @Property
    @Persist
    <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #003399;">String</span> searchTerm<span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #003399;">Object</span> onSubmitFromSearch<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        persons <span style="color: #339933;">=</span> personService.<span style="color: #006633;">findPersons</span><span style="color: #009900;">&#40;</span>searchTerm<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
    <span style="color: #003399;">Object</span> onSubmitFromClear<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        persons <span style="color: #339933;">=</span> <span style="color: #003399;">Collections</span>.<span style="color: #006633;">EMPTY_LIST</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>You can see that this class doesn&#8217;t extend any infrastructure classes and has quite a simple structure. This is a fully functional page with two actions &#8211; one populates a list, the other clears it.</p>
<p>Now, to explain just a little here; PersonService is injected by Tapestry, but you need to configure in your AppModule which implementation you want to use. You can also use it with Spring as your IOC container but the one that comes with Tapestry is perfectly good enough for most applications.</p>
<p>The List, persons, and the searchTerm parameters are marked as @Property (so we don&#8217;t need to add getters and setters) and also @Persist so that the variables are preserved from request to request.</p>
<p>The methods &#8220;onSubmitFromSearch&#8221; and &#8220;onSubmitFromClear&#8221; are using a convention &#8211; &#8220;onSubmit&#8221; will also work, but assuming (as is true in this case) that we may have multiple forms on the one page, each method will only be fired from the &#8220;search&#8221; form in one instance, and the &#8220;clear&#8221; form in the other. These names are not special, it&#8217;s just (as you&#8217;ll see below) the forms will have these two names. They could be &#8220;Bill&#8221; and &#8220;Ben&#8221; in which case the methods would be &#8220;onSubmitFromBill&#8221; and &#8220;onSubmitFromBen&#8221;.</p>
<p>You will also note that these methods return the same page instance, which tells Tapestry to re-render the same page, but if you wanted to forward onto another page, you would add a instance variable, mark it with an @InjectPage annotation, and return that instance variable (after initialising it in your &#8220;onSubmit&#8221; method) instead of just returning &#8220;this&#8221;.</p>
<p>This page Persons, is available at {application-context-path}/persons. But there is one other part of the puzzle &#8211; the actual view. As mentioned, Tapestry uses convention over configuration and in this case, the convention is that the Page markup must be named the same: Persons.tml. Here is the matching tml file for the class above;</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #2a00ff;"><span style="color: #008080;">&lt;</span><span style="color: #3f7f7f;">html</span><span style="color: #000000;"> </span><span style="color: #7f007f;">t:type</span><span style="color: #000000;">=</span>&#8220;layout&#8221;<span style="color: #000000;"> </span><span style="color: #7f007f;">title</span><span style="color: #000000;">=</span>&#8220;Peoples I Might Know&#8221;</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #7f007f;"><span style="color: #000000;"> </span>t:sidebarTitle<span style="color: #000000;">=</span><span style="color: #2a00ff;">&#8220;Current Time&#8221;</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #2a00ff;"><span style="color: #000000;"> </span><span style="color: #7f007f;">xmlns:t</span><span style="color: #000000;">=</span>&#8220;http://tapestry.apache.org/schema/tapestry_5_1_0.xsd&#8221;</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #2a00ff;"><span style="color: #000000;"> </span><span style="color: #7f007f;">xmlns:p</span><span style="color: #000000;">=</span>&#8220;tapestry:parameter&#8221;<span style="color: #008080;">&gt;</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #3f5fbf;">&lt;!&#8211; Most of the page content, including &lt;head&gt;, &lt;body&gt;, etc. tags, comes from Layout.tml &#8211;&gt;</p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; min-height: 14.0px;">
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; min-height: 14.0px;">
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #2a00ff;"><span style="color: #008080;">&lt;</span><span style="color: #3f7f7f;">t:form</span><span style="color: #000000;"> </span><span style="color: #7f007f;">t:id</span><span style="color: #000000;">=</span>&#8220;search&#8221;<span style="color: #008080;">&gt;</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #2a00ff;"><span style="color: #000000;"> </span><span style="color: #008080;">&lt;</span><span style="color: #3f7f7f;">t:textfield</span><span style="color: #000000;"> </span><span style="color: #7f007f;">t:id</span><span style="color: #000000;">=</span>&#8220;searchTerm&#8221;<span style="color: #000000;"> </span><span style="color: #7f007f;">validate</span><span style="color: #000000;">=</span>&#8220;required&#8221;<span style="color: #000000;"> </span><span style="color: #7f007f;">size</span><span style="color: #000000;">=</span>&#8220;20&#8243;<span style="color: #008080;">/&gt;</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #2a00ff;"><span style="color: #000000;"> </span><span style="color: #008080;">&lt;</span><span style="color: #3f7f7f;">t:submit</span><span style="color: #000000;"> </span><span style="color: #7f007f;">t:id</span><span style="color: #000000;">=</span>&#8220;searchPeople&#8221;<span style="color: #000000;"> </span><span style="color: #7f007f;">value</span><span style="color: #000000;">=</span>&#8220;search&#8221;<span style="color: #008080;">/&gt;</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #3f7f7f;"><span style="color: #008080;">&lt;/</span>t:form<span style="color: #008080;">&gt;</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; min-height: 14.0px;">
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #2a00ff;"><span style="color: #008080;">&lt;</span><span style="color: #3f7f7f;">t:grid</span><span style="color: #000000;"> </span><span style="color: #7f007f;">source</span><span style="color: #000000;">=</span>&#8220;persons&#8221;<span style="color: #008080;">/&gt;</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; min-height: 14.0px;">
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #2a00ff;"><span style="color: #008080;">&lt;</span><span style="color: #3f7f7f;">t:form</span><span style="color: #000000;"> </span><span style="color: #7f007f;">t:id</span><span style="color: #000000;">=</span>&#8220;clear&#8221;<span style="color: #008080;">&gt;</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #2a00ff;"><span style="color: #000000;"> </span><span style="color: #008080;">&lt;</span><span style="color: #3f7f7f;">t:submit</span><span style="color: #000000;"> </span><span style="color: #7f007f;">t:id</span><span style="color: #000000;">=</span>&#8220;clearPeople&#8221;<span style="color: #000000;"> </span><span style="color: #7f007f;">value</span><span style="color: #000000;">=</span>&#8220;clear&#8221;<span style="color: #008080;">/&gt;</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #3f7f7f;"><span style="color: #008080;">&lt;/</span>t:form<span style="color: #008080;">&gt;</span></p>
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; min-height: 14.0px;">
<p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Andale Mono; color: #3f7f7f;"><span style="color: #008080;">&lt;/</span>html<span style="color: #008080;">&gt;</span></p>
<p>Yes, it&#8217;s that bloody simple. The first form fires the &#8220;onSubmitFromSearch&#8221; method (with a little bit of validation, done in javascript) and the second method clears the list. In-between, there is this <span style="color: #008080;">&lt;</span><span style="color: #3f7f7f;">t:grid</span><span style="color: #000000;"> </span><span style="color: #7f007f;">source</span><span style="color: #000000;">=</span>&#8220;persons&#8221;<span style="color: #008080;">/&gt; <span style="color: #000000;">business, which, if the &#8216;persons&#8217; variable in the page class is populated, will show a list of its contents! </span></span></p>
<p>To test our app, we can use the command-line &#8216;mvn clean jetty:run&#8217;. When Jetty has run up, then we can point our browser at the web app: http://localhost:8080/sample-webapp/Persons, and with any luck we will see the following:</p>
<p><a href="http://www.crazymcphee.net/x/wp-content/uploads/2009/08/Picture-1.png"><img style="border: 0px initial initial;" title="Initial View" src="http://www.crazymcphee.net/x/wp-content/uploads/2009/08/Picture-1-300x171.png" alt="Initial View" width="300" height="171" /></a></p>
<p>Now, by default, Tapestry creates the web app to use the template design as shown above. Of course, you can make it look completely some other way &#8211; or even use a totally different template if you want. The page template is just a component that&#8217;s included.</p>
<p>So if you enter in a search term and click the search button, you&#8217;d expect to see a result like this:</p>
<p><a href="http://www.crazymcphee.net/x/wp-content/uploads/2009/08/Picture-2.png"><img class="alignnone size-medium wp-image-452" title="Search Result" src="http://www.crazymcphee.net/x/wp-content/uploads/2009/08/Picture-2-300x174.png" alt="Search Result" width="300" height="174" /></a></p>
<p>As you can see, the list is automatically populated with the details returned from the service method (in this particular instance, this are just a canned response, but normally of course they&#8217;d be the result of a database or a web service call of some type).</p>
<p>When you click the clear button, the list is cleared as you&#8217;d expect:</p>
<p><a href="http://www.crazymcphee.net/x/wp-content/uploads/2009/08/Picture-3.png"><img class="alignnone size-medium wp-image-453" title="Clear button result" src="http://www.crazymcphee.net/x/wp-content/uploads/2009/08/Picture-3-300x175.png" alt="Clear button result" width="300" height="175" /></a></p>
<p>Now, here&#8217;s a really powerful feature I find in Tapestry. Let&#8217;s say our automated acceptance tests assert that when the &#8216;Clear&#8217; button is pressed, the Search box as well as the persons list is cleared. What Tapestry allows us to to do, is keep Jetty running, edit the files in the IDE, and re-run the tests against the running app without restarting! We edit our method:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">    <span style="color: #003399;">Object</span> onSubmitFromClear<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        persons <span style="color: #339933;">=</span> <span style="color: #003399;">Collections</span>.<span style="color: #006633;">EMPTY_LIST</span><span style="color: #339933;">;</span>
        searchTerm<span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;&quot;</span><span style="color: #339933;">;</span>
        <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000000; font-weight: bold;">this</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span></pre></div></div>

<p>In this case I&#8217;ve also added a bit of space around the clear button in the template as well:</p>
<p><a href="http://www.crazymcphee.net/x/wp-content/uploads/2009/08/Picture-4.png"><img class="alignnone size-medium wp-image-454" title="Picture 4" src="http://www.crazymcphee.net/x/wp-content/uploads/2009/08/Picture-4-300x175.png" alt="Picture 4" width="300" height="175" /></a></p>
<p>And now our failing test will pass.</p>
<p>Editing files like this in the running web app only works for Pages and I think Components. If I had to change the service or model classes I&#8217;d have to restart, but &#8220;mvn jetty:run&#8221; isn&#8217;t very a heavyweight process.</p>
<p>As I said above, Tapestry&#8217;s not perfect: it&#8217;s major flaw is the poor documentation. Convention-over-configuration is easy to grok &#8211; if you know the convention. If you don&#8217;t and the documentation doesn&#8217;t tell you, and you can&#8217;t find a sample of what you need, it can be very frustrating. There is an excellent user list though.</p>
<p>Its other major flaw may be the stability of the API. Tapestry 5 is different (and incompatible) from Tapestry 4 is different from Tapestry 3. But so far I&#8217;ve used it on a couple of projects and I&#8217;m really enjoying it. I really hate the oodles of XML boilerplate and massive amounts of configuration found in Spring and I find myself somewhat reluctant to use it unless I really have to. Tapestry solves for me a range of different problems and mostly it presents a very elegant way to create a componentised web application. You might like to give it a try.</p>
<p>Attached is the sample code used above. It took me about 10 minutes to write (far shorter than it took me to write this blog entry!) - <a href="http://www.crazymcphee.net/x/wp-content/uploads/2009/08/sample-webapp.tar.gz">sample-webapp.tar bundle</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.crazymcphee.net/x/2009/08/26/tapestry-5-web-framework/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Oracle to buy Sun &#8230;</title>
		<link>http://www.crazymcphee.net/x/2009/04/20/oracle-to-buy-sun/</link>
		<comments>http://www.crazymcphee.net/x/2009/04/20/oracle-to-buy-sun/#comments</comments>
		<pubDate>Mon, 20 Apr 2009 13:33:04 +0000</pubDate>
		<dc:creator>Scot Mcphee</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[glassfish]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[Sun]]></category>
		<category><![CDATA[wizards considered harmful]]></category>

		<guid isPermaLink="false">http://www.crazymcphee.net/x/?p=329</guid>
		<description><![CDATA[Yes, it&#8217;s true. Oracle and Sun have both announced the marriage. Techcrunch has the full press release. ZDnet some other commentary. A few people seem to be sweating about MySQL. It would not be stressing about MySQL too much. It could get spun off, who knows. It&#8217;s even possible, as some commenters on Techcrunch say, [...]]]></description>
			<content:encoded><![CDATA[<p>Yes, it&#8217;s true. Oracle and Sun have both announced the marriage. <a href="http://www.techcrunch.com/2009/04/20/oracle-to-buy-sun-hold-on-to-your-hats/" target="_blank">Techcrunch</a> has the full press release. <a href="http://blogs.zdnet.com/BTL/?p=16598" target="_blank">ZDnet</a> some other commentary.</p>
<p>A few people seem to be sweating about MySQL. It would not be stressing about MySQL too much. It could get spun off, who knows. It&#8217;s even possible, as some commenters on Techcrunch say, that Oracle might use the free MySQL offering to hammer Microsoft&#8217;s database market from the bottom-up</p>
<p>It&#8217;s more touch-and-go in the app-server market (what Oracle likes to call &#8216;middleware&#8217;) which is already suffering a little from Oracle&#8217;s transition over to BEA Weblogic from its older products. Sun has excellent products in that area, i.e. Glassfish. I have used all of these products (plus Websphere and JBoss) and Glassfish is <em>easily</em> the nicest (in fact I would say it&#8217;s the best app-server I&#8217;ve used, apart from plain old Tomcat).</p>
<p>And what will happen to Java? Of course, Oracle wants Java, that&#8217;s part of the reason they are buying Sun in the first place (as well as their hardware business). But will IBM play along now it&#8217;s most critical competitor owns Java (and IBM has previously bet its software integration farm on the Java stack)? And what of the JCP?</p>
<p>Even more worrying for some, is what will happen in the IDE space. Of course, I&#8217;m a confirmed Eclipse man, but it is always a worry when competition is reduced. What will happen to Netbeans? And dare I say it &#8230; JDeveloper is fairly horrible compared to Netbeans but will that save either of them? Oracle&#8217;s got a lot invested into it&#8217;s tooling, which all runs on JDeveloper. As much as I prefer to just write <em>code</em>, that use <em>wizards</em>, Oracle does seem to have at least some customers in that area. Oracle&#8217;s development model tends to focus a <a href="http://www.crazymcphee.net/x/2009/02/14/gui-builders-modern-development-practices-and-vendor-lock-in/">little too much on magic wizards</a>. From the IDE-JDeveloper-to-the-app-server single click-to-deploy, drag-and-drop to create-the-control, easy-peasy wizardry, which I hate, because I think it gets in the way of <em>craftmanship</em>. It&#8217;s the Bunnings Warehouse of software development. Show me the command-line Oracle! you should remember, that Sun is most definitely a company built around the Unix shell prompt. Even with Oracle middleware, it&#8217;s definitely possible, I&#8217;ve just been working on command-line deployment automation for their older Orion-based app-server, they just don&#8217;t like to promote it.</p>
<p>I&#8217;m hoping that Sun can reverse-ferret them on that score and teach them about <em>Ant</em>, <em>Maven</em>, <em>/bin/sh</em> and the goodness of installations that are as simple as <em>tar xcf </em>in the spot you want to install it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.crazymcphee.net/x/2009/04/20/oracle-to-buy-sun/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>GUI builders, modern development practices, and vendor lock-in</title>
		<link>http://www.crazymcphee.net/x/2009/02/14/gui-builders-modern-development-practices-and-vendor-lock-in/</link>
		<comments>http://www.crazymcphee.net/x/2009/02/14/gui-builders-modern-development-practices-and-vendor-lock-in/#comments</comments>
		<pubDate>Sat, 14 Feb 2009 02:22:34 +0000</pubDate>
		<dc:creator>Scot Mcphee</dc:creator>
				<category><![CDATA[infrastructure and frameworks]]></category>
		<category><![CDATA[rants]]></category>
		<category><![CDATA[technical]]></category>
		<category><![CDATA[tools and techniques]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[IDE]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[methodology]]></category>
		<category><![CDATA[oracle]]></category>
		<category><![CDATA[tools]]></category>
		<category><![CDATA[weblogic]]></category>
		<category><![CDATA[wizards considered harmful]]></category>

		<guid isPermaLink="false">http://www.crazymcphee.net/x/?p=176</guid>
		<description><![CDATA[The Paranoid Engineer has declared &#8216;Screw All Gui Builders&#8216;, with an excellent example of the genre of code that can be produced by one such tool, contrasted against the much nicer hand-written code. Now I can certainly sympathise with his pain. The thing that really gets my goat up, and the subject of this post, [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://paranoid-engineering.blogspot.com/">Paranoid Engineer</a> has declared <a href="http://paranoid-engineering.blogspot.com/2009/02/screw-all-gui-builders.html" target="_blank"><em>&#8216;Screw All Gui Builders</em></a>&#8216;, with an excellent example of the genre of code that can be produced by one such tool, contrasted against the much nicer hand-written code. Now I can certainly sympathise with his pain. The thing that really gets my goat up, and the subject of this post, is when vendors use a GUI builder to lock the poor developer and the target <span style="text-decoration: line-through;">victim</span> sorry, enterprise, into their <em>entire product suite</em>.</p>
<p>My case-in-point <em>du jour</em> is Oracle&#8217;s new <a title="Oracle Rich Enterprise Applications" href="http://rea.oracle.com/" target="_blank">Rich Enterprise Applications</a> site and the associated technology.  On that site you will find a flash presentation of their technology around delivering and I quote:</p>
<blockquote><p>multi-channel capable applications that deliver desktop quality, highly interactive user experiences that are pre-integrated to enterprise class server technology.</p></blockquote>
<p>That sounds pretty good, might be of interest to me. Lets investigate further. Now, a lot this technology is built on top of standards, like JSF, and other commonly used technology like AJAX. The earlier version of the ADF component technology was donated to Apache where it lives as the <a title="Apache Trinidad" href="http://myfaces.apache.org/trinidad/index.html" target="_blank">Apache Myfaces Trinidad</a> project. The new components are built on top of these open sourced components. So far, so much is OK.</p>
<p>But, the kick in the tail can be seen in   even just in the quoted sentence above: <em>&#8220;pre-integrated to enterprise class server technology&#8221;</em> &#8211; they certainly don&#8217;t mean <em>Tomcat</em>, right? The point of the presentation is induce <em>lock in</em>. However I&#8217;m still willing to cut them some slack on this particular point. Of course, if you are thinking about using Oracle&#8217;s JSF technology, you probably are already committed to Oracle&#8217;s middleware technology anyway &#8211; and Weblogic is a perfectly good application server, if you need such advanced capabilities (and whether you actually do is another question for another day).</p>
<p>But what absolutely does my head in, is the insistence the only way to develop for this technology is to write it using their proprietary, non-standard developer technology, aka <em>JDeveloper</em>. This is the point where I have to say, I&#8217;m sorry Oracle, but &#8230; <em><strong>FAIL</strong></em>. <em>I actually don&#8217;t even care if your IDE is even the world&#8217;s best!</em> Or even if it comes as an Eclipse plugin. My beef with this sort of IDE integration is the total mind-set that it embodies. The IDE might have all the <em>drag-and-drop interface-building mojo</em> in all the world, but the code it produces will never, ever, stand up to a hand coded model driven off the target domain, using modern agile development techniques that are designed to ensure the most cost-effective, best-quality development delivering timely business process transformation (aka <em>value</em>) that the enterprise prioritises and chooses. Just look at the <a title="Oracle ADF FAQ" href="http://wiki.oracle.com/page/Oracle+ADF+FAQ?t=anon" target="_blank">ADF FAQ on the Oracle Wiki</a>.  Half the questions are related to the <em>IDE</em>. Here&#8217;s a <a title="Introduction to Oracle's ADF Faces" href="http://java.dzone.com/news/introduction-oracles-adf-faces" target="_blank">tutorial style introduction</a> that just assumes JDeveloper as the default way to get access to the Oracle JDF components.<em> </em></p>
<p><em>No, no a thousand times NO!</em></p>
<p>The biggest insult is the way that developers are treated as mere <em>commodities</em> in this whole process. They are just the warm bodies occupying the chair driving the interface. Much like the continually failed dream of <a title="Programmerless programming is just a mirage" href="http://www.crazymcphee.net/x/2009/01/17/programmerless-programming-is-just-a-mirage/" target="_self">developerless development</a>, their primary skill is seen as not &#8220;being a programmer&#8221; but &#8220;being a driver of a software package&#8221;. If I said, my financial skills and experience include 10 years Excel and 5 years MYOB &#8211; <em>I can haz CFO jobz now</em>? NO?! <em>Why not?</em> It&#8217;s insulting, that&#8217;s why not.</p>
<p>Software development is a profession, or at the very least a <em>craft</em>, and software developers should be able to choose their own tools. Obviously, some agreement has to be made organisationally, or at least across a single team or a whole project, to use a certain common toolset. Here&#8217;s one possible checklist:</p>
<blockquote><p>We&#8217;re writing a Java app, check. Deploying onto Weblogic, check. Database is Oracle 11g, check. We have <a href="http://www.crazymcphee.net/x/tag/scrum/">Scrum</a> as our process framework, check. <a href="http://www.crazymcphee.net/x/tag/test-driven-design/">TDD</a> is in our list of favoured engineering disciplines, check. Maven is our chosen build tool, check. Using Subversion for version control, check. Hudson for a continuous integration server, check. Writing the interface with Oracle ADF, check. Using Crossfire to deliver our web services, check. Spring for application wiring, check. Hibernate for persistence, check.</p></blockquote>
<p>Each of these things has to be agreed upon at an architectural and organisational level (and obviously I don&#8217;t mean to say that each of the above is the only choice for each type of item, I&#8217;m just giving <em>examples</em>).</p>
<p>You should note one very deliberate omission from that list, the IDE. <em>Architects</em> might impose a certain application server, a particular approach to application layering, and so on. The <em>developers</em> &#8211; at least the senior ones &#8211; have to choose and agree, for example, on whether to use Ant or Maven, CVS or SVN, Cruisecontrol or Hudson. But what they do not do, is force developers to favour Eclipse or IntelliJ or Netbeans or JDeveloper. What is the point of taking someone who is super-productive with a particular IDE&#8217;s keystrokes and  then forcing them to spend six months learning a whole new set, a new environment? That&#8217;s not productive! A developer needs to have the IDE <em>get out of the way</em>, become second nature &#8211; they need to be thinking about <em>code</em>, not where the menu is for the rename-method refactoring because they are unfamiliar with the keystrokes of the unfamiliar IDE. Keystrokes are <em>muscle memory</em>. You just think, <em>rename this method</em> and your fingers are already on the keys you need to press, without breaking your all-important <em>flow</em>. That&#8217;s how a developer is as <em>productive</em> as they can be. A productive development team should have a <em>mix</em> of IDEs (I&#8217;d propose that this would be statistically in proportion to the usage patterns of the common IDEs). Then we have the specific example of JDeveloper. I won&#8217;t even go into it except to say I&#8217;ve never heard a developer do anything but <em>curse</em> it, or maybe <em>laugh</em> at it. But it&#8217;s the laughter of the condemned man.</p>
<p>It&#8217;s something that vendors really need to get serious about. Rather than presenting me with a seamlessly integrated vision, from developer&#8217;s screen, through application server, to user&#8217;s screen, their technology presentations ought to think <em>discrete</em>. Each piece of technology ought to live and die on it&#8217;s own merits, something I&#8217;m sure Oracle&#8217;s ADF is perfectly capable of &#8211; without JDeveloper. If it&#8217;s not capable of being developed productively without JDeveloper, it&#8217;s already in the reject pile as far as I am concerned.</p>
<p>This essential information needs to be right up front. Don&#8217;t bury the information a thousand web sites deep in your developer portal. <em>Put it right there in the first presentation!</em> Separate the selling of the developer tooling from the selling of the user presentation frameworks and the server technology. Show me how I integrate Oracle ADF into TDD, into continuous integration, into the IDE of the developer&#8217;s choice. Because if you don&#8217;t, <em>you&#8217;ve already lost me as a potential customer</em>. This is the <em>real</em> future of software development. Look at where the major thought leaders of software development are taking development &#8211; open source frameworks, inversion of control, TDD, Domain Driven Design, Domain Specific Languages, Agile Methods, delivering real process transformation and business capability as early as possible &#8211; not <em>drag and drop with wizards</em>. FFS.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.crazymcphee.net/x/2009/02/14/gui-builders-modern-development-practices-and-vendor-lock-in/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>&#8216;Disappeared&#8217; DAO layers</title>
		<link>http://www.crazymcphee.net/x/2009/02/06/disappeared-dao-layers/</link>
		<comments>http://www.crazymcphee.net/x/2009/02/06/disappeared-dao-layers/#comments</comments>
		<pubDate>Fri, 06 Feb 2009 07:01:18 +0000</pubDate>
		<dc:creator>Scot Mcphee</dc:creator>
				<category><![CDATA[infrastructure and frameworks]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jpa]]></category>
		<category><![CDATA[patterns]]></category>
		<category><![CDATA[persistence]]></category>
		<category><![CDATA[test driven design]]></category>

		<guid isPermaLink="false">http://www.crazymcphee.net/x/?p=139</guid>
		<description><![CDATA[Adam Bien still wants to believe that a JPA layer can directly replace a formal &#8216;DAO layer&#8217;. And I still disagree. I might agree that for simple enough systems, it could end up being that in fact the service layers end up with PersistenceManager logic directly in their methods. But then I might say a [...]]]></description>
			<content:encoded><![CDATA[<p>Adam Bien still wants to believe that a <a href="http://www.adam-bien.com/roller/abien/entry/daos_aren_t_dead_but" target="_blank">JPA layer can directly replace a formal &#8216;DAO layer&#8217;</a>. And I still disagree.</p>
<p>I might agree that for simple enough systems, it could end up being that in fact the service layers end up with PersistenceManager logic directly in their methods. But then I might say a language and framework like Ruby on Rails could suit your application better in that case. For any sufficiently complex Java-based enterprise system, a POJO-style data persistence layer naturally evolves, in order to reduce as far as possible the responsibilities the service layer must carry out.</p>
<p>As mentioned by commentators on his blog, the discipline of test-driven design is usually  a strong driver of having a separated set of components that deal with persistence and other data concerns. Not just from the issue over mocking the PersistenceManager, which is certainly a strong driver, but also from design principles.</p>
<p>Service layers marshall requests from clients, and decompose them to call various component layers. Data access layers typically form part of these component layers. A TDD discipline means these data access layers usually end up with more than just CRUD operations.</p>
<p>Furthermore, as a matter of discipline, in any sufficiently complex service layer I prefer not to work directly with database abstractions (i.e. entities that are modelled on database tables and their relationships) but on first-class objects designed to fit directly with the modelled domain. I want those objects to have rich behaviour &#8211; the service layer is actually part of their behaviour. I want to start the design of the system by directly modelling those actions, e.g.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">passenger.<span style="color: #006633;">at</span><span style="color: #009900;">&#40;</span>origin<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
passenger.<span style="color: #006633;">orderJourney</span><span style="color: #009900;">&#40;</span>dispatch, destination<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
Vehicle vehicle <span style="color: #339933;">=</span> dispatch.<span style="color: #006633;">sendVehicle</span><span style="color: #009900;">&#40;</span>origin<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
vehicle.<span style="color: #006633;">pickUp</span><span style="color: #009900;">&#40;</span>passenger<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
vehicle.<span style="color: #006633;">arrives</span><span style="color: #009900;">&#40;</span>destination<span style="color: #009900;">&#41;</span>.<span style="color: #006633;">dropsOff</span><span style="color: #009900;">&#40;</span>passenger<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
vehicle.<span style="color: #006633;">notify</span><span style="color: #009900;">&#40;</span>dispatch<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>I do not want these objects to know about database semantics. That is a responsibility of a separated persistence layer, which we may for convienience sake, called the DAO. Even if internally we end up with;</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">class</span> Passenger <span style="color: #009900;">&#123;</span>
  at<span style="color: #009900;">&#40;</span>Location origin<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">origin</span><span style="color: #339933;">=</span>origin<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
  call<span style="color: #009900;">&#40;</span>DispatchCentre dispatch, Location destination<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    dispatch.<span style="color: #006633;">passengerOrder</span><span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>, destination<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>DispatchCentre at this level, is a service, but we will model it as part of the domain of passengers, locations, and vehicles. Behind that service, it will have a database layer with the semantics as to how it saves and loads the data concerning passengers, locations, and vehicles. I don&#8217;t necessarily want the client objects (e.g. the web action) to have to deal with JPA annotated objects. They just deal with objects as much as possible. And I don&#8217;t see there&#8217;s anything served with developing possibly complex persistence logic directly in the DispatchCentre. In fact, taking a top-down approach, I know pretty much I won&#8217;t do that.</p>
<p>Only after I&#8217;ve done this initial part of the modelling, will I be concerned as to which of these components can be directly JPA or Hibernate annotated, which are Spring-injected services, which are Session EJBs, and the like. I think starting your modelling from the point of view of having a persistence framework like JPA or Session EJBs or any other &#8216;archtectural artifact&#8217; leads to an unnatural design.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.crazymcphee.net/x/2009/02/06/disappeared-dao-layers/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Is Java &#8220;architecture&#8221; irrelevant?</title>
		<link>http://www.crazymcphee.net/x/2009/01/30/is-java-architecture-irrelevant/</link>
		<comments>http://www.crazymcphee.net/x/2009/01/30/is-java-architecture-irrelevant/#comments</comments>
		<pubDate>Fri, 30 Jan 2009 02:51:48 +0000</pubDate>
		<dc:creator>Scot Mcphee</dc:creator>
				<category><![CDATA[infrastructure and frameworks]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://www.crazymcphee.net/x/?p=113</guid>
		<description><![CDATA[Simon Mittag says that Java Architecture is becoming irrelevant. I am now a contractor for a large government organisation and as part of my role there, I get to participate in these workshops. Trust me, a fruitless exercise. People bickering about their favourite frameworks, why to use Axis over Spring-WS, why everyone should use maven [...]]]></description>
			<content:encoded><![CDATA[<p>Simon Mittag <a title="simonsays: The Growing Irrelevance of Java Architecture" href="http://simonsayz.blogspot.com/2009/01/growing-irrelevance-of-java.html" target="_blank">says that Java Architecture is becoming irrelevant</a>.</p>
<blockquote><p>I am now a contractor for a large government organisation and as part of my role there, I get to participate in these workshops. Trust me, a fruitless exercise. People bickering about their favourite frameworks, why to use Axis over Spring-WS, why everyone should use maven style dependency management, maven is the devil, etc, etc.</p></blockquote>
<p>Well, this has been a problem in Java circles for a long time now. I think we are learning to live with it. But what I don&#8217;t clearly see is its full relevance to Java &#8220;architecture&#8221;.</p>
<p>In my view, architecture is an independent set of constraints on the selection of the requisite frameworks; but the selection of the frameworks isn&#8217;t itself  an archiecture, nor necessarily an architectural task. In my view, achitecture is the view that says, &#8220;this is a web service&#8221; or maybe in more detail: &#8220;these are five components &#8216;C&#8217; {Ca, Cb, Cc, Cd, Ce} having responsibilities &#8216;R&#8217; {Ra, Rb, Rc, Rd, Rd} and they communicate via an asynchronous messaging bus in message formats &#8216;M&#8217; {M1, M2, M3}&#8221;. The actual selection of the frameworks to accomplish this just should <em>not</em> be charged to a committee &#8211; ideally the developers should do it, with appropriate guidance from the relevant architect (who should be on the development team anyway).</p>
<p>Of course this proliferation of frameworks and standards to get this stuff done can lead such committees up the proverbial garden path. But, and without being privy to the full scope of the particular organisation Simon refers to, the essential problem I see here is the <em>function of the committee</em> &#8211; it&#8217;s just compounded by the additional issue of choice, and for some, those choices have inevitably become <em>religious</em>, making the said committee even more dysfunctional. Some would argue the proliferation of frameworks is something that makes Java <em>stronger</em>. There&#8217;s a marketplace in frameworks. But we all know about <em>design by committee</em>, don&#8217;t we?</p>
<p>That said, a lot &#8216;standards&#8217; (even the JSR standards) are indeed irrelevant and out of date, as <a title="JSR286 and vendor sales" href="http://www.crazymcphee.net/x/2009/01/25/jsr286-and-vendor-sales/" target="_self">I pointed out only a few days ago</a>.</p>
<p>In closing his blog entry, Simon leaves us with a question:</p>
<blockquote><p>In closing, do you think JEE can be saved from becoming the next dinosaur?</p></blockquote>
<p>Well, that, of course, is the million dollar question for a Java programmer isn&#8217;t it? Myself, I just prefer to get down and dirty and into the writing of the code &#8211; the business objects &#8211; that encapsulate the domain at hand. If we can&#8217;t just naturally select an uncontroversial framework to enable some segment of the desired infrastructure, then the best thing I find is to use your process, or more appropriately, your <em>design</em>, to just route around the controversy. But the best position is just not to be in that position anyway. Unless the chosen framework absolutely prevents you from doing something you <em>absolutely need</em> to do, you&#8217;re not quite in a pile of stinking do-do just yet.</p>
<p>And if your architecture committee is bogged down in arguing about framework selection, then I&#8217;ll tell you your real problem is is your <em>committee</em>, not the <em>frameworks</em>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.crazymcphee.net/x/2009/01/30/is-java-architecture-irrelevant/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Open source and profits</title>
		<link>http://www.crazymcphee.net/x/2009/01/29/open-source-and-profits/</link>
		<comments>http://www.crazymcphee.net/x/2009/01/29/open-source-and-profits/#comments</comments>
		<pubDate>Thu, 29 Jan 2009 05:30:28 +0000</pubDate>
		<dc:creator>Scot Mcphee</dc:creator>
				<category><![CDATA[business]]></category>
		<category><![CDATA[infrastructure and frameworks]]></category>
		<category><![CDATA[glassfish]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[opensource]]></category>
		<category><![CDATA[Sun]]></category>

		<guid isPermaLink="false">http://www.crazymcphee.net/x/?p=108</guid>
		<description><![CDATA[Sun&#8217;s sales topped estimates, according to Bloomberg, and this was all thanks to its open source software strategy, according to Matt Asay at CNET: Sun Microsystems is getting some love from Wall Street after its sales and earnings topped estimates, as detailed by Bloomberg. Software sales jumped 21 percent year-over-year. What is fueling the growth? [...]]]></description>
			<content:encoded><![CDATA[<p>Sun&#8217;s sales topped estimates, according to <a title="Bloomberg's report on Sun's result" href="http://www.bloomberg.com/apps/news?pid=20601087&amp;sid=aTpPkrKPME1g&amp;refer=home" target="_blank">Bloomberg</a>, and this was all thanks to its <em>open source software strategy</em>, according to Matt Asay at CNET:</p>
<blockquote><p>Sun Microsystems is getting some love from Wall Street after its sales and earnings topped estimates, as detailed by Bloomberg. Software sales jumped 21 percent year-over-year.</p>
<p>What is fueling the growth? The same thing that Sun CEO Jonathan Schwartz has doggedly said would lift Sun&#8217;s fortunes again: open source.</p>
<p>via <a href="http://news.cnet.com/8301-13505_3-10152077-16.html#">Open source makes Sun&#8217;s quarter shine | The Open Road &#8211; CNET News</a>.</p></blockquote>
<p>If this approach is validated going forward the next year or two, will it change the software industry radically? Quite possibly. Remember this is not a five-man company selling training and consultancy services leveraged off it&#8217;s founders&#8217; successful open source software effort, nor even a much larger company set up solely to market and sell services and support contracts based around packaged open source distributions. Sun is a <em>big vendor</em>, which has had to turn its ship of business around almost 180 degrees to get where it&#8217;s going now. And maybe, just <em>maybe</em>, it&#8217;s on a winning course now.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.crazymcphee.net/x/2009/01/29/open-source-and-profits/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
