<?xml version="1.0"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://purl.org/rss/1.0/">

  <channel rdf:about="http://blog.maxant.co.uk:80/pebble/">
    <title>Kitchens in the Zoo</title>
    <link>http://blog.maxant.co.uk:80/pebble/</link>
    <description>&lt;small&gt;A blog where Ant writes about anything he finds interesting! &lt;a href=&#039;http://www.linkedin.com/in/maxant&#039;&gt;&lt;font color=&#039;white&#039;&gt;Who is Ant?&lt;/font&gt;&lt;/a&gt;      &lt;a href=&#039;/pebble/pages/copyright.html&#039;&gt;&lt;font color=&#039;white&#039;&gt;Copyright 2005-2010 Ant Kutschera&lt;/font&gt;&lt;/a&gt;&lt;/small&gt;</description>
    <items>
      <rdf:Seq>
        
        <rdf:li resource="http://blog.maxant.co.uk:80/pebble/2010/09/01/1283371140000.html" />
        
        <rdf:li resource="http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html" />
        
        <rdf:li resource="http://blog.maxant.co.uk:80/pebble/2010/08/01/1280691540000.html" />
        
        <rdf:li resource="http://blog.maxant.co.uk:80/pebble/2010/05/16/1274017800000.html" />
        
        <rdf:li resource="http://blog.maxant.co.uk:80/pebble/2010/05/15/1273933560000.html" />
        
      </rdf:Seq>
    </items>
  </channel>

  
  <item rdf:about="http://blog.maxant.co.uk:80/pebble/2010/09/01/1283371140000.html">
    <title>How Brontosaurs kill Raptors</title>
    <link>http://blog.maxant.co.uk:80/pebble/2010/09/01/1283371140000.html</link>
    
      
        <description>
          &lt;p&gt;The board of a large organisation appoints a CIO who delegates technical decisions to his employees.  In the Enterprise Architecture (EA) department, an expert on Business Intelligence (BI) decides that the strategy for this company is to have a single Enterprise Data Warehouse (EDW).  This makes sense, because experience has shown that in the long run, it is cheaper and more efficient to build one Data Warehouse, rather than start by building &amp;quot;islands&amp;quot; and then later try to merge them together.&lt;br /&gt;
&lt;br /&gt;
In the mean time, some business people working for the company have rallied the budget holders, and started a project to build a new online sales application.  They need to generate some reports based on the sales from this application, in order to set themselves targets and measure their performance.  But, they are not experts when it comes to reporting.  The business sector at which their application is aimed is cutting edge and brand new, so they don&#039;t know what to expect, they don&#039;t really know what kind of reports they will need, and they will certainly need to adapt to the market very quickly.&lt;br /&gt;
&lt;br /&gt;
A project team in the IT department then get the assignment to build the application, including the report generation.  Also knowing little about reporting, they start talking to EA, who set up a meeting, between themselves, the development team, some people from the Quality Assurance (QA) department and some experts from the BI team.  Hours of discussion later, they have made the following conclusions:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Company IT Strategy states all reporting must be implemented in the BI solution, to ensure there is only one EDW,&lt;/li&gt;
    &lt;li&gt;The BI team are the only experts of the BI system,&lt;/li&gt;
    &lt;li&gt;The BI team cost a lot, because they are using SAP and consultants (how many SAP guys aren&#039;t freelance?),&lt;/li&gt;
    &lt;li&gt;The BI team dictate a six monthly release cycle, no exceptions,&lt;/li&gt;
    &lt;li&gt;The BI system is a black box, its inner workings stay secret within the BI team.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;br /&gt;
So, a simple question arises...  &amp;quot;Our customer doesn&#039;t know exactly what they want, and because of their business requirements, they need us to be agile.  What do we do and can the BI team help?&amp;quot;, the development team ask.  The first answer skirts around the issue and doesn&#039;t actually deserve being called an answer, because it doesn&#039;t &lt;i&gt;answer&lt;/i&gt; the question.  The development team make the point that the question hasn&#039;t been addressed, to which another attempt to avoid the question is made.  Clearly, either these people don&#039;t understand their businesses needs, or they know they can&#039;t help but won&#039;t admit it.  Either way, the debate moves on.&lt;br /&gt;
&lt;br /&gt;
Days later, the business guys are telling some colleagues about their cool new project over an espresso and a latte.  &amp;quot;Hee hee hee, hoo hoo hoo...&amp;quot;, laugh their colleagues.  &amp;quot;We thought our reports would let us track our progress too, but the IT department screwed us over.  They charged us double and delivered nothing useful.  We tried to submit some change requests to get it working and all the IT department wanted was more money and they couldn&#039;t deliver the changes quick enough anyway!&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The cool business dudes ran over to the IT office, informed their development team about the new information and said, &amp;quot;Guys, we don&#039;t want you to use BI.  Well not for the first release anyway.  Maybe in a year or two.  Sure, it&#039;s policy and all, but we don&#039;t know what we want, and need to gain some experience, so just hack those reports out within budget please!&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
So the development team arrange another meeting with the &lt;strike&gt;astronauts&lt;/strike&gt; EAs and QAs to get that unanswered question answered, and they talk about the customers concerns.  Even if it&#039;s an over reaction, the point is, that another department needs to be involved meaning more communication, less visibility and hence greater costs and risks.  &amp;quot;Sure, no problem if the requirements are stable and known, but this project needs agility&amp;quot;, is the point the dev team makes.  &amp;quot;Well, no, not a chance!&amp;quot;, comes the response.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;In fact,&amp;quot; they continue, &amp;quot;you simply need to go back to the business and tell them that their idea is an architecture infringement - it goes against company policies.  You won&#039;t pass QA, you won&#039;t get the go ahead to go into production, and that&#039;s the end of it&amp;quot;, comes the reply.&lt;br /&gt;
&lt;br /&gt;
A solution oriented response indeed...  &amp;quot;Furthermore,&amp;quot; continues an EA, &amp;quot; the business doesn&#039;t have the right to come into our shop and tell us where to implement things and where not to.  We are the experts in the technology domain.  We make these choices.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
Well, his argument is that the business hired the CIO, who delegated responsibility to a BI expert, who created a non-agile policy.  So the business have to swallow the argument and accept that the IT department is shit and won&#039;t give them solutions which they need, to compete in new markets...  I&#039;m not sure he realises that this is his argument, but it is, if you look at it pragmatically.&lt;br /&gt;
&lt;br /&gt;
I&#039;m not sure the cool business dudes see it that way either.  I know I don&#039;t see it that way.  And I know of no solution oriented architect or developer who sees it that way.&lt;br /&gt;
&lt;br /&gt;
Of course I understand the reasons we have EA, QA, Processes and Policies.  For large organisations they are the only way to avoid utter chaos, amongst many other reasons.  Most of my working life has been spent with large organisations, even though in many cases I was allowed to implement agile solutions.  But, after a long day in the office, with some frustrating decisions, I need to rant, so here is my cynical view of EA, QA, Processes and Policies, albeit somewhat harsh: these are all things which get bigger, the larger a company is, and all things which let people hide behind their responsibility of providing the business with the solutions they need.  They all cause large corporations to be compared to large dinosaurs.  These departments seem to have forgotten one golden rule: if the business fails, those departments won&#039;t exist.  In competitive markets like we have today, businesses, no matter how large, need to stay competitive, and they can do so by using IT departments which are able to deliver agile solutions.  These departments also often remind me of self-perpetuating &lt;a target=&#034;_blank&#034; href=&#034;http://www.amazon.co.uk/Witch-Doctors-Management-Saying-Matters/dp/074932645X&#034;&gt;witch doctors (The Witch Doctors, ISBN 074932645X)&lt;/a&gt;.  They justify themselves by stating that the business learned the hard way and now that they have been built up they cannot possibly be removed or have power taken away, like we some how never managed to go live before they existed, or that small companies can&#039;t exist because they don&#039;t have them.&lt;br /&gt;
&lt;br /&gt;
Copyright &amp;copy; Ant Kutschera&lt;/p&gt;&lt;div class=&#034;tags&#034;&gt;&lt;span&gt;Social Bookmarks : &lt;/span&gt;&amp;nbsp;&lt;a href=&#034;http://slashdot.org/bookmark.pl?url=http://blog.maxant.co.uk:80/pebble/2010/09/01/1283371140000.html&amp;amp;title=How+Brontosaurs+kill+Raptors&#034; target=&#034;_blank&#034; title=&#034;Add this post to Slash Dot&#034;&gt;&lt;img src=&#034;common/images/slashdot.png&#034; alt=&#034;Add this post to Slashdot&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://digg.com/submit?url=http://blog.maxant.co.uk:80/pebble/2010/09/01/1283371140000.html&amp;amp;title=How+Brontosaurs+kill+Raptors&#034; target=&#034;_blank&#034; title=&#034;Digg this post&#034;&gt;&lt;img src=&#034;common/images/digg.png&#034; alt=&#034;Add this post to Digg&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://reddit.com/submit?url=http://blog.maxant.co.uk:80/pebble/2010/09/01/1283371140000.html&amp;amp;title=How+Brontosaurs+kill+Raptors&#034; target=&#034;_blank&#034; title=&#034;Add this post to Reddit&#034;&gt;&lt;img src=&#034;common/images/reddit.png&#034; alt=&#034;Add this post to Reddit&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://del.icio.us/post?url=http://blog.maxant.co.uk:80/pebble/2010/09/01/1283371140000.html&amp;amp;title=How+Brontosaurs+kill+Raptors&#034; target=&#034;_blank&#034; title=&#034;Save this post to Del.icio.us&#034;&gt;&lt;img src=&#034;common/images/delicious.png&#034; alt=&#034;Add this post to Delicious&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.stumbleupon.com/submit?url=http://blog.maxant.co.uk:80/pebble/2010/09/01/1283371140000.html&amp;amp;title=How+Brontosaurs+kill+Raptors&#034; target=&#034;_blank&#034; title=&#034;Stumble this post&#034;&gt;&lt;img src=&#034;common/images/stumbleupon.png&#034; alt=&#034;Add this post to Stumble it&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.google.com/bookmarks/mark?op=edit&amp;amp;bkmk=http://blog.maxant.co.uk:80/pebble/2010/09/01/1283371140000.html&amp;amp;title=How+Brontosaurs+kill+Raptors&#034; target=&#034;_blank&#034; title=&#034;Add this post to Google&#034;&gt;&lt;img src=&#034;common/images/google.png&#034; alt=&#034;Add this post to Google&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://technorati.com/faves?add=http://blog.maxant.co.uk:80/pebble/2010/09/01/1283371140000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Technorati&#034;&gt;&lt;img src=&#034;common/images/technorati.png&#034; alt=&#034;Add this post to Technorati&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.bloglines.com/sub/http://blog.maxant.co.uk:80/pebble/2010/09/01/1283371140000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Bloglines&#034;&gt;&lt;img src=&#034;common/images/bloglines.png&#034; alt=&#034;Add this post to Bloglines&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.facebook.com/share.php?u=http://blog.maxant.co.uk:80/pebble/2010/09/01/1283371140000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Facebook&#034;&gt;&lt;img src=&#034;common/images/facebook.png&#034; alt=&#034;Add this post to Facebook&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.furl.net/storeIt.jsp?u=http://blog.maxant.co.uk:80/pebble/2010/09/01/1283371140000.html&amp;amp;t=How+Brontosaurs+kill+Raptors&#034; target=&#034;_blank&#034; title=&#034;Add this post to Furl&#034;&gt;&lt;img src=&#034;common/images/furl.png&#034; alt=&#034;Add this post to Furl&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;https://favorites.live.com/quickadd.aspx?mkt=en-us&amp;amp;url=http://blog.maxant.co.uk:80/pebble/2010/09/01/1283371140000.html&amp;amp;title=How+Brontosaurs+kill+Raptors&#034; target=&#034;_blank&#034; title=&#034;Add this post to Windows Live&#034;&gt;&lt;img src=&#034;common/images/windowslive.png&#034; alt=&#034;Add this post to Windows Live&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://bookmarks.yahoo.com/toolbar/savebm?opener=tb&amp;amp;u=http://blog.maxant.co.uk:80/pebble/2010/09/01/1283371140000.html&amp;amp;t=How+Brontosaurs+kill+Raptors&#034; target=&#034;_blank&#034; title=&#034;Add this post to Yahoo!&#034;&gt;&lt;img src=&#034;common/images/yahoo.png&#034; alt=&#034;Add this post to Yahoo!&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&lt;/div&gt;
        </description>
      
      
    
  </item>
  
  <item rdf:about="http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html">
    <title>Persistent State Machine with Apache SCXML</title>
    <link>http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html</link>
    
      
        <description>
          The source code for this blog article can be downloaded &lt;a href=&#039;/pebble/files/SCXMLDemo2.zip&#039;&gt;here&lt;/a&gt;.&lt;br&gt;
&lt;br&gt;
I&#039;m bored of reinventing the wheel.  Everytime I need a state machine to ensure my states traverse only valid transitions, I find myself either not bothering, because I trust my coding (and write all the necessary unit tests of course), or writing very similar code over again.&lt;br&gt;
&lt;br&gt;
So I started wondering if there was a configurable state machine out there somewhere, and in no time at all Google gave me a link to &lt;a target=&#039;blank&#039; href=&#039;http://commons.apache.org/scxml/&#039;&gt;SCXML from Apache&lt;/a&gt;.  Apache SCXML is an implementation of a configurable state machine based on the &lt;a target=&#039;_blank&#039; href=&#039;http://www.w3.org/TR/scxml/&#039;&gt;SCXML working draft&lt;/a&gt; from W3C.&lt;br&gt;
&lt;br&gt;
I started by taking a look at what it does and how it works, always keeping in mind my requirements based on previous projects.  The main question was how I could use a state machine in a persistent entity so that when an attempt is made to change the state, the state machine validated the attempt, ensuring only valid transitions are carried out.  That meant two things:&lt;br&gt;
&lt;ul&gt;
	&lt;li&gt;The state machine had to be able to have its current state set to any state.  If I load an object
		with state out of the database, I need to be able to set that state in the state machine so that 
		it checks any attempts to change state, based on this starting state.&lt;/li&gt;
	&lt;li&gt;The state machine had to fit into a JPA entity class so that I could persist and load the state.&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
Apache SCXML doesn&#039;t come with great documentation but if you look around, it has some &#034;use cases&#034; which are examples of how you can use it.  It comes with the class org.apache.commons.scxml.env.AbstractStateMachine which uses reflection to trigger transitions.  I went for a slightly different approach and created the uk.co.maxant.demo.scxml.util.AbstractStateMachine, which wraps an instance of the SCXMLExecutor (the &#034;engine&#034;, or state machine itself).  By wrapping the state machine, I am able to provide two extra benefits:&lt;br&gt;
&lt;ul&gt;
	&lt;li&gt;I can construct the state machine using the starting state out of a persisted entity, rather than 
		being forced to use the state charts initial state.  The implementation details of this construction 
		are a little complicated so my abstract wrapper can hide the details from the caller who is more
		interested in writing some business code, rather than boiler plate code.&lt;/li&gt;
	&lt;li&gt;I can enforce only valid state transitions, in that before performing a transition, I can use the
		state machine to check if its a valid transition from the current state.  Apache SCXMLs default 
		handling means that if you try to set the state to an illegal state, the state machine simply does
		nothing.  I prefer to be a little harsher and throw an IllegalStateException!&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
The implementation of the AbstractStateMachine contains trigger methods for changing state via transition events.  Each event makes a simple call to the &lt;code&gt;AbstractStateMachine.trigger(String)&lt;/code&gt; method which first of all checks that the current state allows the transition, and second of all delegates the transition to the wrapped state machine instance.  If the requested state transition is illegal, then an &lt;code&gt;IllegalStateException&lt;/code&gt; with details of the problem is thrown.  I too, could have also used reflection like the Apache example, but prefer to write more readable code for this Blog.&lt;br&gt;
&lt;br&gt;
Apache SCXML is built up by creating an &lt;code&gt;SCXML&lt;/code&gt; instance which is based upon the configuration which is an XML representation of the state chart and can be generated from UML.  As such, this configuration has an initial state, as defined in your state chart.  You then create an instance of the engine (state machine, &lt;code&gt;SCXMLExecutor&lt;/code&gt;) which is responsible for running with the configuration.  For performance reasons, the configuration should only be created once, as it parses the XML document.  In my demo, I instantiated it at class load time in the subclass of &lt;code&gt;AbstractStateMachine&lt;/code&gt;.&lt;br&gt;
&lt;br&gt;
So what do you do, if you are loading an object from a persistent store like a database and you want to instantiate your state machine (&lt;code&gt;SCXMLExecutor&lt;/code&gt;) with a state other than the initial state?  Well, it&#039;s quite easy, you simply use the API to modify the current state of the state machine (&lt;code&gt;SCXMLExecutor&lt;/code&gt;) instance and set the initial state to be that, which your persisted entity currently has.  The method isn&#039;t &lt;code&gt;setCurrentState()&lt;/code&gt;, rather you use the current state object, and remove its states and set the relevant state which you retrieved from the configuration (&lt;code&gt;SCXML&lt;/code&gt;).  Have a look at &lt;code&gt;AbstractStateMachine.setInitialState(SCXMLExecutor, String)&lt;/code&gt; to see how.  Thanks to the SCXML team for showing me how to do this!&lt;br&gt;
&lt;br&gt;
So having done all that, I was now in a position to use the state machine to manage the state in a persistent entity.  I created a database table with a &lt;code&gt;varchar&lt;/code&gt; column for holding my state, and primary key.  In the real world, the state would be part of a much larger entity with other fields.  I then setup my Eclipse project to contain the JPA facet and by right clicking on the project was able to generate my JPA entity classes from the table, such as shown in the &lt;code&gt;SomethingPersistentWithState&lt;/code&gt; class.  The only special thing I did, was to select &#034;property based access&#034; as the way in which JPA accesses the attributes.  Normally, and by default, JPA uses field based access, i.e. it uses reflection at runtime to get and set the class attributes.  By selecting &#034;property based access&#034;, Eclipse generates an additional Annotation on my entity class: &lt;code&gt;@Access(AccessType.PROPERTY)&lt;/code&gt;.  I then had only three things to do:&lt;br&gt;
&lt;ul&gt;
	&lt;li&gt;Change the &#034;state&#034; class attribute from a &lt;code&gt;String&lt;/code&gt; into an instance of
		&lt;code&gt;StateMachineDemo&lt;/code&gt;, which is the implementation of &lt;code&gt;AbstractStateMachine&lt;/code&gt;.
		I can do this, because the above Annotation means that JPA doesn&#039;t care how I implement the 
		attribute, is will always use bean conform accessors to set/get the state of my entity, namely the
		&lt;code&gt;String getState()&lt;/code&gt; and &lt;code&gt;void setState(String)&lt;/code&gt; methods.&lt;/li&gt;
	&lt;li&gt;Change the generated &lt;code&gt;void setState(String)&lt;/code&gt; method visibility to become private, so
		that no one could explicitly set the state of my entity.  The method needs to exist, so that JPA can 
		access the attribute to persist it, but JPA can happily live with the method being private.&lt;/li&gt;
	&lt;li&gt;Add methods for each transition, which simply delegate the call to the state machine.  Users of the 
		persistent entity use these trigger methods to change the state, rather than calling
		&lt;code&gt;void setState(String)&lt;/code&gt; on the entity.&lt;/li&gt;
&lt;/ul&gt;
&lt;br&gt;
These changes are all shown/documented in the &lt;code&gt;StateMachineDemo&lt;/code&gt; class.&lt;br&gt;
&lt;br&gt;
To demonstrate the state machine working, as well as it being used in a persistent environment, have a look at the JUnit test case &lt;code&gt;StateMachineDemoTest&lt;/code&gt;.  This class contains tests for setting any state during construction, tests for state transitions proving that only valid ones are allowed, as well as reading/writing an entity containing state to the database and updating the state along the way.
&lt;br&gt;
&lt;br&gt;
Download the source &lt;a href=&#039;/pebble/files/SCXMLDemo2.zip&#039;&gt;here&lt;/a&gt;.&lt;br&gt;
&lt;br&gt;
&amp;copy; 2010, Ant Kutschera&lt;div class=&#034;tags&#034;&gt;&lt;span&gt;Social Bookmarks : &lt;/span&gt;&amp;nbsp;&lt;a href=&#034;http://slashdot.org/bookmark.pl?url=http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html&amp;amp;title=Persistent+State+Machine+with+Apache+SCXML&#034; target=&#034;_blank&#034; title=&#034;Add this post to Slash Dot&#034;&gt;&lt;img src=&#034;common/images/slashdot.png&#034; alt=&#034;Add this post to Slashdot&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://digg.com/submit?url=http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html&amp;amp;title=Persistent+State+Machine+with+Apache+SCXML&#034; target=&#034;_blank&#034; title=&#034;Digg this post&#034;&gt;&lt;img src=&#034;common/images/digg.png&#034; alt=&#034;Add this post to Digg&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://reddit.com/submit?url=http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html&amp;amp;title=Persistent+State+Machine+with+Apache+SCXML&#034; target=&#034;_blank&#034; title=&#034;Add this post to Reddit&#034;&gt;&lt;img src=&#034;common/images/reddit.png&#034; alt=&#034;Add this post to Reddit&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://del.icio.us/post?url=http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html&amp;amp;title=Persistent+State+Machine+with+Apache+SCXML&#034; target=&#034;_blank&#034; title=&#034;Save this post to Del.icio.us&#034;&gt;&lt;img src=&#034;common/images/delicious.png&#034; alt=&#034;Add this post to Delicious&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.stumbleupon.com/submit?url=http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html&amp;amp;title=Persistent+State+Machine+with+Apache+SCXML&#034; target=&#034;_blank&#034; title=&#034;Stumble this post&#034;&gt;&lt;img src=&#034;common/images/stumbleupon.png&#034; alt=&#034;Add this post to Stumble it&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.google.com/bookmarks/mark?op=edit&amp;amp;bkmk=http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html&amp;amp;title=Persistent+State+Machine+with+Apache+SCXML&#034; target=&#034;_blank&#034; title=&#034;Add this post to Google&#034;&gt;&lt;img src=&#034;common/images/google.png&#034; alt=&#034;Add this post to Google&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://technorati.com/faves?add=http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Technorati&#034;&gt;&lt;img src=&#034;common/images/technorati.png&#034; alt=&#034;Add this post to Technorati&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.bloglines.com/sub/http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Bloglines&#034;&gt;&lt;img src=&#034;common/images/bloglines.png&#034; alt=&#034;Add this post to Bloglines&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.facebook.com/share.php?u=http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Facebook&#034;&gt;&lt;img src=&#034;common/images/facebook.png&#034; alt=&#034;Add this post to Facebook&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.furl.net/storeIt.jsp?u=http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html&amp;amp;t=Persistent+State+Machine+with+Apache+SCXML&#034; target=&#034;_blank&#034; title=&#034;Add this post to Furl&#034;&gt;&lt;img src=&#034;common/images/furl.png&#034; alt=&#034;Add this post to Furl&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;https://favorites.live.com/quickadd.aspx?mkt=en-us&amp;amp;url=http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html&amp;amp;title=Persistent+State+Machine+with+Apache+SCXML&#034; target=&#034;_blank&#034; title=&#034;Add this post to Windows Live&#034;&gt;&lt;img src=&#034;common/images/windowslive.png&#034; alt=&#034;Add this post to Windows Live&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://bookmarks.yahoo.com/toolbar/savebm?opener=tb&amp;amp;u=http://blog.maxant.co.uk:80/pebble/2010/08/26/1282857660000.html&amp;amp;t=Persistent+State+Machine+with+Apache+SCXML&#034; target=&#034;_blank&#034; title=&#034;Add this post to Yahoo!&#034;&gt;&lt;img src=&#034;common/images/yahoo.png&#034; alt=&#034;Add this post to Yahoo!&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&lt;/div&gt;
        </description>
      
      
    
  </item>
  
  <item rdf:about="http://blog.maxant.co.uk:80/pebble/2010/08/01/1280691540000.html">
    <title>Waffle Theorem</title>
    <link>http://blog.maxant.co.uk:80/pebble/2010/08/01/1280691540000.html</link>
    
      
        <description>
          &lt;p&gt;Eating a waffle, I just developed a new theorem.&amp;nbsp; First assume the waffle is square and made up of little squares.&amp;nbsp; If, like me, you eat around two edges, one square deep, so that the waffle stays square, you ALWAYS eat an odd number of squares.&amp;nbsp; Eg. 6x6, you eat 6 mini squares, follwed by 5, making 11 (odd number), so that the waffle itself stays square, now only 5x5.&amp;nbsp; My theorem hypothesises that this is true for all waffle sizes.&amp;nbsp; In fact it&#039;s called the &amp;quot;Waffle Theorem&amp;quot;, and here is the mathematical proof:&lt;br /&gt;
&lt;br /&gt;
y = x^2 - (x-1)^2&lt;br /&gt;
&lt;br /&gt;
-&amp;gt; y = x^2 - (x^2 - 2x + 1)&lt;br /&gt;
-&amp;gt; y = 2x-1.&lt;br /&gt;
&lt;br /&gt;
QED, because 2 times anything (&amp;quot;2x&amp;quot;)&amp;nbsp;is always even, and subtracting one (&amp;quot;-1&amp;quot;) always makes an even number odd.&amp;nbsp; Hence my hypothesis holds true, regardless of waffle size.&lt;br /&gt;
&lt;br /&gt;
Not bad for a Sunday night, all I wanted to do was eat the damn waffle...&amp;nbsp; I&amp;nbsp;have to say though, it&#039;s this kind of thing that I&amp;nbsp;love about maths.&lt;br /&gt;
&amp;nbsp;&lt;/p&gt;
&lt;p&gt;-----------------&lt;/p&gt;
&lt;p&gt;(c) 2010 Ant Kutschera&lt;/p&gt;&lt;div class=&#034;tags&#034;&gt;&lt;span&gt;Social Bookmarks : &lt;/span&gt;&amp;nbsp;&lt;a href=&#034;http://slashdot.org/bookmark.pl?url=http://blog.maxant.co.uk:80/pebble/2010/08/01/1280691540000.html&amp;amp;title=Waffle+Theorem&#034; target=&#034;_blank&#034; title=&#034;Add this post to Slash Dot&#034;&gt;&lt;img src=&#034;common/images/slashdot.png&#034; alt=&#034;Add this post to Slashdot&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://digg.com/submit?url=http://blog.maxant.co.uk:80/pebble/2010/08/01/1280691540000.html&amp;amp;title=Waffle+Theorem&#034; target=&#034;_blank&#034; title=&#034;Digg this post&#034;&gt;&lt;img src=&#034;common/images/digg.png&#034; alt=&#034;Add this post to Digg&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://reddit.com/submit?url=http://blog.maxant.co.uk:80/pebble/2010/08/01/1280691540000.html&amp;amp;title=Waffle+Theorem&#034; target=&#034;_blank&#034; title=&#034;Add this post to Reddit&#034;&gt;&lt;img src=&#034;common/images/reddit.png&#034; alt=&#034;Add this post to Reddit&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://del.icio.us/post?url=http://blog.maxant.co.uk:80/pebble/2010/08/01/1280691540000.html&amp;amp;title=Waffle+Theorem&#034; target=&#034;_blank&#034; title=&#034;Save this post to Del.icio.us&#034;&gt;&lt;img src=&#034;common/images/delicious.png&#034; alt=&#034;Add this post to Delicious&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.stumbleupon.com/submit?url=http://blog.maxant.co.uk:80/pebble/2010/08/01/1280691540000.html&amp;amp;title=Waffle+Theorem&#034; target=&#034;_blank&#034; title=&#034;Stumble this post&#034;&gt;&lt;img src=&#034;common/images/stumbleupon.png&#034; alt=&#034;Add this post to Stumble it&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.google.com/bookmarks/mark?op=edit&amp;amp;bkmk=http://blog.maxant.co.uk:80/pebble/2010/08/01/1280691540000.html&amp;amp;title=Waffle+Theorem&#034; target=&#034;_blank&#034; title=&#034;Add this post to Google&#034;&gt;&lt;img src=&#034;common/images/google.png&#034; alt=&#034;Add this post to Google&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://technorati.com/faves?add=http://blog.maxant.co.uk:80/pebble/2010/08/01/1280691540000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Technorati&#034;&gt;&lt;img src=&#034;common/images/technorati.png&#034; alt=&#034;Add this post to Technorati&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.bloglines.com/sub/http://blog.maxant.co.uk:80/pebble/2010/08/01/1280691540000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Bloglines&#034;&gt;&lt;img src=&#034;common/images/bloglines.png&#034; alt=&#034;Add this post to Bloglines&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.facebook.com/share.php?u=http://blog.maxant.co.uk:80/pebble/2010/08/01/1280691540000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Facebook&#034;&gt;&lt;img src=&#034;common/images/facebook.png&#034; alt=&#034;Add this post to Facebook&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.furl.net/storeIt.jsp?u=http://blog.maxant.co.uk:80/pebble/2010/08/01/1280691540000.html&amp;amp;t=Waffle+Theorem&#034; target=&#034;_blank&#034; title=&#034;Add this post to Furl&#034;&gt;&lt;img src=&#034;common/images/furl.png&#034; alt=&#034;Add this post to Furl&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;https://favorites.live.com/quickadd.aspx?mkt=en-us&amp;amp;url=http://blog.maxant.co.uk:80/pebble/2010/08/01/1280691540000.html&amp;amp;title=Waffle+Theorem&#034; target=&#034;_blank&#034; title=&#034;Add this post to Windows Live&#034;&gt;&lt;img src=&#034;common/images/windowslive.png&#034; alt=&#034;Add this post to Windows Live&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://bookmarks.yahoo.com/toolbar/savebm?opener=tb&amp;amp;u=http://blog.maxant.co.uk:80/pebble/2010/08/01/1280691540000.html&amp;amp;t=Waffle+Theorem&#034; target=&#034;_blank&#034; title=&#034;Add this post to Yahoo!&#034;&gt;&lt;img src=&#034;common/images/yahoo.png&#034; alt=&#034;Add this post to Yahoo!&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&lt;/div&gt;
        </description>
      
      
    
  </item>
  
  <item rdf:about="http://blog.maxant.co.uk:80/pebble/2010/05/16/1274017800000.html">
    <title>Taking Advantage of Parallelism</title>
    <link>http://blog.maxant.co.uk:80/pebble/2010/05/16/1274017800000.html</link>
    
      
        <description>
          &lt;p&gt;A while ago some colleagues attended a lecture where the presenter introduced the idea that applications may not take full advantage of the multi-core servers which are available today.  The idea was that if you have two cores but a process which is running on a single thread, then all the work is done on one single core.  Application servers help in this respect, because they handle multiple incoming requests simultaneously, by starting a new thread for each request.  So if the server has two cores it can really handle two requests simultaneously, or if it has 6 cores, it can handle 6 requests simultanously.&lt;br /&gt;
&lt;br /&gt;
So multi-core CPUs can help the performance of your server if you have multiple simultaneous requests, which is often the case when your server is running near its limit.  But it&#039;s not often the case that you want your servers running close to the limit, so you typically scale out, by adding more nodes to your server cluster, which has a similar effect to adding cores to the CPU (you can continue to handle multiple requests simultaneously).&lt;br /&gt;
&lt;br /&gt;
So once you have scaled up by adding more cores, and scaled out by adding more servers, how can you improve performance?&lt;br /&gt;
&lt;br /&gt;
Some processes can be designed to be non-serial, especially in enterprise scenarios.  The &lt;a href=&#034;http://en.wikipedia.org/wiki/Multi-core_processor#Software_impact&#034; target=&#034;_blank&#034;&gt;Wikipedia article on multi-core processors&lt;/a&gt; talks about this.  Imagine a process which gathers data from multiple systems while preparing the data which it responds with.  An example would be a pricing system. Imagine your local zoo offered a web service for purchasing individual tickets, say an entrance ticket, a voucher for some tasty elephant snacks for feeding time, a voucher for their shop for getting gifts before you leave, etc.  Now imagine, you as an entrepreneur wanted to open a re-selling business offering packages for such products, so that you could offer a discount (greater sales volume, lower per-item profit).&lt;br /&gt;
&lt;br /&gt;
A perfect way to do this would be to partner with the Zoo and offer a website which integrates with the zoo&#039;s web service and sells such packages. You implement your website, but then while doing performance tests, you notice that regardless of load, an average sales is taking 3 seconds to complete.  You analyse the system and determine that its the zoo&#039;s web service which is the problem - each product quote is taking a full second to get.  You talk to the zoo&#039;s IT department, and they confirm that this is known, but there is little they can do about it because in the back end they are using complex reservation systems which work out a dynamic &lt;a href=&#034;http://en.wikipedia.org/wiki/Market_price&#034; target=&#034;_blank&#034;&gt;market price&lt;/a&gt; which is based on supply and demand.&lt;br /&gt;
&lt;br /&gt;
So, you go away and have a think, and remember that your data center has just just installed some servers with flashy new multi-core processors, which are costing you a fortune.  Then it hits you!  Getting a product quote is an independent task.  So while getting quotes for the items in your package, you might as well do it in parallel, at the same time! Hang on now.  You implemented your system in Java and the business logic is in EJBs, so there&#039;s no chance of spawning new threads, the container won&#039;t let you! Except... you implemented it on a shiny new Java EE 6 server!  Hooray!  Why?  Because of the &lt;code&gt;javax.ejb.Asynchronous&lt;/code&gt; annotation.&lt;br /&gt;
&lt;br /&gt;
The Javadocs for this annotation state:&lt;br /&gt;
&lt;br /&gt;
&lt;i&gt;Used to mark a method as an asynchronous method or to designate all business methods of a class or interface as asynchronous.&lt;/i&gt;&lt;br /&gt;
&lt;br /&gt;
So, what you do, is add this annotation to a business method of your EJB and the container runs it on a new thread.  Brilliant!  The only minor issue is how to get the result from your asynchronous calls, but that&#039;s relatively easy, using the &lt;code&gt;Future&amp;lt;T&amp;gt;&lt;/code&gt; class.  Consider the following method declaration:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt; /**&lt;br /&gt;
&amp;nbsp;* note that async methods implicitly start new transactions! &lt;br /&gt;
&amp;nbsp;* see ejb 3.1 spec, chapter 4.5.3.&lt;br /&gt;
&amp;nbsp;*/&lt;br /&gt;
@Override&lt;br /&gt;
@Asynchronous&lt;br /&gt;
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)&lt;br /&gt;
public Future&lt;offer&gt; getOffer(Product product, UUID purchaseId) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;.&lt;br /&gt;
&lt;/offer&gt;&lt;/code&gt; &lt;br /&gt;
This EJB business method takes a product and purchase ID (effectively a session ID).  It gets called by the container on a new thread, which implicitly means that it cannot re-use any existing transactions and must hence be run using a new transaction (see EJB specification, chapter 4.5.3).  This method then calls the zoo&#039;s web service and when it gets a response, returns the response:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return new AsyncResult&lt;offer&gt;(o);&lt;br /&gt;
&lt;/offer&gt;&lt;/code&gt; &lt;br /&gt;
where &amp;quot;o&amp;quot; is an offer - the response from the web service call.  The &lt;code&gt;javax.ejb.AsyncResult&amp;lt;T&amp;gt;&lt;/code&gt; class is the standard implentation of a &lt;code&gt;Future&amp;lt;T&amp;gt;&lt;/code&gt;, and simply wraps the actual object you want to return.&lt;br /&gt;
&lt;br /&gt;
The EJB which started the async calls knows when they have all returned, because it can check the results &lt;code&gt;isDone()&lt;/code&gt; method.  As soon as the new thread completes, the container sets this method to return true.&lt;br /&gt;
&lt;br /&gt;
So, the net effect is that instead of taking three seconds to get an offer for your package of three items, it only takes one second!  A whopping 300% improvement!&lt;br /&gt;
&lt;br /&gt;
The async annotation in the EJB spec is a welcome extension.  If also offers the ability to cancel tasks as well as handle exceptions from the async calls (via &lt;code&gt;ExecutionException&lt;/code&gt;s which wrap the problem).  With it however, there are some dangers, as suggested in the Wikipedia article on multi-core processors.  The fact that such async methods are forced to start a new transaction can cause problems.  However, this is actually an advantage, because we are calling web services!  Web services are inherently non-transactional.  That means they are committed as soon as you get their response, not as soon as your transaction is committed.  So in order to make web services XA (two phase commit) compatible, one normally adds a &amp;quot;commit&amp;quot; method to the web service which the caller must call when all their business logic is complete, or one adds a mechanism for cancelling such transactions.&lt;br /&gt;
&lt;br /&gt;
I have used the new &amp;quot;inner&amp;quot; transaction which the container starts to track the state of these offers / sales.  As soon as the web service returns, I write the result to a table in the database with its status &amp;quot;OFFERED&amp;quot;, so that I know I have not actually purchased it.  Regardless of errors in other calls to the web service, I am guaranteed to have such an entry for each successful web service result, due to the inner transaction.  After I get the three offers, the orchestration EJB which called the async bean (which calls the web services), purchases the three offers.  After each purchase, I update the status in the database to &amp;quot;BOUGHT&amp;quot;, also using an inner transaction (REQUIRES_NEW), so that regardless of any failures in subsequent purchases, the state of individual purchases is known.  Why go to this effort?  Well, I have a business rule: my packages are sold as complete packages, or not at all!  So if any single purchase fails, I need to cancel my other purchases.  If I don&#039;t, I still owe the zoo for what I have purchased, and I didn&#039;t get any money from my customer, because the package failed!&lt;br /&gt;
&lt;br /&gt;
The solution is to use the timer service from the EJB container.  I schedule a method in an EJB to analyse my offers/purchases and for any incomplete session (purchase ID), I cancel all three offers and update my records to mark the purchases as &amp;quot;CANCELLED&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
I&#039;ve put this together as a sample app which includes EJB 3.1, Servlet 3.0, Inteceptors, JPA 2.0, the EJB Timer Service, Validation (JSR-303), JMS and JAX-WS, all based on the GlassFish 3 configuration which was blogged at &lt;a href=&#034;http://blog.maxant.co.uk/pebble/2010/05/08/1273354800000.html&#034;&gt;GlassFish 3 In 30 Minutes&lt;/a&gt;. The source for this mega sample app can be downloaded &lt;a href=&#034;/pebble/files/Seven_Parallelism.zip&#034;&gt;here&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Some final quick notes: &lt;br /&gt;
&lt;br /&gt;
1) A web service, and its client cannot be deployed in the same EAR! That makes sense in normal conditions, but for a sample app, where you want your server to call a test WS, it can cause trouble. So the zoo web service is deployed as a simple web project.&lt;br /&gt;
&lt;br /&gt;
2) The Javadocs for the OrchestrationBean provide some more details of the business process.&lt;br /&gt;
&lt;br /&gt;
&amp;copy; 2010 Ant Kutschera&lt;/p&gt;&lt;div class=&#034;tags&#034;&gt;&lt;span&gt;Social Bookmarks : &lt;/span&gt;&amp;nbsp;&lt;a href=&#034;http://slashdot.org/bookmark.pl?url=http://blog.maxant.co.uk:80/pebble/2010/05/16/1274017800000.html&amp;amp;title=Taking+Advantage+of+Parallelism&#034; target=&#034;_blank&#034; title=&#034;Add this post to Slash Dot&#034;&gt;&lt;img src=&#034;common/images/slashdot.png&#034; alt=&#034;Add this post to Slashdot&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://digg.com/submit?url=http://blog.maxant.co.uk:80/pebble/2010/05/16/1274017800000.html&amp;amp;title=Taking+Advantage+of+Parallelism&#034; target=&#034;_blank&#034; title=&#034;Digg this post&#034;&gt;&lt;img src=&#034;common/images/digg.png&#034; alt=&#034;Add this post to Digg&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://reddit.com/submit?url=http://blog.maxant.co.uk:80/pebble/2010/05/16/1274017800000.html&amp;amp;title=Taking+Advantage+of+Parallelism&#034; target=&#034;_blank&#034; title=&#034;Add this post to Reddit&#034;&gt;&lt;img src=&#034;common/images/reddit.png&#034; alt=&#034;Add this post to Reddit&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://del.icio.us/post?url=http://blog.maxant.co.uk:80/pebble/2010/05/16/1274017800000.html&amp;amp;title=Taking+Advantage+of+Parallelism&#034; target=&#034;_blank&#034; title=&#034;Save this post to Del.icio.us&#034;&gt;&lt;img src=&#034;common/images/delicious.png&#034; alt=&#034;Add this post to Delicious&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.stumbleupon.com/submit?url=http://blog.maxant.co.uk:80/pebble/2010/05/16/1274017800000.html&amp;amp;title=Taking+Advantage+of+Parallelism&#034; target=&#034;_blank&#034; title=&#034;Stumble this post&#034;&gt;&lt;img src=&#034;common/images/stumbleupon.png&#034; alt=&#034;Add this post to Stumble it&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.google.com/bookmarks/mark?op=edit&amp;amp;bkmk=http://blog.maxant.co.uk:80/pebble/2010/05/16/1274017800000.html&amp;amp;title=Taking+Advantage+of+Parallelism&#034; target=&#034;_blank&#034; title=&#034;Add this post to Google&#034;&gt;&lt;img src=&#034;common/images/google.png&#034; alt=&#034;Add this post to Google&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://technorati.com/faves?add=http://blog.maxant.co.uk:80/pebble/2010/05/16/1274017800000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Technorati&#034;&gt;&lt;img src=&#034;common/images/technorati.png&#034; alt=&#034;Add this post to Technorati&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.bloglines.com/sub/http://blog.maxant.co.uk:80/pebble/2010/05/16/1274017800000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Bloglines&#034;&gt;&lt;img src=&#034;common/images/bloglines.png&#034; alt=&#034;Add this post to Bloglines&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.facebook.com/share.php?u=http://blog.maxant.co.uk:80/pebble/2010/05/16/1274017800000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Facebook&#034;&gt;&lt;img src=&#034;common/images/facebook.png&#034; alt=&#034;Add this post to Facebook&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.furl.net/storeIt.jsp?u=http://blog.maxant.co.uk:80/pebble/2010/05/16/1274017800000.html&amp;amp;t=Taking+Advantage+of+Parallelism&#034; target=&#034;_blank&#034; title=&#034;Add this post to Furl&#034;&gt;&lt;img src=&#034;common/images/furl.png&#034; alt=&#034;Add this post to Furl&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;https://favorites.live.com/quickadd.aspx?mkt=en-us&amp;amp;url=http://blog.maxant.co.uk:80/pebble/2010/05/16/1274017800000.html&amp;amp;title=Taking+Advantage+of+Parallelism&#034; target=&#034;_blank&#034; title=&#034;Add this post to Windows Live&#034;&gt;&lt;img src=&#034;common/images/windowslive.png&#034; alt=&#034;Add this post to Windows Live&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://bookmarks.yahoo.com/toolbar/savebm?opener=tb&amp;amp;u=http://blog.maxant.co.uk:80/pebble/2010/05/16/1274017800000.html&amp;amp;t=Taking+Advantage+of+Parallelism&#034; target=&#034;_blank&#034; title=&#034;Add this post to Yahoo!&#034;&gt;&lt;img src=&#034;common/images/yahoo.png&#034; alt=&#034;Add this post to Yahoo!&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&lt;/div&gt;
        </description>
      
      
    
  </item>
  
  <item rdf:about="http://blog.maxant.co.uk:80/pebble/2010/05/15/1273933560000.html">
    <title>GlassFish v3, JSF and Virtual Servers</title>
    <link>http://blog.maxant.co.uk:80/pebble/2010/05/15/1273933560000.html</link>
    
      
        <description>
          &lt;p&gt;Anyone wanting to run a JSF&amp;nbsp;app on GlassFish may run into problems when migrating to production, if they are hosting multiple domains on their servers by using virtual hosts!&lt;/p&gt;
&lt;p&gt;The default deployment, deploys your app to all virtual servers (except _asadmin).&amp;nbsp; If you do that, you get lots of errors, and the app doesn&#039;t run.&lt;/p&gt;
&lt;p&gt;The solution is easy, simply add the --virtualservers argument to the &amp;quot;deploy&amp;quot; command in the &amp;quot;asadmin&amp;quot; console, and supply the relevant virtual server (just the one).&lt;/p&gt;
&lt;p&gt;Hopefully this will get fixed in GFv3.1!&lt;/p&gt;&lt;div class=&#034;tags&#034;&gt;&lt;span&gt;Social Bookmarks : &lt;/span&gt;&amp;nbsp;&lt;a href=&#034;http://slashdot.org/bookmark.pl?url=http://blog.maxant.co.uk:80/pebble/2010/05/15/1273933560000.html&amp;amp;title=GlassFish+v3%2C+JSF+and+Virtual+Servers&#034; target=&#034;_blank&#034; title=&#034;Add this post to Slash Dot&#034;&gt;&lt;img src=&#034;common/images/slashdot.png&#034; alt=&#034;Add this post to Slashdot&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://digg.com/submit?url=http://blog.maxant.co.uk:80/pebble/2010/05/15/1273933560000.html&amp;amp;title=GlassFish+v3%2C+JSF+and+Virtual+Servers&#034; target=&#034;_blank&#034; title=&#034;Digg this post&#034;&gt;&lt;img src=&#034;common/images/digg.png&#034; alt=&#034;Add this post to Digg&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://reddit.com/submit?url=http://blog.maxant.co.uk:80/pebble/2010/05/15/1273933560000.html&amp;amp;title=GlassFish+v3%2C+JSF+and+Virtual+Servers&#034; target=&#034;_blank&#034; title=&#034;Add this post to Reddit&#034;&gt;&lt;img src=&#034;common/images/reddit.png&#034; alt=&#034;Add this post to Reddit&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://del.icio.us/post?url=http://blog.maxant.co.uk:80/pebble/2010/05/15/1273933560000.html&amp;amp;title=GlassFish+v3%2C+JSF+and+Virtual+Servers&#034; target=&#034;_blank&#034; title=&#034;Save this post to Del.icio.us&#034;&gt;&lt;img src=&#034;common/images/delicious.png&#034; alt=&#034;Add this post to Delicious&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.stumbleupon.com/submit?url=http://blog.maxant.co.uk:80/pebble/2010/05/15/1273933560000.html&amp;amp;title=GlassFish+v3%2C+JSF+and+Virtual+Servers&#034; target=&#034;_blank&#034; title=&#034;Stumble this post&#034;&gt;&lt;img src=&#034;common/images/stumbleupon.png&#034; alt=&#034;Add this post to Stumble it&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.google.com/bookmarks/mark?op=edit&amp;amp;bkmk=http://blog.maxant.co.uk:80/pebble/2010/05/15/1273933560000.html&amp;amp;title=GlassFish+v3%2C+JSF+and+Virtual+Servers&#034; target=&#034;_blank&#034; title=&#034;Add this post to Google&#034;&gt;&lt;img src=&#034;common/images/google.png&#034; alt=&#034;Add this post to Google&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://technorati.com/faves?add=http://blog.maxant.co.uk:80/pebble/2010/05/15/1273933560000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Technorati&#034;&gt;&lt;img src=&#034;common/images/technorati.png&#034; alt=&#034;Add this post to Technorati&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.bloglines.com/sub/http://blog.maxant.co.uk:80/pebble/2010/05/15/1273933560000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Bloglines&#034;&gt;&lt;img src=&#034;common/images/bloglines.png&#034; alt=&#034;Add this post to Bloglines&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.facebook.com/share.php?u=http://blog.maxant.co.uk:80/pebble/2010/05/15/1273933560000.html&#034; target=&#034;_blank&#034; title=&#034;Add this post to Facebook&#034;&gt;&lt;img src=&#034;common/images/facebook.png&#034; alt=&#034;Add this post to Facebook&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://www.furl.net/storeIt.jsp?u=http://blog.maxant.co.uk:80/pebble/2010/05/15/1273933560000.html&amp;amp;t=GlassFish+v3%2C+JSF+and+Virtual+Servers&#034; target=&#034;_blank&#034; title=&#034;Add this post to Furl&#034;&gt;&lt;img src=&#034;common/images/furl.png&#034; alt=&#034;Add this post to Furl&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;https://favorites.live.com/quickadd.aspx?mkt=en-us&amp;amp;url=http://blog.maxant.co.uk:80/pebble/2010/05/15/1273933560000.html&amp;amp;title=GlassFish+v3%2C+JSF+and+Virtual+Servers&#034; target=&#034;_blank&#034; title=&#034;Add this post to Windows Live&#034;&gt;&lt;img src=&#034;common/images/windowslive.png&#034; alt=&#034;Add this post to Windows Live&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;a href=&#034;http://bookmarks.yahoo.com/toolbar/savebm?opener=tb&amp;amp;u=http://blog.maxant.co.uk:80/pebble/2010/05/15/1273933560000.html&amp;amp;t=GlassFish+v3%2C+JSF+and+Virtual+Servers&#034; target=&#034;_blank&#034; title=&#034;Add this post to Yahoo!&#034;&gt;&lt;img src=&#034;common/images/yahoo.png&#034; alt=&#034;Add this post to Yahoo!&#034; border=&#034;0&#034; /&gt;&lt;/a&gt;&lt;/div&gt;
        </description>
      
      
    
  </item>
  

</rdf:RDF>
