<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;DkEBQHg_fCp7ImA9WhRVE0Q.&quot;"><id>tag:blogger.com,1999:blog-28383337</id><updated>2012-01-12T13:57:31.644-05:00</updated><category term="TriJUG" /><category term="logging" /><category term="controllers" /><category term="postgres" /><category term="tools" /><category term="news" /><category term="bug" /><category term="bugs" /><category term="soa" /><category term="pngj" /><category term="UI" /><category term="self" /><category term="events" /><category term="service" /><category term="Acegi" /><category term="suse" /><category term="osgi" /><category term="BarCampRDU" /><category term="TDD" /><category term="configuration" /><category term="repost" /><category term="ORM" /><category term="rails" /><category term="beryl" /><category term="portal" /><category term="video" /><category term="WTF" /><category term="thought" /><category term="dot-com" /><category term="POJO" /><category term="jee" /><category term="closures" /><category term="DrWho" /><category term="gaelyk" /><category term="cronjob" /><category term="lego" /><category term="java" /><category term="CSS" /><category term="philosophy" /><category term="jaas" /><category term="joy" /><category term="ideas" /><category term="concurrency" /><category term="computers" /><category term="networking" /><category term="CAS" /><category term="IntellectualProperty" /><category term="interview" /><category term="iPhone" /><category term="desktop" /><category term="build" /><category term="opinion" /><category term="groovy" /><category term="Java5" /><category term="market analysis" /><category term="stolen data" /><category term="design" /><category term="fix" /><category term="tridroid" /><category term="velocity" /><category term="J2EE" /><category term="webflow" /><category term="projectZero" /><category term="talks" /><category term="svn" /><category term="google" /><category term="ruby" /><category term="technology" /><category term="reflection" /><category term="slides" /><category term="wikemo" /><category term="PMD" /><category term="legacy" /><category term="perl" /><category term="quote" /><category term="sofware" /><category term="normalization" /><category term="Oracle" /><category term="DTO" /><category term="woe" /><category term="GORM" /><category term="richUI" /><category term="frameworks" /><category term="evaluation" /><category term="opensource" /><category term="plugin" /><category term="Chicago" /><category term="charity" /><category term="jetty" /><category term="Software Design" /><category term="zen" /><category term="code" /><category term="qrcode" /><category term="software culture" /><category term="repository" /><category term="utopia" /><category term="hack" /><category term="Annotations" /><category term="speaking" /><category term="asType" /><category term="howto" /><category term="hudson" /><category term="tip" /><category term="technical debt" /><category term="filters" /><category term="geocode" /><category term="jsr181" /><category term="fit" /><category term="trick" /><category term="unix" /><category term="administration" /><category term="XFire" /><category term="UNC" /><category term="OLPC" /><category term="questions" /><category term="management" /><category term="beginner" /><category term="SWT" /><category term="install" /><category term="triLUG" /><category term="active directory" /><category term="Software Engineering" /><category term="documentation" /><category term="neural net" /><category term="swing" /><category term="junit" /><category term="projects" /><category term="rdbms" /><category term="pipe" /><category term="date" /><category term="negligence" /><category term="validation" /><category term="jar" /><category term="SpringSecurity" /><category term="grails" /><category term="liferay" /><category term="rules engine" /><category term="spring roo" /><category term="society" /><category term="DSL" /><category term="ejb3" /><category term="spring" /><category term="tips" /><category term="FuBI" /><category term="eclipse" /><category term="nonsense" /><category term="review" /><category term="laptop" /><category term="notes" /><category term="humor" /><category term="identity-theft" /><category term="future" /><category term="xml" /><category term="3Di" /><category term="advice" /><category term="GroovyMag" /><category term="mysql" /><category term="logic" /><category term="NFJS" /><category term="object" /><category term="jBPM" /><category term="geek" /><category term="SSO" /><category term="cloud" /><category term="pthreads" /><category term="sample" /><category term="portlet" /><category term="trac" /><category term="android" /><category term="posix" /><category term="RCP" /><category term="jpa" /><category term="software" /><category term="dataSource" /><category term="conversation" /><category term="coding" /><category term="insanity" /><category term="testing" /><category term="JavaScript" /><category term="widget" /><category term="groovy programming language" /><category term="wiki" /><category term="proxy" /><category term="java.awt.Color" /><category term="MVC" /><category term="jdbc" /><category term="debugging" /><category term="DSP" /><category term="IT" /><category term="google talk" /><category term="trace" /><category term="coding software culture" /><category term="speed test" /><category term="Security" /><category term="crazy" /><category term="PLEAC" /><category term="star wars" /><category term="ldap" /><category term="social networking" /><category term="ibm" /><category term="searchable" /><category term="JAX-RPC" /><category term="agile" /><category term="OLTP" /><category term="BLUI" /><category term="enterprise" /><category term="internet" /><category term="ci" /><category term="script" /><category term="DWR" /><category term="domain" /><category term="iBatis" /><category term="addon" /><category term="fitnesse" /><category term="database" /><category term="WorkFlow" /><category term="linux" /><category term="computer science" /><category term="DWR2" /><category term="hibernate" /><category term="idea" /><category term="architectures" /><category term="ant" /><category term="soap" /><category term="linguistics" /><category term="law" /><category term="REST" /><category term="ajax" /><category term="politics" /><category term="programming" /><category term="tutorial" /><category term="multithreading" /><category term="mapping" /><category term="audit" /><category term="jvm" /><category term="fowler" /><category term="j5ee" /><category term="API" /><category term="JavaFX" /><category term="domain specific languages" /><category term="appengine" /><category term="3D" /><category term="SpringOne 2GX" /><category term="web2.0" /><category term="joel" /><category term="LeJOS" /><category term="languages" /><category term="jboss" /><category term="search" /><category term="article" /><category term="Enum" /><category term="book shelf" /><category term="distribution" /><title>Thoughts and Ideas</title><subtitle type="html">The power of software is the power of thoughts and ideas.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://hartsock.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://hartsock.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Shawn Hartsock</name><uri>http://www.blogger.com/profile/07041739178513685832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_Y1izti3dd0w/SRtSwklBY9I/AAAAAAAAAR0/FYJePOEOrtQ/s1600-R/5d0da4a7693ba9c2edf0e82e4106f5e9%3Fs%3D80" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>262</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/blogspot/KbOyU" /><feedburner:info uri="blogspot/kboyu" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;Ak8EQH0-eCp7ImA9WhRRF0g.&quot;"><id>tag:blogger.com,1999:blog-28383337.post-3166278435865895849</id><published>2011-12-01T12:00:00.000-05:00</published><updated>2011-12-01T12:00:01.350-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-01T12:00:01.350-05:00</app:edited><title>What is Computer Science?</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/68Zo_l7u-zfkQ5jik-D7pZnuxqk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/68Zo_l7u-zfkQ5jik-D7pZnuxqk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/68Zo_l7u-zfkQ5jik-D7pZnuxqk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/68Zo_l7u-zfkQ5jik-D7pZnuxqk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;blockquote class="tr_bq"&gt;
"Computer Science is the Science of Computing Machinery."&lt;/blockquote&gt;
When I hear this I want to put a stick in the eye of the person who just said it. That's not a definition, it's a slogan. Yet, this is the definition used in most textbooks that even try to tackle the subject.&lt;br /&gt;
&lt;br /&gt;
Let's sit down and try and break this apart. When do we cross the line from just being a machine and becoming a &lt;i&gt;computing&lt;/i&gt;&amp;nbsp;machine? Where is the distinction? Perhaps that will tell us something.&lt;br /&gt;
&lt;br /&gt;
If I take a light bulb and plug it in and it turns on, that's not a computing machine.&lt;br /&gt;
&lt;br /&gt;
If I take a light bulb and plug it in and it flickers... not still not computing since the flicker is random and has nothing to do with anything outside the light bulb.&lt;br /&gt;
&lt;br /&gt;
If I take a light bulb and plug it in and it doesn't light. That's not computing, that's broken.&lt;br /&gt;
&lt;br /&gt;
If I take a light bulb and it has a sensor so that when I plug it in, it doesn't light ... until I darken the room. In the dark it turns &lt;i&gt;on&lt;/i&gt;, and in the light it turns off.&lt;br /&gt;
&lt;br /&gt;
This machine has now crossed into the realm of computing. Albeit the simplest possible processing is happening: an outside stimulus is causing a response. We could call this a &lt;i&gt;stimulus-response&lt;/i&gt;&amp;nbsp;agent. Even so, this is now a computing machine and what is going inside this simple device is the very smallest beginning of something of interest.&lt;br /&gt;
&lt;br /&gt;
Now, name a system that we can clearly define as a &lt;i&gt;computer&lt;/i&gt;&amp;nbsp;that &lt;i&gt;does not&lt;/i&gt;&amp;nbsp;exhibit some form of this behavior. Even a batch processing system that starts at a given time takes input or stimulus from outside itself, processes this inside itself, and then produces output.&lt;br /&gt;
&lt;br /&gt;
What is Computer Science? We study something called "Computing" perhaps that &lt;i&gt;should&lt;/i&gt;&amp;nbsp;have been the name of the field? &lt;i&gt;Computing&lt;/i&gt;&amp;nbsp;is really what I've been working with my entire career and that's really what the degree is all about.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28383337-3166278435865895849?l=hartsock.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/KbOyU/~4/tWcTWw_qUEU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://hartsock.blogspot.com/feeds/3166278435865895849/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=28383337&amp;postID=3166278435865895849" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/3166278435865895849?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/3166278435865895849?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/KbOyU/~3/tWcTWw_qUEU/what-is-computer-science.html" title="What is Computer Science?" /><author><name>Shawn Hartsock</name><uri>http://www.blogger.com/profile/07041739178513685832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_Y1izti3dd0w/SRtSwklBY9I/AAAAAAAAAR0/FYJePOEOrtQ/s1600-R/5d0da4a7693ba9c2edf0e82e4106f5e9%3Fs%3D80" /></author><thr:total>0</thr:total><feedburner:origLink>http://hartsock.blogspot.com/2011/12/what-is-computer-science.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkIERXk6fip7ImA9WhRSFUg.&quot;"><id>tag:blogger.com,1999:blog-28383337.post-4737434026408126162</id><published>2011-11-17T11:59:00.002-05:00</published><updated>2011-11-17T13:28:24.716-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-17T13:28:24.716-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="plugin" /><category scheme="http://www.blogger.com/atom/ns#" term="spring roo" /><category scheme="http://www.blogger.com/atom/ns#" term="enterprise" /><category scheme="http://www.blogger.com/atom/ns#" term="grails" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy programming language" /><category scheme="http://www.blogger.com/atom/ns#" term="addon" /><title>The Life Cycle of Plugins &amp; Addons in the Enterprise</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/td8KfLYHTliHFqXrUb1R4c7A0rk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/td8KfLYHTliHFqXrUb1R4c7A0rk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/td8KfLYHTliHFqXrUb1R4c7A0rk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/td8KfLYHTliHFqXrUb1R4c7A0rk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;I'm probably one of the few people in the world that has had the opportunity to work with both Grails and Spring Roo on extended projects. In both environments I've discovered a strategy around code reuse that is a bit different from what I normally observe in the Enterprises I consult with.&lt;br /&gt;&lt;br /&gt;Both Spring Roo and Grails feature a reusable component system. They are similar enough you can use similar strategies in the enterprise with either Spring Roo or Grails. If you are in an enterprise that uses both Grails and Roo (these companies do in fact exist), I recommend that you develop common functionality in Spring POJO then graft a Grails plugin and/or a Spring Roo addon over the top.&lt;br /&gt;&lt;br /&gt;In Grails, plugins are powerful sub-applications. A plugin can provide a command line script to the Grails CLI, a library, a library dependency, to a full set of Model View and Controllers or anywhere in between.&lt;br /&gt;&lt;br /&gt;In Spring Roo, we term these reusable components &lt;i&gt;addons&lt;/i&gt; because they do not necessarily contribute runtime functionality to the final system. Spring Roo's philosophy of having &lt;i&gt;zero&lt;/i&gt; runtime footprint means that you don't have a Roo runtime to hang your hat on. What you do have is a very powerful Command Line Interface (CLI) that you can leverage along with a templating system inside your Roo addon to allow your end-user-developer to generate their own components. Instead of shipping function as you do in Grails, in Roo you provide a mechanism for guiding the developer through generating function.&lt;br /&gt;&lt;br /&gt;Whether you are shipping function wholesale, as you do in Grails, or you are providing functional templates as you do in Roo, in an abstract sense I've discovered the same pattern applies to both Roo and Grails. You start with a pilot project for the addon or the plugin and you lift it out of the pilot project allowing it to graduate to a shared enterprise-wide repository.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-bVhyDtBuba8/TrwGeSS_-vI/AAAAAAAADOk/3Fjz3RJU2TE/s1600/addon_or_plugin_lifecycle.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 303px;" src="http://3.bp.blogspot.com/-bVhyDtBuba8/TrwGeSS_-vI/AAAAAAAADOk/3Fjz3RJU2TE/s400/addon_or_plugin_lifecycle.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5673416747957353202" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As time goes by, you work on the addon or plugin as a separate project. Each project that uses the addon/plugin will keep track of its own versions of these addons meaning it is important to keep those old revisions available just in case. You will also want to tag each released revision in the event you need to &lt;i&gt;back port&lt;/i&gt; fixes into old releases should a critical project get stuck on an old version of Roo or Grails for some reason.&lt;br /&gt;&lt;br /&gt;The advantages to the enterprise would be a single place to revision control the client components of a Single Sign On system, or a single place to revision control and distribute shared client functions, look and feel components, or other commonly reused system components.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28383337-4737434026408126162?l=hartsock.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/KbOyU/~4/vXEr7WBAcuc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://hartsock.blogspot.com/feeds/4737434026408126162/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=28383337&amp;postID=4737434026408126162" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/4737434026408126162?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/4737434026408126162?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/KbOyU/~3/vXEr7WBAcuc/life-cycle-of-plugins-addons-in.html" title="The Life Cycle of Plugins &amp; Addons in the Enterprise" /><author><name>Shawn Hartsock</name><uri>http://www.blogger.com/profile/07041739178513685832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_Y1izti3dd0w/SRtSwklBY9I/AAAAAAAAAR0/FYJePOEOrtQ/s1600-R/5d0da4a7693ba9c2edf0e82e4106f5e9%3Fs%3D80" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-bVhyDtBuba8/TrwGeSS_-vI/AAAAAAAADOk/3Fjz3RJU2TE/s72-c/addon_or_plugin_lifecycle.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://hartsock.blogspot.com/2011/11/life-cycle-of-plugins-addons-in.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU8BSXg9fCp7ImA9WhRTEUo.&quot;"><id>tag:blogger.com,1999:blog-28383337.post-6638116893967329303</id><published>2011-11-01T15:58:00.003-04:00</published><updated>2011-11-01T16:04:18.664-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-01T16:04:18.664-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="SpringOne 2GX" /><category scheme="http://www.blogger.com/atom/ns#" term="grails" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><title>The Highly Monitored Grails Application @ SpringOne 2GX 2011</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/7TPrUsFa1oNvFELQZU1GBT8FEbE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7TPrUsFa1oNvFELQZU1GBT8FEbE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/7TPrUsFa1oNvFELQZU1GBT8FEbE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/7TPrUsFa1oNvFELQZU1GBT8FEbE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;My second talk at SpringOne 2GX was "The Highly Monitored Grails Application" and it had a great turn out from a large and lively audience. This was fantastic especially considering I was presenting as the very last presenter of the conference. This was one of the best received talks I've ever given. &lt;br /&gt;&lt;br /&gt;The talk was demo heavy and so, while there's not much in the slides we spent a lot of time in my IDE, at the command line, and running through ways to monitor and work with live Grails applications. We even manipulated the hibernate settings in a running Grails application! Great fun!&lt;br /&gt;&lt;br /&gt;&lt;iframe src="https://docs.google.com/presentation/embed?id=1o4sDcc5vl0c6md2FzeyeJEkO11tr6R0bArekr95n23A&amp;start=false&amp;loop=false&amp;delayms=3000" frameborder="0" width="480" height="389" allowfullscreen="true" webkitallowfullscreen="true"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;Definitely the highlight of my SpringOne 2GX conference!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28383337-6638116893967329303?l=hartsock.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/KbOyU/~4/r0pNoskQ7cI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://hartsock.blogspot.com/feeds/6638116893967329303/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=28383337&amp;postID=6638116893967329303" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/6638116893967329303?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/6638116893967329303?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/KbOyU/~3/r0pNoskQ7cI/highly-monitored-grails-application.html" title="The Highly Monitored Grails Application @ SpringOne 2GX 2011" /><author><name>Shawn Hartsock</name><uri>http://www.blogger.com/profile/07041739178513685832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_Y1izti3dd0w/SRtSwklBY9I/AAAAAAAAAR0/FYJePOEOrtQ/s1600-R/5d0da4a7693ba9c2edf0e82e4106f5e9%3Fs%3D80" /></author><thr:total>0</thr:total><feedburner:origLink>http://hartsock.blogspot.com/2011/11/highly-monitored-grails-application.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE4DRnY8eip7ImA9WhdaF0s.&quot;"><id>tag:blogger.com,1999:blog-28383337.post-7037946621157079931</id><published>2011-10-27T20:31:00.005-04:00</published><updated>2011-10-27T20:49:37.872-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-27T20:49:37.872-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Chicago" /><category scheme="http://www.blogger.com/atom/ns#" term="SpringOne 2GX" /><category scheme="http://www.blogger.com/atom/ns#" term="grails" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><title>Performance Tuning Grails applications at SpringOne 2GX 2011</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/A9rPsyWRCfWQw_d8IvfHn529doE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/A9rPsyWRCfWQw_d8IvfHn529doE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/A9rPsyWRCfWQw_d8IvfHn529doE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/A9rPsyWRCfWQw_d8IvfHn529doE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;I just got done with my SpringOne 2GX talk on &lt;a href="http://www.springone2gx.com/conference/chicago/2011/10/session?id=23281"&gt;Performance Tuning Grails Applications&lt;/a&gt;. When I proposed this talk six months ago there was no material on this subject. Since then a fantastic webinar came out. At the start of the presentation I mentioned this video which I would call the essential resource. And, you can watch it any time.&lt;br /&gt;&lt;br /&gt;&lt;iframe width="560" height="315" src="http://www.youtube.com/embed/gl83-80Qq94" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;I &lt;i&gt;deliberately&lt;/i&gt; cut out of my talk much of the subject matter there, why present the same information in a talk that you can download at any time? Wanting to present new and original material at SpringOne 2GX I rewrote my own talk from scratch. This time focused on the performance tuning of the server side code itself.&lt;br /&gt;&lt;br /&gt;I decided to focus on real world performance metrics associated with Groovy Code itself. In the talk I demonstrated four implementations of a service three in Groovy and one in Java. The result is a bit surprising. Restructuring your Groovy code yields order-of-magnitude &lt;i&gt;greater&lt;/i&gt; performance improvement than simply shedding Groovy in favor of Java.&lt;br /&gt;&lt;br /&gt;The lesson to be learned is that the largest expenses your application will pay are in data marshalling, unmarshalling, network transmission time, and database querying. The Groovy itself can be restructured to be more performant without resorting to pure Java. Pure Java is there for us if we really need it but the majority of its benefit is not in that it is Java but in that it removes the most elegant features of &lt;i&gt;functional programming&lt;/i&gt; and dynamic type systems from our pallet. I ask if the trade-off is really worth the small difference we see when simple Groovy code restructuring can give us five times better performance.&lt;br /&gt;&lt;br /&gt;Slides:&lt;br /&gt;&lt;iframe src="https://docs.google.com/present/embed?id=ajj7hrpdn7tk_102gt8zbggg" frameborder="0" width="410" height="342"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;Code:&lt;br /&gt;&lt;a href="https://github.com/hartsock/folksonomy"&gt;https://github.com/hartsock/folksonomy&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28383337-7037946621157079931?l=hartsock.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/KbOyU/~4/yAPyl8Jt13U" height="1" width="1"/&gt;</content><link rel="related" href="http://www.springone2gx.com/conference/chicago/2011/10/session?id=23281" title="Performance Tuning Grails applications at SpringOne 2GX 2011" /><link rel="replies" type="application/atom+xml" href="http://hartsock.blogspot.com/feeds/7037946621157079931/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=28383337&amp;postID=7037946621157079931" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/7037946621157079931?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/7037946621157079931?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/KbOyU/~3/yAPyl8Jt13U/performance-tuning-grails-applications.html" title="Performance Tuning Grails applications at SpringOne 2GX 2011" /><author><name>Shawn Hartsock</name><uri>http://www.blogger.com/profile/07041739178513685832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_Y1izti3dd0w/SRtSwklBY9I/AAAAAAAAAR0/FYJePOEOrtQ/s1600-R/5d0da4a7693ba9c2edf0e82e4106f5e9%3Fs%3D80" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://img.youtube.com/vi/gl83-80Qq94/default.jpg" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://hartsock.blogspot.com/2011/10/performance-tuning-grails-applications.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk8CRXs5eyp7ImA9WhdVFUo.&quot;"><id>tag:blogger.com,1999:blog-28383337.post-4658871660574903318</id><published>2011-09-20T23:10:00.002-04:00</published><updated>2011-09-20T23:14:24.523-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-20T23:14:24.523-04:00</app:edited><title>Speaking at Milwaukee Java User's Group</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/avly-PW-CxNOTDwpPyoc_O5WjxM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/avly-PW-CxNOTDwpPyoc_O5WjxM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/avly-PW-CxNOTDwpPyoc_O5WjxM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/avly-PW-CxNOTDwpPyoc_O5WjxM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;I'm honored to be speaking at the Milwaukee Java User Group coming up on September 27th. If you are in the area, I'd be glad to see you and hear your input on the topic. I'm leaving my normal fare of talks on Groovy and Grails and speaking on the topic of cloud computing and Java. Many of my engagements revolve around tuning Java in cloud computing platforms for use in high volume websites. This talk is about my reflections on travelling from mere virtualization to three variations on cloud computing that I've used.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-pjFlgUSRq0U/TnlV2q0BZLI/AAAAAAAAC5k/fh9m7SsXxss/s1600/Screen%2Bshot%2B2011-09-20%2Bat%2B10.10.08%2BPM.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 276px;" src="http://3.bp.blogspot.com/-pjFlgUSRq0U/TnlV2q0BZLI/AAAAAAAAC5k/fh9m7SsXxss/s400/Screen%2Bshot%2B2011-09-20%2Bat%2B10.10.08%2BPM.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5654645204834149554" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hope to see you there.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28383337-4658871660574903318?l=hartsock.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/KbOyU/~4/hXTYyDvjFh0" height="1" width="1"/&gt;</content><link rel="related" href="http://www.wjug.org/wjug/" title="Speaking at Milwaukee Java User's Group" /><link rel="replies" type="application/atom+xml" href="http://hartsock.blogspot.com/feeds/4658871660574903318/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=28383337&amp;postID=4658871660574903318" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/4658871660574903318?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/4658871660574903318?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/KbOyU/~3/hXTYyDvjFh0/speaking-at-milwaukee-java-users-group.html" title="Speaking at Milwaukee Java User's Group" /><author><name>Shawn Hartsock</name><uri>http://www.blogger.com/profile/07041739178513685832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_Y1izti3dd0w/SRtSwklBY9I/AAAAAAAAAR0/FYJePOEOrtQ/s1600-R/5d0da4a7693ba9c2edf0e82e4106f5e9%3Fs%3D80" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-pjFlgUSRq0U/TnlV2q0BZLI/AAAAAAAAC5k/fh9m7SsXxss/s72-c/Screen%2Bshot%2B2011-09-20%2Bat%2B10.10.08%2BPM.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://hartsock.blogspot.com/2011/09/speaking-at-milwaukee-java-users-group.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE8CQXs7fip7ImA9WhdQFUQ.&quot;"><id>tag:blogger.com,1999:blog-28383337.post-456315346612766468</id><published>2011-08-17T12:01:00.003-04:00</published><updated>2011-08-17T12:01:00.506-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-17T12:01:00.506-04:00</app:edited><title>Software Development versus Software Engineering</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/H5nGJSuagrYH2QSXafYYi7IxO90/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/H5nGJSuagrYH2QSXafYYi7IxO90/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/H5nGJSuagrYH2QSXafYYi7IxO90/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/H5nGJSuagrYH2QSXafYYi7IxO90/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;One of the most useful things that I have gotten from studying things that I call "&lt;a href="http://en.wikipedia.org/wiki/W._Edwards_Deming"&gt;Deming&lt;/a&gt;esque " is the idea of &lt;a href="http://en.wikipedia.org/wiki/Kanban"&gt;Kanban&lt;/a&gt;. Kanban means "sign board" and is a way for projects to display information about themselves.
&lt;br /&gt;
&lt;br /&gt;In its simplest form the Kanban idea is simply to keep track of things I need to do, things that I am doing, and things that I have done. In addition, because the board is placed in a location that is easy for management to see it can't help but communicate the status of the project or work area associated with the Kanban.
&lt;br /&gt;
&lt;br /&gt;This idea is so simple it hardly seems like it is worth the effort of naming it. It is so engrained in the idea of a productive work team that I can't fathom needing to have a "methodology" associated with it. Yet I see amazingly complex ideas built up around this very simple tool.
&lt;br /&gt;
&lt;br /&gt;Ironically, developers tend to like over complicated things in place of simple things. I suspect that it is because we are smart people and we don't like things that are too "simple" challenge us. Instead we want something hard that forces us to really stretch. So, I'd like to challenge people who think like that: &lt;span style="font-style:italic;"&gt;don't think like that&lt;/span&gt;.
&lt;br /&gt;
&lt;br /&gt;Instead, we should relish the idea of doing amazingly complex things with the simplest tools possible. In the places I've worked, the Kanban is most frequently implemented using a simple white sheet and a simple "sticky note" approach. I've seen many variations but ultimately you are just capturing the following information:
&lt;br /&gt;
&lt;br /&gt;1. What do you need to do?
&lt;br /&gt;2. What are you doing?
&lt;br /&gt;3. What have you done?
&lt;br /&gt;
&lt;br /&gt;Anything beyond this is probably a waste of time. This information recorded regularly can give you an idea of how long a project will take (based on the velocity of movement of items from "need to do" over to "have done") and how many "are doing" things are happening at the same time. The &lt;span style="font-style:italic;"&gt;manager's&lt;/span&gt; job now becomes tracking this information and predicting that if fewer "are doing" things are happening then the "have done" pile grows more slowly.
&lt;br /&gt;
&lt;br /&gt;You can formalize this as much as you feel like, put pretty math on it, or give it buzzword names, but really this is the basis for all software development project management... also sometimes known as "software engineering."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28383337-456315346612766468?l=hartsock.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/KbOyU/~4/3XFGCIPkNqg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://hartsock.blogspot.com/feeds/456315346612766468/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=28383337&amp;postID=456315346612766468" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/456315346612766468?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/456315346612766468?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/KbOyU/~3/3XFGCIPkNqg/software-development-versus-software.html" title="Software Development versus Software Engineering" /><author><name>Shawn Hartsock</name><uri>http://www.blogger.com/profile/07041739178513685832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_Y1izti3dd0w/SRtSwklBY9I/AAAAAAAAAR0/FYJePOEOrtQ/s1600-R/5d0da4a7693ba9c2edf0e82e4106f5e9%3Fs%3D80" /></author><thr:total>0</thr:total><feedburner:origLink>http://hartsock.blogspot.com/2011/08/software-development-versus-software.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMGR3k9eip7ImA9WhdVGUQ.&quot;"><id>tag:blogger.com,1999:blog-28383337.post-6221923103662447828</id><published>2011-08-14T19:00:00.001-04:00</published><updated>2011-09-25T20:37:06.762-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-25T20:37:06.762-04:00</app:edited><title>Washington DC Area Groovy User Group</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/LbWqyOYvvQr-wQwJTuRu4apLIrE/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LbWqyOYvvQr-wQwJTuRu4apLIrE/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/LbWqyOYvvQr-wQwJTuRu4apLIrE/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LbWqyOYvvQr-wQwJTuRu4apLIrE/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos2.meetupstatic.com/photos/event/8/f/1/global_22682289.jpeg"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 180px; height: 147px;" src="http://photos2.meetupstatic.com/photos/event/8/f/1/global_22682289.jpeg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;I'm honored to be presenting at the &lt;a href="http://www.dcgroovy.org/events/25246131/"&gt;Washington DC Area Groovy User Group&lt;/a&gt; this Wednesday. If you are going to be in DC I would encourage you to come out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28383337-6221923103662447828?l=hartsock.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/KbOyU/~4/ZL7C9l50FnI" height="1" width="1"/&gt;</content><link rel="related" href="http://www.dcgroovy.org/events/25246131/" title="Washington DC Area Groovy User Group" /><link rel="replies" type="application/atom+xml" href="http://hartsock.blogspot.com/feeds/6221923103662447828/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=28383337&amp;postID=6221923103662447828" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/6221923103662447828?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/6221923103662447828?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/KbOyU/~3/ZL7C9l50FnI/washington-dc-area-groovy-user-group.html" title="Washington DC Area Groovy User Group" /><author><name>Shawn Hartsock</name><uri>http://www.blogger.com/profile/07041739178513685832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_Y1izti3dd0w/SRtSwklBY9I/AAAAAAAAAR0/FYJePOEOrtQ/s1600-R/5d0da4a7693ba9c2edf0e82e4106f5e9%3Fs%3D80" /></author><thr:total>0</thr:total><feedburner:origLink>http://hartsock.blogspot.com/2011/08/washington-dc-area-groovy-user-group.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEcFQXs4fyp7ImA9WhdRGUQ.&quot;"><id>tag:blogger.com,1999:blog-28383337.post-8923411694472086474</id><published>2011-08-10T12:00:00.013-04:00</published><updated>2011-08-10T12:00:10.537-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-10T12:00:10.537-04:00</app:edited><title>good code, great code, and really great code</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/V86wEnFjQYJbFeoBoa6jwrMzdRw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/V86wEnFjQYJbFeoBoa6jwrMzdRw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/V86wEnFjQYJbFeoBoa6jwrMzdRw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/V86wEnFjQYJbFeoBoa6jwrMzdRw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;There's great software, and there's really great software. The stuff that's great is the stuff that works well and is well documented. Ever need to figure out something? Go read the docs, if you screw up then the software tells you exactly how you messed up and didn't follow the documentation. That's great software.
&lt;br /&gt;
&lt;br /&gt;The best software (the really great stuff) doesn't require documentation. You can play with it and discover how to make it do what you want. You just have to poke about with it a little bit and it will guide you to a working use case. You don't have to read a book, understand a theory (beyond basic computer sciencey things) and you can get to work almost immediately.
&lt;br /&gt;
&lt;br /&gt;This is accomplished through really good failure modes and support tools that help you figure out how to use the system. It's 100 time the work of documentation but it is 100 times better. The best form of this is really great test coverage. You need to have really great test coverage to show you the use cases the system designers were thinking of. That is the best documentation because if a developer &lt;span style="font-style: italic;"&gt;changes their minds&lt;/span&gt; the tests &lt;span style="font-style: italic;"&gt;must&lt;/span&gt; reflect the change in paradigm.
&lt;br /&gt;
&lt;br /&gt;Then there's stuff like this:
&lt;br /&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/-Uyt90-ul3Ug/TkAFKc6-P1I/AAAAAAAAB4o/ohSkoPc4q3Q/s1600/Screen%2Bshot%2B2011-08-08%2Bat%2B10.40.57%2BAM.png"&gt;&lt;img style="display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 311px; height: 202px;" src="http://2.bp.blogspot.com/-Uyt90-ul3Ug/TkAFKc6-P1I/AAAAAAAAB4o/ohSkoPc4q3Q/s400/Screen%2Bshot%2B2011-08-08%2Bat%2B10.40.57%2BAM.png" alt="" id="BLOGGER_PHOTO_ID_5638512410588233554" border="0" /&gt;&lt;/a&gt;
&lt;br /&gt;This is from the &lt;a href="http://www.sonatype.com/people/2009/06/integration-tests-with-maven-part-2-test-coverage-reports/"&gt;Sonatype Blog&lt;/a&gt;. On its own this is a tiny mistake. A blog has had the POM XML fragment stripped out of it. A bit of spelunking on the web produces &lt;a href="http://www.sonatype.com/people/2009/06/integration-tests-with-maven-part-2-test-coverage-reports/"&gt;this link&lt;/a&gt; as the definitive documentation for the plugin. Let's go and read the code for the plugin and see if we can't figure out what the missing tags are.&lt;/p&gt;&lt;p&gt;Over on github we find the &lt;a href="https://github.com/sonatype/emma4it-maven-plugin"&gt;emma4it plugin's source code&lt;/a&gt;. Diving this code we find that the project is actually pretty darn thin... and that's good because it is easy to understand. What does the JavaDoc say about how to configure this plugin? Thankfully there is at least documentation telling us what each of the Java files are for in the Maven lifecycle.&lt;/p&gt;&lt;p&gt;Does any of this include an example like the one Sonatype accidentally destroyed the only canonical example of in their blog? Sadly, no.&lt;/p&gt;&lt;p&gt;So my best guess is the first "report" word shown is a "report" id for the execution since we have more than one execution. My next guess is the phase we use in the documentation from the blog is different from the phase shown in the JavaDoc. The phase here is the "post-integration-test" phase by my guess. Next I have to take a wild leap. My guess is "project.build.sourcesDirectory" is the value set in the sourcesDirectory tag.&lt;/p&gt;This is my best guess at the missing POM fragment:
&lt;br /&gt;
&lt;br /&gt;&lt;blockquote&gt;                            &amp;lt;execution&amp;gt;
&lt;br /&gt;                              &amp;lt;id&amp;gt;report&amp;lt;/id&amp;gt;
&lt;br /&gt;                              &amp;lt;phase&amp;gt;post-integration-test&amp;lt;/phase&amp;gt;
&lt;br /&gt;                              &amp;lt;goals&amp;gt;
&lt;br /&gt;                                  &amp;lt;goal&amp;gt;report&amp;lt;/goal&amp;gt;
&lt;br /&gt;                              &amp;lt;/goals&amp;gt;
&lt;br /&gt;                              &amp;lt;configuration&amp;gt;
&lt;br /&gt;                                  &amp;lt;sourcesDirectory&amp;gt;
&lt;br /&gt;${project.build.sourcesDirectory}
&lt;br /&gt;                                  &amp;lt;/sourcesDirectory&amp;gt;
&lt;br /&gt;                              &amp;lt;/configuration&amp;gt;
&lt;br /&gt;                          &amp;lt;/execution&amp;gt;
&lt;br /&gt;&lt;/blockquote&gt;
&lt;br /&gt;
&lt;br /&gt;So by my estimation this is good code, that is on the cusp of being great code. That is still a ways from being really great code which wouldn't require you to dig around for documentation to begin with.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28383337-8923411694472086474?l=hartsock.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/KbOyU/~4/VpCm4vBUJ0w" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://hartsock.blogspot.com/feeds/8923411694472086474/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=28383337&amp;postID=8923411694472086474" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/8923411694472086474?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/8923411694472086474?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/KbOyU/~3/VpCm4vBUJ0w/good-code-great-code-and-really-great.html" title="good code, great code, and really great code" /><author><name>Shawn Hartsock</name><uri>http://www.blogger.com/profile/07041739178513685832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_Y1izti3dd0w/SRtSwklBY9I/AAAAAAAAAR0/FYJePOEOrtQ/s1600-R/5d0da4a7693ba9c2edf0e82e4106f5e9%3Fs%3D80" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-Uyt90-ul3Ug/TkAFKc6-P1I/AAAAAAAAB4o/ohSkoPc4q3Q/s72-c/Screen%2Bshot%2B2011-08-08%2Bat%2B10.40.57%2BAM.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://hartsock.blogspot.com/2011/08/good-code-great-code-and-really-great.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0cGRXc_eip7ImA9WhdREkk.&quot;"><id>tag:blogger.com,1999:blog-28383337.post-4926676643210060683</id><published>2011-08-01T21:09:00.007-04:00</published><updated>2011-08-01T21:37:04.942-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-01T21:37:04.942-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="PMD" /><title>The seven stages of dealing with PMD rule violation</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/kbvRzJkMRO7Uu3lcjbVURIzjyiM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kbvRzJkMRO7Uu3lcjbVURIzjyiM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/kbvRzJkMRO7Uu3lcjbVURIzjyiM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/kbvRzJkMRO7Uu3lcjbVURIzjyiM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Is your build broken from a PMD rule violation? Has your project has been set up so that a &lt;a href="http://pmd.sourceforge.net/"&gt;PMD&lt;/a&gt; rule violation breaks the build? On occasion even the best developers slip and push code that is in violation of the PMD rules they themselves agreed to. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I have been observing developers under these severe conditions for some time now and I've identified seven emotional stages that every developer who breaks the build due to PMD rule violations goes through. I am cataloging these here in the hope that it helps some developer cope with their broken build and move on in their project.&lt;/div&gt;&lt;ol&gt;&lt;li&gt;Shock and denial&lt;br /&gt;&lt;br /&gt;You will probably react to learning that your code does not conform to your project's PMD rules with numbed disbelief. You may deny the reality of this PMD rule violation at some level in order to avoid the pain. Shock provides an emotional protection from being overwhelmed all at once.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Pain and Guilt&lt;br /&gt;&lt;br /&gt;As the shock wears off it is replaced with suffering. Although it is excruciating, it is important that you experience this pain fully and not avoid it or escape it with &lt;span class="Apple-style-span" style="font-style: italic; "&gt;//NOPMD &lt;/span&gt;&lt;span class="Apple-style-span"&gt;comments or by the use of alcohol or drugs.&lt;br /&gt;&lt;br /&gt;You may have guilty feelings or remorse for the things you did or didn't do with your code. Life feels scary and chaotic during this phase.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"&gt;Anger and Bargaining&lt;br /&gt;&lt;br /&gt;Frustration gives way to anger. You lash out and lay unwarranted blame for the rule violation on someone else. You may blame PMD itself. You may blame the authors of the rules. You may rail against fate questioning "Why me?" and you may also try to bargain in vain with PMD saying things like: "I will never drink while coding again if you will just accept my patch"&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"&gt;Depression, reflection, loneliness&lt;br /&gt;&lt;br /&gt;Just when other developers think you should be getting on with your project, a long period of sad reflection will likely overtake you. This is a normal stage of resolving breaking a build due to a PMD rules violation.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;During this time you will finally realize the full magnitude of your rule violation. You may isolate yourself from other developers on purpose to reflect on things you did in the code-base and focus on your memories of past times before you violated the PMD rule.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The upward turn&lt;br /&gt;&lt;br /&gt;As you start to adjust to life after a PMD rule violation has occurred, you become calmer, your thoughts organize. Your physical symptoms (these range from mild stomach cramps and headaches to full blown cold-sweats and involuntary spasms) lessen your depression lifts and you begin to formulate a plan.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Reconstruction and working through.&lt;br /&gt;&lt;br /&gt;As your mind becomes more functional, you find yourself seeking realistic code changes to be made to resolve the PMD rule violation. You start to work on restructuring your code around the PMD rule violation.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Acceptance and hope&lt;br /&gt;&lt;br /&gt;During this last stage you learn to accept and deal with the reality of using PMD on your project. Acceptance of PMD does not necessarily mean happiness. Given the pain and turmoil you have experienced you may never return to a care-free and untroubled code base that existed before you broke the build. But, you will find a way forward in your project.&lt;br /&gt;&lt;br /&gt;You will start to look positively on your project again as a whole and actually plan things for future releases. You will once again anticipate writing good code and may even find joy in writing software again.&lt;br /&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Rest assured, you can recover from a PMD rule violation. You can put your project back on track. There will be joy in coding again someday.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28383337-4926676643210060683?l=hartsock.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/KbOyU/~4/bNjLoWmfwUw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://hartsock.blogspot.com/feeds/4926676643210060683/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=28383337&amp;postID=4926676643210060683" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/4926676643210060683?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/4926676643210060683?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/KbOyU/~3/bNjLoWmfwUw/seven-stages-of-dealing-with-pmd-rule.html" title="The seven stages of dealing with PMD rule violation" /><author><name>Shawn Hartsock</name><uri>http://www.blogger.com/profile/07041739178513685832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_Y1izti3dd0w/SRtSwklBY9I/AAAAAAAAAR0/FYJePOEOrtQ/s1600-R/5d0da4a7693ba9c2edf0e82e4106f5e9%3Fs%3D80" /></author><thr:total>0</thr:total><feedburner:origLink>http://hartsock.blogspot.com/2011/08/seven-stages-of-dealing-with-pmd-rule.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUIMSHYzcCp7ImA9WhdSFUk.&quot;"><id>tag:blogger.com,1999:blog-28383337.post-5551344419096771239</id><published>2011-07-24T18:34:00.011-04:00</published><updated>2011-07-24T18:46:29.888-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-24T18:46:29.888-04:00</app:edited><title>The one about scope. And tacos.</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/76Y2p7DU6dTqW_OyZvzeR0mmavg/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/76Y2p7DU6dTqW_OyZvzeR0mmavg/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/76Y2p7DU6dTqW_OyZvzeR0mmavg/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/76Y2p7DU6dTqW_OyZvzeR0mmavg/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Consider the following paragraph.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Mary and Sally are friends. Mary gives Sally a gift for her birthday. Mary hangs up the telephone.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Are there any syntax problems in the above paragraph? Are there any grammar problems? What is wrong with this paragraph exactly? The problem is non-technical in nature. The paragraph references a relationship between Mary and Sally and then describes an interaction that occurs between them. Finally it describes Mary ending a phone conversation. However, we have no idea when or how Mary began talking on the phone. We don't even have a prior reference to a phone conversation.&lt;br /&gt;&lt;br /&gt;Consider the following code:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;def exchangeIfRelated(def mary, def sally) {&lt;br /&gt;if( canRelate(mary,sally) ) {&lt;br /&gt;mary.exchange(sally)&lt;br /&gt;}&lt;br /&gt;mary.closeConnection()&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;What is wrong here? The isn't anything technically wrong provided whatever connection we just closed was not in use after this method finishes. What is the likely hood this call is made from a different part of the program like this?&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;public void friends(FooService mary, BarService sally) {&lt;br /&gt;   mary.openConnection()&lt;br /&gt;   sally.openConnection()&lt;br /&gt;   exchangeIfRelated(mary,sally)&lt;br /&gt;   sally.closeConnection()&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Anything wrong here? No. Not really. It will compile, it will run. In this method we have implicitly taken responsibility for opening and closing whatever these connection things are. In a more concrete example, weight be opening and closing a database connection. In that kind of example we are allowing concerns to bleed between methods. Ideally, I want one unit of code to be concerned with one thing. That thing (whatever it is) is hopefully easily abstracted for use by other units of code without their having to become experts in that other field. The following is better and will likely lead to fewer misunderstandings.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public void friends(FooService mary, BarService sally) {&lt;br /&gt;   mary.openConnection()&lt;br /&gt;   sally.openConnection()&lt;br /&gt;   exchangeIfRelated(mary,sally) &lt;br /&gt;   mary.closeConnection()&lt;br /&gt;   sally.closeConnection() &lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;Knowing how an ignition system works does not aid my ability to drive a car in rush hour traffic. When I start my car I do not need to have knowledge of what happens when in my car's engine, nor do I need to know how a camshaft functions in order to drive my car down the road. The driver is insulated from these automotive inner workings. In the same way when we build software we want to insulate the layer above us from details about the layer beneath us.&lt;br /&gt;&lt;br /&gt;Mixing the scope of when and where you do things is like changing the subject of a paragraph. There are fish in the sea. Nothing is really wrong with it from the stand point of the compiler which really only understands the mechanics of phrases in the programming language. There are tacos in a truck. However, just as properly formed sentences that have little to do with the core thought of a paragraph are disruptive and confusing. I like kites. Similarly, such disruptive  code phrases in our code leads to confusion and in a program that kind of thing leads to bugs. And tacos.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28383337-5551344419096771239?l=hartsock.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/KbOyU/~4/lUeZNXOokaw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://hartsock.blogspot.com/feeds/5551344419096771239/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=28383337&amp;postID=5551344419096771239" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/5551344419096771239?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/5551344419096771239?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/KbOyU/~3/lUeZNXOokaw/one-about-scope-and-tacos.html" title="The one about scope. And tacos." /><author><name>Shawn Hartsock</name><uri>http://www.blogger.com/profile/07041739178513685832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_Y1izti3dd0w/SRtSwklBY9I/AAAAAAAAAR0/FYJePOEOrtQ/s1600-R/5d0da4a7693ba9c2edf0e82e4106f5e9%3Fs%3D80" /></author><thr:total>0</thr:total><feedburner:origLink>http://hartsock.blogspot.com/2011/07/one-about-scope-and-tacos.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0cASXkzeip7ImA9WhZREUQ.&quot;"><id>tag:blogger.com,1999:blog-28383337.post-4548358280090212395</id><published>2011-03-23T08:42:00.006-04:00</published><updated>2011-04-07T12:50:48.782-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-07T12:50:48.782-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="jpa" /><category scheme="http://www.blogger.com/atom/ns#" term="DSL" /><category scheme="http://www.blogger.com/atom/ns#" term="speaking" /><category scheme="http://www.blogger.com/atom/ns#" term="grails" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><title>GR8Conf</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/9HJqqQvw-8EquD4BX348mbRW-WQ/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9HJqqQvw-8EquD4BX348mbRW-WQ/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/9HJqqQvw-8EquD4BX348mbRW-WQ/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9HJqqQvw-8EquD4BX348mbRW-WQ/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;I'm very pleased to be speaking at &lt;a href="http://gr8conf.us/"&gt;GR8Conf&lt;/a&gt; this year. I'll be covering two topics. I hope the Groovy communities find them interesting.&lt;div&gt;&lt;span class="Apple-style-span"  &gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;The first up, how to use Domain Specific Languages in order to reduce accidental complexity. I have a very long post that I'm holding on to based on this topic (inspired by my trip to Manhattan and Google NYC earlier this year). In this talk I'll really take time to explore this idea practically. I will create a Domain Specific Language before your eyes as I do live coding with Test Driven Development. &lt;i&gt;It's performance art with Unit Tests!&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;The second topic is on Grails and the JPA. I'm currently working on a lab for this topic. We'll explore some of the nastier Object Relational Mapping problems I've encountered working with Grails and with JPA in isolation and together. If time permits I'll work in some performance troubleshooting in this lab too. In this format we'll have the chance to work together and really get a deep understanding of what's going on with Grails persistence and how you can use GORM and/or the JPA in places you may have thought were &lt;i&gt;impossible.&lt;/i&gt; I really enjoy the lab format and I hope to see a good turnout.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;For me, getting the opportunity to speak at the &lt;a href="http://gr8conf.us/"&gt;GR8Conf&lt;/a&gt; is a major milestone and I'm very pleased that &lt;a href="http://www.osintegrators.com"&gt;Open Software Integrators&lt;/a&gt; is allowing me to participate. The fine folks at Open Software Integrators have an experienced consulting staff that can help you with all things JVM related. I've had a great time working with the other consultants here over the last few months learning a great deal about performance tuning and scalability.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  &gt;&lt;span class="Apple-style-span" style="font-size: 14px;"&gt;So please check me out at&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="color: rgb(34, 34, 34); font-family: verdana, arial, helvetica, sans-serif; font-size: 14px; "&gt; &lt;a href="http://gr8conf.us/"&gt;GR8Conf&lt;/a&gt; and I look forward to seeing you there!&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;a target="_blank" href="https://www.google.com/calendar/event?action=TEMPLATE&amp;tmeid=NTVldDFqOTVwZXBiY2k2aTQwZHRjNHBsbjQgMzJ2Y2M4YzgybnJicmZrbG4yajhiMXFvMzRAZw&amp;tmsrc=32vcc8c82nrbrfkln2j8b1qo34%40group.calendar.google.com"&gt;&lt;img border="0" src="http://www.google.com/calendar/images/ext/gc_button1_en.gif"&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28383337-4548358280090212395?l=hartsock.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/KbOyU/~4/5jVS7G3WdNI" height="1" width="1"/&gt;</content><link rel="related" href="http://blog.gr8conf.us/2011/03/shawn-hartsock-joins-gr8-in-us-lineup.html" title="GR8Conf" /><link rel="replies" type="application/atom+xml" href="http://hartsock.blogspot.com/feeds/4548358280090212395/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=28383337&amp;postID=4548358280090212395" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/4548358280090212395?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/4548358280090212395?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/KbOyU/~3/5jVS7G3WdNI/gr8conf.html" title="GR8Conf" /><author><name>Shawn Hartsock</name><uri>http://www.blogger.com/profile/07041739178513685832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_Y1izti3dd0w/SRtSwklBY9I/AAAAAAAAAR0/FYJePOEOrtQ/s1600-R/5d0da4a7693ba9c2edf0e82e4106f5e9%3Fs%3D80" /></author><thr:total>1</thr:total><feedburner:origLink>http://hartsock.blogspot.com/2011/03/gr8conf.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0UERng_fSp7ImA9Wx9UGEs.&quot;"><id>tag:blogger.com,1999:blog-28383337.post-4493151481074545894</id><published>2011-02-16T08:00:00.000-05:00</published><updated>2011-02-16T08:00:07.645-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-16T08:00:07.645-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="controllers" /><category scheme="http://www.blogger.com/atom/ns#" term="filters" /><category scheme="http://www.blogger.com/atom/ns#" term="grails" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><title>Groovy/Grails: How to disable a controller</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/m6TpoCsSN6jjvalZ0AEVIJL07ac/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/m6TpoCsSN6jjvalZ0AEVIJL07ac/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/m6TpoCsSN6jjvalZ0AEVIJL07ac/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/m6TpoCsSN6jjvalZ0AEVIJL07ac/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/-By767SNeNuY/TVWfI3pC26I/AAAAAAAAA58/RuroYklguwc/s1600/Selection_012.png"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 315px; height: 231px;" src="http://1.bp.blogspot.com/-By767SNeNuY/TVWfI3pC26I/AAAAAAAAA58/RuroYklguwc/s400/Selection_012.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5572535088664730530" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Let's say you have a plugin. That plugin includes a controller. You don't want to use the controller provided by the plugin (for whatever reason) but instead you want use your own controller.&lt;br /&gt;&lt;br /&gt;What do you do?&lt;br /&gt;&lt;br /&gt;Filters my friend. Filters.&lt;br /&gt;&lt;br /&gt;Next to your &lt;i&gt;Config.groovy&lt;/i&gt; file in the grails-app/conf directory create for your self a file called &lt;i&gt;DisableFilters.groovy&lt;/i&gt; and then add a class definition. Here's a filter definition that disables &lt;i&gt;everything&lt;/i&gt; in the application... (making your grails application headless).&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;pre&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;class DisableFilters {&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;    def filters = {&lt;/div&gt;&lt;div&gt;        all(controller:'*', action:'*') {&lt;/div&gt;&lt;div&gt;            before = {&lt;/div&gt;&lt;div&gt;                // return false&lt;/div&gt;&lt;div&gt;            }&lt;/div&gt;&lt;div&gt;            after = {&lt;/div&gt;&lt;div&gt;                &lt;/div&gt;&lt;div&gt;            }&lt;/div&gt;&lt;div&gt;            afterView = {&lt;/div&gt;&lt;div&gt;                &lt;/div&gt;&lt;div&gt;            }&lt;/div&gt;&lt;div&gt;        }&lt;/div&gt;&lt;div&gt;    }&lt;/div&gt;&lt;div&gt;    &lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now you'll notice there is a &lt;i&gt;before&lt;/i&gt; closure and it returns false. This closure fires &lt;i&gt;before&lt;/i&gt; the request is passed to its destined controller/action. The &lt;i&gt;*&lt;/i&gt; means match all. So if you had a specific controller name or specific controller name pattern you wanted to disable you could easily disable all these by matching the name here.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Notice the nifty &lt;i&gt;after&lt;/i&gt; which would execute &lt;i&gt;after&lt;/i&gt; the controller and action complete. Finally you have the &lt;i&gt;afterView&lt;/i&gt; closure which would execute after the entire call chain was done and the browser has left. I'll leave the uses for these up to your imagination.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In the filter body you have access to everything you have in a grails controller so you have a great deal of flexibility here with what you can do. You could look at usernames, session data, whatever your heart desires. You can even redirect the request to another URL using the same conventions as you would have in a controller. So have at it!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28383337-4493151481074545894?l=hartsock.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/KbOyU/~4/Bg95vx-IOmQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://hartsock.blogspot.com/feeds/4493151481074545894/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=28383337&amp;postID=4493151481074545894" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/4493151481074545894?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/4493151481074545894?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/KbOyU/~3/Bg95vx-IOmQ/groovygrails-how-to-disable-controller.html" title="Groovy/Grails: How to disable a controller" /><author><name>Shawn Hartsock</name><uri>http://www.blogger.com/profile/07041739178513685832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_Y1izti3dd0w/SRtSwklBY9I/AAAAAAAAAR0/FYJePOEOrtQ/s1600-R/5d0da4a7693ba9c2edf0e82e4106f5e9%3Fs%3D80" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-By767SNeNuY/TVWfI3pC26I/AAAAAAAAA58/RuroYklguwc/s72-c/Selection_012.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://hartsock.blogspot.com/2011/02/groovygrails-how-to-disable-controller.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMEQnw7cSp7ImA9Wx9UEkg.&quot;"><id>tag:blogger.com,1999:blog-28383337.post-385196263950495086</id><published>2011-02-09T08:00:00.006-05:00</published><updated>2011-02-09T08:00:03.209-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-09T08:00:03.209-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="opinion" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><title>double entendre</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/63cYoVDtkF1YrLyxJkACtCZo2t4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/63cYoVDtkF1YrLyxJkACtCZo2t4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/63cYoVDtkF1YrLyxJkACtCZo2t4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/63cYoVDtkF1YrLyxJkACtCZo2t4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;I have said "The Future of Java is Groovy" and I meant it deliberately as a &lt;span style="font-style:italic;"&gt;double entendre&lt;/span&gt;. The future of Java is indeed &lt;span style="font-style:italic;"&gt;groovy&lt;/span&gt; and is indeed Groovy. This does not mean Java will be supplanted by Groovy, or some other language. Instead, the future of the JVM and the technology stack that calls the JVM home is tied more to technological off-shoots like Groovy than it is to any other purist re-engineering of the JVM or the core Java language.&lt;br /&gt;&lt;br /&gt;Java is what it &lt;span style="font-style:italic;"&gt;is&lt;/span&gt; at this point. Tools like Groovy give developers the chance to get a gentle introduction to new techniques such as &lt;a href="http://groovy.codehaus.org/Functional+Programming+with+Groovy"&gt;Functional Programming&lt;/a&gt;, &lt;a href="http://gpars.codehaus.org/"&gt;Parallel Computing&lt;/a&gt;, &lt;a href="http://www.justinspradlin.com/programming/groovy-domain-specific-language-tutorial/"&gt;Domain Specific Langauges&lt;/a&gt;, &lt;a href="http://groovy.codehaus.org/Dynamic+Groovy"&gt;Runtime Metaprogramming&lt;/a&gt;, and &lt;a href="http://groovy.codehaus.org/Compile-time+Metaprogramming+-+AST+Transformations"&gt;Compiletime Metaprogramming&lt;/a&gt;, as well as a whole host of other techniques and technologies.&lt;br /&gt;&lt;br /&gt;The beauty of Groovy as a programming language is how accessible it makes all these advanced techniques to a beginner and how readily it will get out of the way of an expert. This is a beautiful balance of the elegant and the ugly that few other languages manage to pull off well.&lt;br /&gt;&lt;br /&gt;Do I think Groovy will supplant Java on the JVM? No, not really. Do I think any other language will make that claim? I seriously doubt it. Do I think Java needs a successor? No. No I do not.&lt;br /&gt;&lt;br /&gt;The closest ecosystems that we can draw analogies to for the modern JVM are the .Net ecosystem and the C/C++ ecosystem. The C/C++ ecosystem is probably a better environment to draw lessons from since C/C++ long ago shed its lock-in with a single vendor (that being AT&amp;T long long ago).&lt;br /&gt;&lt;br /&gt;I think Java is growing up the same way the C/C++ ecosystem did and C hasn't really changed much over the years. I think Java needs to become the same kind of solid foundation. If other languages come and go on the JVM that needs to be &lt;i&gt;groovy&lt;/i&gt; with everyone.&lt;br /&gt;&lt;br /&gt;I don't steer any ships in the Groovy navy, I don't direct any plans or strategies, so what I say here is just what I say, and what I say is: &lt;blockquote&gt;Groovy allows rapid access to advanced computing concepts with a minimum extraneous cognitive load.&lt;/blockquote&gt; This is the Groovy language's strength. It is immediately accessible to anyone with any programming background. This accessibility is the vital engine for the success we are seeing in Groovy adoption. It is also the weakness of the language. It means that Groovy must necessarily avoid the traps of becoming too "beautiful" of a language forcing people into certain forms steepening its learning curve too sharply.&lt;br /&gt;&lt;br /&gt;That's my opinion anyway. I happen to be one those kinds of guys who likes what I can &lt;span style="font-style:italic;"&gt;do&lt;/span&gt; with a language. I tend to not get hung up on whether it is &lt;span style="font-style:italic;"&gt;pretty&lt;/span&gt;, or if it is &lt;span style="font-style:italic;"&gt;pure&lt;/span&gt;. It's all groovy man.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28383337-385196263950495086?l=hartsock.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/KbOyU/~4/ocGhAlVmY6c" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://hartsock.blogspot.com/feeds/385196263950495086/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=28383337&amp;postID=385196263950495086" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/385196263950495086?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/385196263950495086?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/KbOyU/~3/ocGhAlVmY6c/double-entendre.html" title="double entendre" /><author><name>Shawn Hartsock</name><uri>http://www.blogger.com/profile/07041739178513685832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_Y1izti3dd0w/SRtSwklBY9I/AAAAAAAAAR0/FYJePOEOrtQ/s1600-R/5d0da4a7693ba9c2edf0e82e4106f5e9%3Fs%3D80" /></author><thr:total>1</thr:total><feedburner:origLink>http://hartsock.blogspot.com/2011/02/double-entendre.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ck8DSHc6fCp7ImA9Wx9VFko.&quot;"><id>tag:blogger.com,1999:blog-28383337.post-8056675729875623176</id><published>2011-02-02T12:44:00.004-05:00</published><updated>2011-02-02T13:21:19.914-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-02T13:21:19.914-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="self" /><category scheme="http://www.blogger.com/atom/ns#" term="events" /><category scheme="http://www.blogger.com/atom/ns#" term="conversation" /><title>A late New Year's post.</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/LqMGvCKUqpq8XW_29qA4NwBqhMM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LqMGvCKUqpq8XW_29qA4NwBqhMM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/LqMGvCKUqpq8XW_29qA4NwBqhMM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/LqMGvCKUqpq8XW_29qA4NwBqhMM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;tl;dr &lt;span style="font-style:italic;"&gt;I am a consultant now.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It's a quite late, but I did make some new year's resolutions. One was a personal fitness resolution to run a mile every workday. The other was a professional resolution to "get out there" more and contribute more to the Groovy/Grails community. For most of 2010 I felt as if I were under a rock and not able to contribute to the community more and so I've made a couple of drastic moves. &lt;br /&gt;&lt;br /&gt;My first drastic move was to step-up my fitness routine. I have been working out 3 times a week now for a few years. This year I have stepped it up to 5 times a week. Yes. 5 times a week. My warm up is a 1 mile run.&lt;br /&gt;&lt;br /&gt;So far this year I've managed to run one mile every weekday (I give myself Saturday and Sunday off from running). So far, I haven't missed a day. I was inspired by my son's devotion to his Cross Country training and I have set myself some small goals for my running to try and achieve over the next few years. My big goal is to eventually run a Marathon. This seems utterly absurd to say, I have so very far to go before I can do something like that. Barring any medical reasons I fully intend to achieve that goal.&lt;br /&gt;&lt;br /&gt;My results this last month are encouraging. I started the year with a mile time of 15:44 (fifteen minutes and forty-four seconds) and I've managed to bring this down to 11:24 or so on my best day. I typically complete the mile now between 11:30 and 12:30 now. My goal is to make a 12 minute mile an easy run for me. If I can do that then I will begin increasing my mileage over time.&lt;br /&gt;&lt;br /&gt;The other one of those drastic moves was quitting my job at a company I dearly loved working at and really respected. It was a very hard decision to make but I decided that I wanted to invest more directly in the Open Source community and open source efforts. I believe strongly in the cause of Open Software and if I believe in it I should put my whole being behind what I say. So I've joined forces with &lt;a href="http://www.osintegrators.com/"&gt;Open Software Integrators&lt;/a&gt; which is a young Open Software consultancy based here in the Research Triangle area of North Carolina. We have a strong match for vision and attitude toward software development and I look forward to working with the team here to help companies reap benefits from Open Source software and toward making solid contributions back to the Open Source community.&lt;br /&gt;&lt;br /&gt;There have been a lot of preparations going on in making these transitions so I've not been as active here in this blog as I intended. I have made a resolution to also post more regularly here. It was this blog that enabled me to get published in GroovyMag, create the plugins that have taught me so much about living with open source software projects, and introduced me to so many of you.&lt;br /&gt;&lt;br /&gt;I hope that I can find a way in my new role to make a real positive impact on the open source community and fill a need that is currently under served. As always I'm open to your feedback and I find your comments valuable. I am currently looking for conferences that would be open to me speaking so your pointers will be welcome. Obviously, I can't attend them all but I will make a real effort this year. &lt;br /&gt;&lt;br /&gt;Thank you for reading and I hope I get meet some of you in person this year too!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28383337-8056675729875623176?l=hartsock.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/KbOyU/~4/XAjGhA18TRY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://hartsock.blogspot.com/feeds/8056675729875623176/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=28383337&amp;postID=8056675729875623176" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/8056675729875623176?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/8056675729875623176?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/KbOyU/~3/XAjGhA18TRY/late-new-years-post.html" title="A late New Year's post." /><author><name>Shawn Hartsock</name><uri>http://www.blogger.com/profile/07041739178513685832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_Y1izti3dd0w/SRtSwklBY9I/AAAAAAAAAR0/FYJePOEOrtQ/s1600-R/5d0da4a7693ba9c2edf0e82e4106f5e9%3Fs%3D80" /></author><thr:total>3</thr:total><feedburner:origLink>http://hartsock.blogspot.com/2011/02/late-new-years-post.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0MNR3w4cCp7ImA9Wx5UEEs.&quot;"><id>tag:blogger.com,1999:blog-28383337.post-6798494972508591936</id><published>2010-10-14T08:55:00.006-04:00</published><updated>2010-10-14T10:11:36.238-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-14T10:11:36.238-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="hibernate" /><category scheme="http://www.blogger.com/atom/ns#" term="junit" /><category scheme="http://www.blogger.com/atom/ns#" term="grails" /><category scheme="http://www.blogger.com/atom/ns#" term="database" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><category scheme="http://www.blogger.com/atom/ns#" term="audit" /><title>On the topic of Grails Audit Logging Plugin version 0.5.4</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Hn1UuYlZnVWuGfR0YnaM-ILvvIw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Hn1UuYlZnVWuGfR0YnaM-ILvvIw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Hn1UuYlZnVWuGfR0YnaM-ILvvIw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Hn1UuYlZnVWuGfR0YnaM-ILvvIw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Last night, I released a new version of my &lt;a href="http://www.grails.org/plugin/audit-logging"&gt;Audit Logging Plugin&lt;/a&gt;. Release notes are &lt;a href="http://jira.codehaus.org/browse/GRAILSPLUGINS/fixforversion/16581"&gt;here&lt;/a&gt;. There had been an outstanding compatibility issue with &lt;a href="http://www.grails.org/1.3+Release+Notes"&gt;Grails 1.3.x&lt;/a&gt; based on JUnit 4's Integration tests. The bug documented &lt;a href="http://jira.codehaus.org/browse/GRAILSPLUGINS-2187"&gt;here&lt;/a&gt; has been open for several months as I haven't had time to come back to the project to work on it.&lt;br /&gt;&lt;br /&gt;Normally I don't blog about tickets but I figure this one requires some attention because I've run into a few plugins that I need in my day job that are "broken" in 1.3.x and I'm not sure who else is having these troubles. In the interest of helping the community as a whole I want to cover my experience.&lt;br /&gt;&lt;br /&gt;It turns out that &lt;a href="http://jira.codehaus.org/browse/GRAILSPLUGINS-2243"&gt;GRAILSPLUGINS-2243&lt;/a&gt; (titled "Integration tests with auditable domain class do not observe test transaction boundary") is actually a more accurate description of the actual bug. The symptom is during integration testing you can't delete entities that are audited. If you take the same code and run it in development or production mode you &lt;i&gt;can&lt;/i&gt; delete the objects.&lt;br /&gt;&lt;br /&gt;The issue with my code is in this block... (extraneous logging and debugging code removed)&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Session session = sessionFactory.openSession()&lt;br /&gt;def trans = session.beginTransaction()&lt;br /&gt;def saved = session.merge(auditLogObject)&lt;br /&gt;session.flush()&lt;br /&gt;trans.commit()&lt;br /&gt;session.close()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Keep in mind this block functions exactly as expected in Grails 1.2 under all environments I know of. The one environment this code is horribly wrong is Grails 1.3.x in Integration testing. Only at that time does this code cause a problem.&lt;br /&gt;&lt;br /&gt;So let me ask you... what's wrong with this code?&lt;br /&gt;&lt;br /&gt;Before addressing the real issue, questions I anticipate:&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Why are you opening your own session?&lt;p&gt;Because on a transactional database in some cases the audit log must fire &lt;i&gt;after&lt;/i&gt; the database insert so that I can log the automatically assigned object Id. This means you can't use the open session without invalidating it.&lt;/p&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Why are you using merge and not save?&lt;p&gt;Because there are edge cases where the AuditLog object will be saved twice and I don't want to dictate the logic for that in this block to keep it simple&lt;/p&gt;&lt;/li&gt;&lt;div style="text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;li&gt;Why are you flushing the session?&lt;p&gt;Because we want to make sure the audit log is being written outside the regular transaction cycle and this particular session is going to perform no other job we want to ensure the log is written out to the database&lt;/p&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;So ... what is wrong with this code again?&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;def trans = session.beginTransaction()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Apparently, under &lt;b&gt;integration&lt;/b&gt; testing in Grails 1.3.x if you start a transaction in the way I have you will cause a problem with the other independent transactions in the rest of the application. This is simply &lt;b&gt;not&lt;/b&gt; the behavior I see in my production systems under Grails 1.2 or in my staging systems running Grails 1.3 for that matter.&lt;br /&gt;&lt;br /&gt;My solution is a bit of a work around. In the application context initialization for the Audit Logging plugin (the bit that runs just as you start up your grails application I have a block that does this...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;if( Environment.getCurrent() != Environment.PRODUCTION &amp;amp;&amp;amp; ConfigurationHolder.config.auditLog?.transactional == null ) {&lt;br /&gt;       transactional = false&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;... which simply says in environments that are &lt;i&gt;not&lt;/i&gt; production (Notice I'm using the Grails 1.1 API to find that breaking compatibility with Grails 1.0) the boolean flag "transactional" is set to false. I then wrapped the begin and commit calls to the transaction around a check on this boolean. For good measure, I gave the end developer the ability to override this behavior using the setting "auditLog.transactional" in their Config.groovy file. &lt;i&gt;(It would figure that I would release this as a feature and someone needs to use those transactions in their integration testing because they run their testing environment against Oracle or something so here's an out for you to get the old behaviors)&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;What took so much time to find this bug? It's not clear cut basically. I stumbled on this answer by blindly trying different things until I found a combination that worked. Then I tried to build a theory around this result that fit the facts that I had on hand.&lt;br /&gt;&lt;br /&gt;My theory is the JUnit 4 integration environment does something to the session factory so it does not really produce new sessions such that the session that I get in my plugin's &lt;i&gt;listener&lt;/i&gt; code is not really a separate session or transaction. I call commit on this transaction and when the session is returned to the normal GORM code it is already committed so the actual entity delete call can't happen and is swallowed.&lt;br /&gt;&lt;br /&gt;What is disturbing about this is &lt;i&gt;I didn't invent&lt;/i&gt; this technique for Audit Logging I'm implementing here. I created this code after being educated by &lt;a href="http://community.jboss.org/wiki/AuditLogging"&gt;the Hibernate wiki&lt;/a&gt;. This means if my theory holds it's not just a Grails application that will observe this strange-ness ... pretty much any Hibernate application with this kind of Audit Logging will be affected when integration tested under JUnit 4.&lt;br /&gt;&lt;br /&gt;Beyond just this anyone developing applications that open their own sessions independent of the GORM session may potentially see bugs during &lt;i&gt;integration&lt;/i&gt; testing that do not manifest in other environments. That can be a very difficult situation to deal with. So I've over documented things here for the benefit of the community at large.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;In other news...&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In other places I've noticed a change in Groovy 1.6 and 1.7's builder API. In particular I use RichUI in one project which makes calls like...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;builder.yield(" var ${attrs.yuiVariableName}DataSource = new YAHOO.util.XHRDataSource(\"${attrs?.action}\");\n", false)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;... under Groovy 1.6 &lt;i&gt;yeild&lt;/i&gt; was a builder method.&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;img src="http://3.bp.blogspot.com/_Y1izti3dd0w/TLcKImYTTjI/AAAAAAAAAwE/jrFtt0pxd-I/s400/Screen+shot+2010-10-14+at+9.47.26+AM.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5527898210478280242" style="display: block; margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; text-align: center; cursor: pointer; width: 400px; height: 80px; " /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;But, under Groovy 1.7 this method is not present. That means the HTML rendered by code that used the &lt;i&gt;yield&lt;/i&gt; and &lt;i&gt;yieldUnescaped&lt;/i&gt; calls now create tags &amp;lt;yield&amp;gt; and &amp;lt;yieldUnescaped&amp;gt; which breaks some pages (but not all).&lt;br /&gt;&lt;br /&gt;So far these are the only surprising issues I've run into that has kept Grails 1.3.x off of my production servers. I haven't yet seen and great benefit to 1.3 so I can't say I'm deeply compelled to move to the new version. &lt;br /&gt;&lt;br /&gt;I am looking to rewrite the plugin in light of &lt;a href="http://jira.codehaus.org/browse/GRAILS-5725"&gt;GRAILS-5725&lt;/a&gt; but this will be &lt;span style="font-style:italic;"&gt;a breaking change&lt;/span&gt;. Frankly, it's such a large change I'm surprised it was not pushed to Grails 1.4 ... however, it does not appear to interfere with the operation of plugins using the listener injection technique I am also using so no harm no foul.&lt;br /&gt;&lt;br /&gt;I see I've lost a &lt;i&gt;whole star&lt;/i&gt; in my plugin ratings so, my apologies to my end users who have not had a plugin that works with your Grails 1.3 integration tests. I sincerely hope I can earn back that extra star from you. Thanks for your support and help. I am reviewing code submissions for another version of the plugin coming up and I greatly appreciate your support.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28383337-6798494972508591936?l=hartsock.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/KbOyU/~4/tiEvjOTOIkg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://hartsock.blogspot.com/feeds/6798494972508591936/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=28383337&amp;postID=6798494972508591936" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/6798494972508591936?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/6798494972508591936?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/KbOyU/~3/tiEvjOTOIkg/on-topic-of-grails-audit-logging-plugin.html" title="On the topic of Grails Audit Logging Plugin version 0.5.4" /><author><name>Shawn Hartsock</name><uri>http://www.blogger.com/profile/07041739178513685832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_Y1izti3dd0w/SRtSwklBY9I/AAAAAAAAAR0/FYJePOEOrtQ/s1600-R/5d0da4a7693ba9c2edf0e82e4106f5e9%3Fs%3D80" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_Y1izti3dd0w/TLcKImYTTjI/AAAAAAAAAwE/jrFtt0pxd-I/s72-c/Screen+shot+2010-10-14+at+9.47.26+AM.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://hartsock.blogspot.com/2010/10/on-topic-of-grails-audit-logging-plugin.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkEMR385eSp7ImA9Wx5WGUk.&quot;"><id>tag:blogger.com,1999:blog-28383337.post-6023330828779715748</id><published>2010-09-30T22:27:00.008-04:00</published><updated>2010-10-01T10:51:26.121-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-01T10:51:26.121-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="qrcode" /><category scheme="http://www.blogger.com/atom/ns#" term="tridroid" /><category scheme="http://www.blogger.com/atom/ns#" term="android" /><title>TriDroid: QRCode, Linkulator &amp; other "move the data" ideas</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/jpZQpUrZafcv8u-1wOMBHoLv3aM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/jpZQpUrZafcv8u-1wOMBHoLv3aM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/jpZQpUrZafcv8u-1wOMBHoLv3aM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/jpZQpUrZafcv8u-1wOMBHoLv3aM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;At tonight's &lt;a href="http://www.meetup.com/TriDroid/calendar/14785106/"&gt;TriDroid&lt;/a&gt; we discussed QRCodes and other techniques for moving data between the environment and our Android phones. Here are hastily-hand-drawn my slides for anyone interested in them.&lt;br /&gt;&lt;br /&gt;&lt;iframe src="https://docs.google.com/present/embed?id=ajj7hrpdn7tk_43fcnh97gz" frameborder="0" width="410" height="342"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;Other things we talked about:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Chess Data format based on &lt;a href="http://en.wikipedia.org/wiki/Algebraic_chess_notation#Example"&gt;Algebraic Chess Notation&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://current.com/1n1sm4c"&gt;3D Barcodes&lt;/a&gt; for manufacturing&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://140.78.90.140/medien/ar/Pub/U4DB.pdf"&gt;4D barcodes&lt;/a&gt; (time phased codes for higher data density)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.hpl.hp.com/techreports/2010/HPL-2010-7.pdf"&gt;color barcodes&lt;/a&gt; where color is used as a new "dimension" to store data in.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;EDIT:&lt;br /&gt;&lt;br /&gt;As George points out (and many have pointed this out repeatedly) the &lt;a href="http://googlecode.blogspot.com/2008/07/qr-codes-now-available-on-google-chart.html"&gt;Google Chart API&lt;/a&gt; has had QRCodes incorporated in it for some time. Once again, being lazy would have paid off much more than working hard. A lesson the universe seems to be trying to teach me repeatedly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28383337-6023330828779715748?l=hartsock.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/KbOyU/~4/gaTqcO7PN-w" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://hartsock.blogspot.com/feeds/6023330828779715748/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=28383337&amp;postID=6023330828779715748" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/6023330828779715748?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/6023330828779715748?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/KbOyU/~3/gaTqcO7PN-w/tridroid-qrcode-linkulator-other-move.html" title="TriDroid: QRCode, Linkulator &amp; other &quot;move the data&quot; ideas" /><author><name>Shawn Hartsock</name><uri>http://www.blogger.com/profile/07041739178513685832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_Y1izti3dd0w/SRtSwklBY9I/AAAAAAAAAR0/FYJePOEOrtQ/s1600-R/5d0da4a7693ba9c2edf0e82e4106f5e9%3Fs%3D80" /></author><thr:total>1</thr:total><feedburner:origLink>http://hartsock.blogspot.com/2010/09/tridroid-qrcode-linkulator-other-move.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkUFRX4zfSp7ImA9WxFaEUw.&quot;"><id>tag:blogger.com,1999:blog-28383337.post-5888466802758076943</id><published>2010-07-14T08:51:00.004-04:00</published><updated>2010-07-14T09:30:14.085-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-14T09:30:14.085-04:00</app:edited><title>App Inventor</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/G-xc-fzjq6SxB2vxmfBWBAj_4KU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/G-xc-fzjq6SxB2vxmfBWBAj_4KU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/G-xc-fzjq6SxB2vxmfBWBAj_4KU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/G-xc-fzjq6SxB2vxmfBWBAj_4KU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;If you haven't heard about it &lt;a href="http://appinventor.googlelabs.com/about/"&gt;App Inventor&lt;/a&gt; is available to educators wanting to teach students about programming. It allows novice programmers to create Android applications using a graphical programming environment similar to &lt;a href="http://scratch.mit.edu/"&gt;Scratch&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;The educational perspective that motivates App Inventor holds that programming can be a vehicle for engaging powerful ideas through active learning. As such, it is part of an ongoing movement in computers and education that began with the work of Seymour Papert and the MIT Logo Group in the 1960s.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;This is probably one of the more interesting and exciting ways to engage lay-programmers in software creation. It is possible to view the graphical programming language blocks as a &lt;i&gt;Domain Specific Language&lt;/i&gt; but I'm not clear on whether this is actually the case or not. In particular:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;the types of statements are limited to available blocks&lt;/li&gt;&lt;br /&gt;&lt;li&gt;these statement blocks are limited to guided classifications specific to phone app development&lt;/li&gt;&lt;br /&gt;&lt;li&gt;user and device interactions are limited to the palette&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;In these ways the "developer" is "on-rails" (in the &lt;a href="http://en.wikipedia.org/wiki/Shoot_'em_up#Definition"&gt;video game&lt;/a&gt; sense) limited to a certain type of application. This kind of limitation is beneficial in some cases guiding the developer toward a "good" application. In this case the limitation keeps the developers from heading down paths that require knowledge about the halting problem or multi-threading. For this class of application... that's a good thing.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://dspace.mit.edu/handle/1721.1/41550"&gt;OpenBlock&lt;/a&gt; &lt;i&gt;abstract&lt;/i&gt; certainly &lt;i&gt;sounds&lt;/i&gt; like a description of a Domain Specific Language (emphasis added):&lt;br /&gt;&lt;blockquote&gt;Graphical programming systems have been built to lower the threshold to programming for beginners. However, because these systems were &lt;b&gt;designed to make programming more accessible to novices&lt;/b&gt;, they were developed with narrower intentions for their users and applications. For example, in StarLogo TNG, a graphical block programming environment, &lt;b&gt;users may create games and simulations, but they cannot use this same system to create programs&lt;/b&gt; that can automate their computer processes, like the text-based scripting system AppleScript. Application developers can create their own programming systems, but doing so can take a significant amount of time to design and implement. This thesis describes an extendable framework called OpenBlocks that enables application developers to build and iterate their own graphical block programming systems by specifying a single XML file. Application developers can &lt;b&gt;focus more on the design of their systems instead of oil the details of implementation&lt;/b&gt;. The design and implementation of OpenBlocks are described, along with a user study conducted to test its usability and extendability.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;On the other hand it could be argued that the graphical programming environment is just an immature environment and is only limited because of how new the tool set is. There is no intrinsic reason a graphic block based programming language couldn't eventually become as rich as a traditional text based language. The real differentiator between a (DSL) Domain Specific Language and a GPL (General Purpose Language) is that the scope of the programming done.&lt;br /&gt;&lt;br /&gt;You evolve a DSL either by creating a very rich API that "begins to talk" or you create a deliberately limited subset of your GPL that can be exposed and interpreted using limited API.&lt;br /&gt;&lt;br /&gt;So is App Inventor using a new(-ish) Domain Specific Language or a new way to wrap a General Purpose Language?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28383337-5888466802758076943?l=hartsock.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/KbOyU/~4/aipApAm2eTs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://hartsock.blogspot.com/feeds/5888466802758076943/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=28383337&amp;postID=5888466802758076943" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/5888466802758076943?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/5888466802758076943?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/KbOyU/~3/aipApAm2eTs/app-inventor.html" title="App Inventor" /><author><name>Shawn Hartsock</name><uri>http://www.blogger.com/profile/07041739178513685832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_Y1izti3dd0w/SRtSwklBY9I/AAAAAAAAAR0/FYJePOEOrtQ/s1600-R/5d0da4a7693ba9c2edf0e82e4106f5e9%3Fs%3D80" /></author><thr:total>0</thr:total><feedburner:origLink>http://hartsock.blogspot.com/2010/07/app-inventor.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkEAQ3k6fSp7ImA9WxFbFkQ.&quot;"><id>tag:blogger.com,1999:blog-28383337.post-757950609247677881</id><published>2010-07-09T11:10:00.008-04:00</published><updated>2010-07-09T11:50:42.715-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-09T11:50:42.715-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="video" /><category scheme="http://www.blogger.com/atom/ns#" term="qrcode" /><category scheme="http://www.blogger.com/atom/ns#" term="gaelyk" /><category scheme="http://www.blogger.com/atom/ns#" term="interview" /><category scheme="http://www.blogger.com/atom/ns#" term="pngj" /><category scheme="http://www.blogger.com/atom/ns#" term="google" /><category scheme="http://www.blogger.com/atom/ns#" term="opensource" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><category scheme="http://www.blogger.com/atom/ns#" term="appengine" /><title>Three Small Ideas</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/MtHjrGriJQ7eRhzsNqfL0YqemZw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MtHjrGriJQ7eRhzsNqfL0YqemZw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/MtHjrGriJQ7eRhzsNqfL0YqemZw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/MtHjrGriJQ7eRhzsNqfL0YqemZw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;I was glad to be interviewed by DZone a while ago. The second interview was on my current Open Source work and I gave what is probably a non-traditional answer on why Open Source contribution is important for a developer. The google appengine project I'm talking about is the &lt;a href="http://www.youtube.com/watch?v=5ex8sPrVeLQ"&gt;qrcode linkulator&lt;/a&gt;. And, for the record, I've got a better hair-cut now.&lt;br /&gt;&lt;br /&gt;&lt;embed src="http://blip.tv/play/hbZ3gei_WAI%2Em4v" type="application/x-shockwave-flash" width="480" height="367" allowscriptaccess="always" allowfullscreen="true"&gt;&lt;/embed&gt;&lt;br /&gt;&lt;br /&gt;My statistics are from this article on &lt;a href="http://en.wikipedia.org/wiki/Functional_fixedness"&gt;Functional Fixedness at wikipedia&lt;/a&gt;. The over-lapping concept I'm trying to tease out is that there are problem solving exercises that are not served by tightly focused environments like business. As a developer you need to be able to work in spaces that allow for creative freedom and the lessons you learn there (for better or worse) translate back into your "high pressure" environment. The result is a better developer that is able to think outside the parameters of the problem.&lt;br /&gt;&lt;br /&gt;A nice animation covering the idea popularized by &lt;a href="http://twitter.com/DanielPink"&gt;Daniel Pink&lt;/a&gt; (who is an infinitely better speaker) is on youtube:&lt;br /&gt;&lt;object width="640" height="385"&gt;&lt;param name="movie" value="http://www.youtube.com/v/Fe6Jgng4FZc&amp;amp;hl=en_US&amp;amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/Fe6Jgng4FZc&amp;amp;hl=en_US&amp;amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;My contribution is: not only is open source a product of intrinsic motivation... it &lt;i&gt;creates&lt;/i&gt; intrinsic motivation to improve yourself as a developer. These improvements translate back to your "day job" ... so for purely selfish reasons you *should* create open source code. You will be forced to learn. You'll get interaction with other developers. You'll learn much more than if you stay locked in your office and never get challenged by people who never would think like you do and have no reason to pretend they do.&lt;br /&gt;&lt;br /&gt;Even if the project is a failure and your contributions are insignificant... you'll learn something.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28383337-757950609247677881?l=hartsock.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/KbOyU/~4/9DjQLiRLjtU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://hartsock.blogspot.com/feeds/757950609247677881/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=28383337&amp;postID=757950609247677881" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/757950609247677881?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/757950609247677881?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/KbOyU/~3/9DjQLiRLjtU/three-small-ideas.html" title="Three Small Ideas" /><author><name>Shawn Hartsock</name><uri>http://www.blogger.com/profile/07041739178513685832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_Y1izti3dd0w/SRtSwklBY9I/AAAAAAAAAR0/FYJePOEOrtQ/s1600-R/5d0da4a7693ba9c2edf0e82e4106f5e9%3Fs%3D80" /></author><thr:total>2</thr:total><feedburner:origLink>http://hartsock.blogspot.com/2010/07/three-small-ideas.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak8AR385cSp7ImA9WxFUGE8.&quot;"><id>tag:blogger.com,1999:blog-28383337.post-6532158642703487732</id><published>2010-06-29T11:46:00.006-04:00</published><updated>2010-06-29T12:27:26.129-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-29T12:27:26.129-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="CAS" /><category scheme="http://www.blogger.com/atom/ns#" term="grails" /><category scheme="http://www.blogger.com/atom/ns#" term="Acegi" /><category scheme="http://www.blogger.com/atom/ns#" term="SpringSecurity" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><category scheme="http://www.blogger.com/atom/ns#" term="proxy" /><title>Grails + Acegi + CAS + Proxy Ticket</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/yZXbQy7zpjC6uuapHuNRC6wkjys/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yZXbQy7zpjC6uuapHuNRC6wkjys/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/yZXbQy7zpjC6uuapHuNRC6wkjys/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/yZXbQy7zpjC6uuapHuNRC6wkjys/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Should you have Acegi + CAS setup in Grails and you want to proxy a URL secured behind the same CAS instance you should do something like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;    URL url = new URL(urlString)&lt;br /&gt;    SecurityContext ctx = SecurityContextHolder.getContext();&lt;br /&gt;    CasAuthenticationToken auth = ctx?.getAuthentication();&lt;br /&gt;    Assertion assertion = auth?.getAssertion();&lt;br /&gt;    Principal principal = assertion?.getPrincipal();&lt;br /&gt;    assert principal.proxyRetriever != null &lt;br /&gt;   // the above line asserts that proxy system is properly setup and working&lt;br /&gt;    String proxyTicket = principal?.getProxyTicketFor(url?.toString());&lt;br /&gt;    assert proxyTicket != null&lt;br /&gt;    URL readUrl = new URL(url.toString() + "?ticket=${proxyTicket}")&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This only works if your CAS supports proxying and you have a working proxy call back. For details on troubleshooting this with &lt;a href="http://www.grails.org/plugin/acegi"&gt;Grails-Acegi 0.5.3&lt;/a&gt; see &lt;a href="http://jira.codehaus.org/browse/GRAILSPLUGINS-2231"&gt;GRAILSPLUGINS-2231&lt;/a&gt; which includes a working proxy callback controller. Hopefully this will be fixed in an upcoming version so you won't need this reference for long.&lt;br /&gt;&lt;br /&gt;If your setup is not working properly the proxyRetriever embedded in the Principal object will be null. If it is null then &lt;i&gt;getProxyTicketFor&lt;/i&gt; returns null no matter what. Once you get your CAS and SecurityConfig.groovy working properly the proxyRetriever starts getting magically injected into your application. This doesn't mean you actually have proxying working yet but you can almost rule out client-side configuration errors.&lt;br /&gt;&lt;br /&gt;Your Grails application should also have something at /secure/receptor that can catch responses issued by the CAS server. You should see this URI respond to something just after you successfully log in. That URI also needs to be open so the CAS server can post there without needing to login to itself.&lt;br /&gt;&lt;br /&gt;NOTE: your CAS server must be able to resolve the URL of the proxy call back. That means if you are running your proxy callback on localhost the responding CAS server must be able to post to that URL. Why? When you request a proxy granting ticket CAS will send the ticket back to your Grails application at the URI /secure/receptor by default. That means your application's URL must be resolvable by the CAS &lt;i&gt;server&lt;/i&gt; for proxy tickets to function. &lt;br /&gt;&lt;br /&gt;In practice, I run a small CAS server on localhost at an obscure port with the URL to proxy also on localhost when testing proxy ticket granting and other CAS secured proxy services. I work around the SSL issues by using a custom implementation of javax.net.ssl.HostnameVerifier that is installed during bootstrap in &lt;i&gt;development&lt;/i&gt; and &lt;i&gt;test-app&lt;/i&gt; modes only. The custom verifier (written in Java) looks like:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;import javax.net.ssl.HostnameVerifier;&lt;br /&gt;import javax.net.ssl.SSLSession;&lt;br /&gt;import javax.net.ssl.HttpsURLConnection;&lt;br /&gt;&lt;br /&gt;public class CustomHostnameVerifier implements HostnameVerifier {&lt;br /&gt;    public String[] exemptNames = {"localhost","testing.com","example.com"}; &lt;br /&gt;   // whatever hosts need exempting from having a "real" SSL certificate&lt;br /&gt;    public boolean verify(String hostname, SSLSession session) {&lt;br /&gt;        boolean exempt = false;&lt;br /&gt;        if(exemptNames != null) {&lt;br /&gt;            for(String name:exemptNames) {&lt;br /&gt;                if(hostname.toLowerCase().endsWith(name)) {&lt;br /&gt;                    exempt = true;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        return exempt;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    // call from BootStrap.groovy or other opportune initializer&lt;br /&gt;    public static void init() {&lt;br /&gt;        HttpsURLConnection.setDefaultHostnameVerifier(new CustomHostnameVerifier());&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Other work arounds would involve a staging CAS server that was able to resolve the development or testing host during work on proxying. These are up to you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28383337-6532158642703487732?l=hartsock.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/KbOyU/~4/VvpXLIgV0iY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://hartsock.blogspot.com/feeds/6532158642703487732/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=28383337&amp;postID=6532158642703487732" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/6532158642703487732?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/6532158642703487732?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/KbOyU/~3/VvpXLIgV0iY/grails-acegi-cas-proxy-ticket.html" title="Grails + Acegi + CAS + Proxy Ticket" /><author><name>Shawn Hartsock</name><uri>http://www.blogger.com/profile/07041739178513685832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_Y1izti3dd0w/SRtSwklBY9I/AAAAAAAAAR0/FYJePOEOrtQ/s1600-R/5d0da4a7693ba9c2edf0e82e4106f5e9%3Fs%3D80" /></author><thr:total>0</thr:total><feedburner:origLink>http://hartsock.blogspot.com/2010/06/grails-acegi-cas-proxy-ticket.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkUGQXw6eCp7ImA9WxFUE0o.&quot;"><id>tag:blogger.com,1999:blog-28383337.post-4133148154821804429</id><published>2010-06-24T06:53:00.005-04:00</published><updated>2010-06-24T07:17:00.210-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-24T07:17:00.210-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="DSL" /><category scheme="http://www.blogger.com/atom/ns#" term="philosophy" /><category scheme="http://www.blogger.com/atom/ns#" term="domain specific languages" /><title>When NOT to use a Domain Specific Language</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/WZxKqNqK5fPqKkgtJJGjQ-1w-zc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/WZxKqNqK5fPqKkgtJJGjQ-1w-zc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/WZxKqNqK5fPqKkgtJJGjQ-1w-zc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/WZxKqNqK5fPqKkgtJJGjQ-1w-zc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;There's really one rule I can use to sum up why you would &lt;b&gt;not&lt;/b&gt; use a domain specific language.&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;Do not use a Domain Specific Language when implementation specifics out weigh domain specifics.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;This one rule covers numerous cases:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;when intimate knowledge of &lt;i&gt;API&lt;/i&gt; are as important as function&lt;/li&gt;&lt;br /&gt;&lt;li&gt;when performance is critical and requires expert knowledge&lt;/li&gt;&lt;br /&gt;&lt;li&gt;when implementation details are nearly as important as semantic details&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;All these cases and numerous variations on this theme are summed up by acknowledging that the choice of using a Domain Specific Language (DSL) is a design trade off. You are deliberately adding a layer to your application stack. This layer intrinsically incurs a maintenance and/or performance cost. (Not all DSL cost additional clock cycles at run time it depends on your implementation.)&lt;br /&gt;&lt;br /&gt;With these costs and benefits in mind you can make an intelligent choice about when and where to use this tool. It is far from a panacea but Domain Specific Languages do have the allure of potentially netting you accidental programmers and preserving folk knowledge about your system and its real world uses that few other techniques offer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28383337-4133148154821804429?l=hartsock.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/KbOyU/~4/K_tiYKDZLqk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://hartsock.blogspot.com/feeds/4133148154821804429/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=28383337&amp;postID=4133148154821804429" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/4133148154821804429?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/4133148154821804429?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/KbOyU/~3/K_tiYKDZLqk/when-not-to-use-domain-specific.html" title="When NOT to use a Domain Specific Language" /><author><name>Shawn Hartsock</name><uri>http://www.blogger.com/profile/07041739178513685832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_Y1izti3dd0w/SRtSwklBY9I/AAAAAAAAAR0/FYJePOEOrtQ/s1600-R/5d0da4a7693ba9c2edf0e82e4106f5e9%3Fs%3D80" /></author><thr:total>0</thr:total><feedburner:origLink>http://hartsock.blogspot.com/2010/06/when-not-to-use-domain-specific.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkIHR3wycSp7ImA9WxFSFE4.&quot;"><id>tag:blogger.com,1999:blog-28383337.post-8778475375200512738</id><published>2010-04-16T09:39:00.004-04:00</published><updated>2010-04-16T11:08:56.299-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-04-16T11:08:56.299-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dataSource" /><category scheme="http://www.blogger.com/atom/ns#" term="configuration" /><category scheme="http://www.blogger.com/atom/ns#" term="howto" /><category scheme="http://www.blogger.com/atom/ns#" term="grails" /><category scheme="http://www.blogger.com/atom/ns#" term="database" /><category scheme="http://www.blogger.com/atom/ns#" term="jboss" /><category scheme="http://www.blogger.com/atom/ns#" term="trick" /><title>Never edit icky JBoss XML files again!</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/-LEimfzpmx3aamra8y24XDx9Wys/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-LEimfzpmx3aamra8y24XDx9Wys/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/-LEimfzpmx3aamra8y24XDx9Wys/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/-LEimfzpmx3aamra8y24XDx9Wys/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;Do you have a JBoss application server? Do you have configuration files in that server that need to be edited or changed periodically? Do you have an allergy to XML?&lt;br /&gt;&lt;br /&gt;Have I got a solution for you!&lt;br /&gt;&lt;br /&gt;JBoss has the amazing ability to load *.properties files from any location (on the file system or on the internet) as part of its start up routine. So you can set properties in a simple properties file instead of an icky XML file.&lt;br /&gt;&lt;br /&gt;NOTE: I'll refer to the directory you have installed JBoss into as $JBOSS_HOME you may have your JBoss server installed in /opt/jboss or /usr/local/jboss for example. It doesn't matter.&lt;br /&gt;&lt;br /&gt;NOTE: I'll assume your JBoss is set up to load the "default" server directory. If it isn't then I think you are smart enough to figure out what to do on your own.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Stop the JBoss server&lt;/li&gt;&lt;br /&gt;&lt;li&gt;open the file $JBOSS_HOME/server/default/deploy/properties-service.xml in your favorite text editor.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Find the tag &lt;pre&gt;&amp;lt;mbean code="org.jboss.varia.property.SystemPropertiesService" &lt;br /&gt;  name="jboss:type=Service,name=SystemProperties"&amp;gt;&lt;/pre&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Add this tag:&lt;br /&gt; &lt;pre&gt;&amp;lt;attribute name="URLList"&amp;gt;&lt;br /&gt;      /etc/jboss/system.properties&lt;br /&gt;&amp;lt;/attribute&amp;gt;&lt;/pre&gt; &lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Comment out or delete any other instances of the &amp;lt;attribute name="URLList"&amp;gt; &lt;i&gt;...&lt;/i&gt; &amp;lt;/attribute&amp;gt; tag&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Great! Now when we start up the JBoss server again it will read the file /etc/jboss/system.properties and set its properties from there. But, wait... the file doesn't exist yet. If I start my JBoss server and that file isn't easily readable it will &lt;b&gt;crash&lt;/b&gt;.&lt;br /&gt;&lt;br /&gt;So let's create the directory...&lt;br /&gt;&lt;pre&gt;$ sudo mkdir -p /etc/jboss&lt;/pre&gt;&lt;br /&gt;... and the file ...&lt;br /&gt;&lt;pre&gt;$ sudo touch /etc/jboss/system.properties&lt;/pre&gt;&lt;br /&gt;... now we can restart JBoss safely.&lt;br /&gt;&lt;br /&gt;We don't get much benefit yet though. Nothing in JBoss is using that file. So let's take a database-ds.xml file and configure it to use &lt;i&gt;system.properties&lt;/i&gt; for its connector-url, user-name, and password.&lt;br /&gt;&lt;br /&gt;Assuming you have a file like $JBOSS_HOME/server/default/deploy/database-ds.xml you can edit it to look like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;br /&gt;&amp;lt;datasources&amp;gt;&lt;br /&gt;   &amp;lt;local-tx-datasource&amp;gt;&lt;br /&gt;      &amp;lt;jndi-name&amp;gt;MyDatabaseDS&amp;lt;/jndi-name&amp;gt;&lt;br /&gt;      &lt;br /&gt;      &amp;lt;connection-url&amp;gt;&lt;b&gt;${MyDatabaseDS.connection-url}&lt;/b&gt;&amp;lt;/connection-url&amp;gt;&lt;br /&gt;      &amp;lt;driver-class&amp;gt;&lt;b&gt;${MyDatabaseDS.driver-class}&lt;/b&gt;&amp;lt;/driver-class&amp;gt;&lt;br /&gt;      &amp;lt;user-name&amp;gt;&lt;b&gt;${MyDatabaseDS.user-name}&lt;/b&gt;&amp;lt;/user-name&amp;gt;&lt;br /&gt;      &amp;lt;password&amp;gt;&lt;b&gt;${MyDatabaseDS.password}&lt;/b&gt;&amp;lt;/password&amp;gt;&lt;br /&gt;      &lt;br /&gt;      &amp;lt;min-pool-size&amp;gt;10&amp;lt;/min-pool-size&amp;gt;&lt;br /&gt;      &amp;lt;max-pool-size&amp;gt;20&amp;lt;/max-pool-size&amp;gt;&lt;br /&gt;      &amp;lt;prepared-statement-cache-size&amp;gt;10&amp;lt;/prepared-statement-cache-size&amp;gt;      &lt;br /&gt;   &amp;lt;/local-tx-datasource&amp;gt;&lt;br /&gt;&amp;lt;/datasources&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now edit /etc/jboss/system.properties to hold those values... it should look like this&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# config for database-ds.xml&lt;br /&gt;MyDatabaseDS.connection-url=jdbc:postgresql://localhost:5432/database&lt;br /&gt;MyDatabaseDS.driver-class=org.postgresql.Driver&lt;br /&gt;MyDatabaseDS.user-name=username&lt;br /&gt;MyDatabaseDS.password=password&lt;br /&gt;# this example is for postgresql but you could substitute any database.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;... when you start up JBoss it will read the &lt;i&gt;/etc/jboss/system.properties&lt;/i&gt; file and when it looks at &lt;i&gt;database-ds.xml&lt;/i&gt; it will see the &lt;b&gt;${variable}&lt;/b&gt; values and substitute the values you set in &lt;i&gt;system.properties&lt;/i&gt; for the &lt;b&gt;${variable}&lt;/b&gt;. If a &lt;b&gt;${variable}&lt;/b&gt; is not present, there will be no substitution... so be sure that every time you use a variable you set its value somewhere.&lt;br /&gt;&lt;br /&gt;You can also set system wide system properties this way too. Commonly on servers that I work with the unix host name has nothing to do with the hostname being served. So I commonly set:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;server.host=server.example.com&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;For use in my Grails applications which I then read in Config.groovy like this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;grails.serverURL = "https://${System.getProperty('server.host')}/${appName}"&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;... but that is another story ...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28383337-8778475375200512738?l=hartsock.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/KbOyU/~4/ee5MTvnobUU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://hartsock.blogspot.com/feeds/8778475375200512738/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=28383337&amp;postID=8778475375200512738" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/8778475375200512738?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/8778475375200512738?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/KbOyU/~3/ee5MTvnobUU/never-edit-icky-jboss-xml-files-again.html" title="Never edit icky JBoss XML files again!" /><author><name>Shawn Hartsock</name><uri>http://www.blogger.com/profile/07041739178513685832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_Y1izti3dd0w/SRtSwklBY9I/AAAAAAAAAR0/FYJePOEOrtQ/s1600-R/5d0da4a7693ba9c2edf0e82e4106f5e9%3Fs%3D80" /></author><thr:total>2</thr:total><feedburner:origLink>http://hartsock.blogspot.com/2010/04/never-edit-icky-jboss-xml-files-again.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEUFSHczcSp7ImA9WxBaGUg.&quot;"><id>tag:blogger.com,1999:blog-28383337.post-1162681679595079120</id><published>2010-03-30T08:58:00.003-04:00</published><updated>2010-03-30T09:36:59.989-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-30T09:36:59.989-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="qrcode" /><category scheme="http://www.blogger.com/atom/ns#" term="gaelyk" /><category scheme="http://www.blogger.com/atom/ns#" term="cloud" /><category scheme="http://www.blogger.com/atom/ns#" term="java.awt.Color" /><category scheme="http://www.blogger.com/atom/ns#" term="google" /><category scheme="http://www.blogger.com/atom/ns#" term="android" /><category scheme="http://www.blogger.com/atom/ns#" term="appengine" /><title>QRCode Linkulator the interesting bit.</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/sAcEDWqm_Q0nztB0rB_rU4tlX10/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/sAcEDWqm_Q0nztB0rB_rU4tlX10/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/sAcEDWqm_Q0nztB0rB_rU4tlX10/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/sAcEDWqm_Q0nztB0rB_rU4tlX10/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;For me the interesting bit about writing &lt;a href="http://qrcodelinkulator.appspot.com/"&gt;QRCode Linkulator&lt;/a&gt; was creating a PNG on AppEngine. The &lt;a href="http://code.google.com/appengine/docs/java/jrewhitelist.html"&gt;JRE Class White List&lt;/a&gt; doesn't include any Graphical libraries. Notice that most of java.awt.* is missing?&lt;br /&gt;&lt;br /&gt;Why would Google do that? Well, try downloading a copy of the OpenJDK. Go ahead. I'll wait. Got it now? Great. Now look in openjdk-6-src&lt;your-version&gt;/jdk/src/share/native/sun/awt ... what do you see? A mess of native C code.&lt;br /&gt;&lt;br /&gt;So key components of OpenJDK are written in C. Key components of AWT. That means if you want to do graphics (server side) in Java you need to hit some chunks of C code. I bet that's dangerous in AppEngine.&lt;br /&gt;&lt;br /&gt;Combine this with the fact that &lt;a href="http://code.google.com/p/pngj/"&gt;pngj&lt;/a&gt; is the only project I could find that had a pure Java implementation of the &lt;a href="http://www.w3.org/TR/PNG/"&gt;PNG&lt;/a&gt; specification and the challenge of doing the "&lt;a href="http://code.google.com/p/googleappengine/issues/detail?id=1423"&gt;impossible&lt;/a&gt;" and the temptation to pull this off was irresistible. Consider &lt;a href="http://sourceforge.net/tracker/?func=detail&amp;aid=2810312&amp;group_id=15255&amp;atid=365255"&gt;how&lt;/a&gt; &lt;a href="http://mail-archives.apache.org/mod_mbox/poi-dev/200907.mbox/%3Cbug-47497-47293@https.issues.apache.org/bugzilla/%3E"&gt;many&lt;/a&gt; &lt;a href="http://www.aspose.com/community/forums/thread/226124/google-app-engine-java-aspose-words.aspx"&gt;programs&lt;/a&gt; &lt;a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=446827"&gt;rely&lt;/a&gt; on &lt;a href="http://koders.com/default.aspx?s=java.awt.Color&amp;submit=Search&amp;la=*&amp;li=*"&gt;those classes&lt;/a&gt; and there is NO pure Java solution in existence.&lt;br /&gt;&lt;br /&gt;At my current workplace we do a lot with cloud computing. Because of this I've got a special sympathy for the guys working on AppEngine. They probably have some technical infrastructural reason they can't let you get at those AWT classes either directly or indirectly. My guess is it has to do with how they implemented the custom JRE that your app runs in.&lt;br /&gt;&lt;br /&gt;That combined with an interesting socio-economic constraint they placed on AppEngine applications makes me think that AppEngine isn't just "free" as in beer hosting but really an interesting way for Google to codify their chief aesthetic concerns about how applications function. &lt;br /&gt;&lt;br /&gt;This aesthetic is born of cloud computing on a scale no other company gets close to. At this scale, apparently, an aesthetic similar to that found in embedded systems starts to come through. Which in my mind is extremely ironic. See... I've been doing some Android development lately.&lt;br /&gt;&lt;br /&gt;Consider that your app-engine app may be sitting cold with no one using it. Then the user hits the application for the first time... perhaps deep linking into your application. The deep link re-activates the app. It's cold, dark, and if you are a scripting environment... not compiled requiring an interpreter to fire up, load your script and then interpret it.&lt;br /&gt;&lt;br /&gt;Huge penalties in that environment. So I hear some clever developers have kept their applications hot by writing Google AppEngine &lt;a href="http://code.google.com/appengine/docs/java/config/cron.html"&gt;Cron Jobs&lt;/a&gt; which hit the web application in some low cost way to keep it warm. That's pretty clever. But only works until your application scales.&lt;br /&gt;&lt;br /&gt;Yes. That's right. It works until your application becomes really really popular. Why?&lt;br /&gt;&lt;br /&gt;When your application scales your application is going to get provisioned with another "machine" on the Google Cloud. That application will be cold. You'll pay the warm up penalty for that application and that first user gets the raw deal having to wait while your app spins up. Bad news. This happens every time your app scales up one "machine" and the net effect can be &lt;a href="http://failwhale.com/"&gt;Fail Whale&lt;/a&gt; like badness.&lt;br /&gt;&lt;br /&gt;Besides, inflating your own app's "popularity" by "hitting yourself" seems a tad... well... evil. So please. Stop hitting yourself.&lt;br /&gt;&lt;br /&gt;The "right" answer is to somehow mitigate that first page hit cost. You get that first page view cost down as close to zero as you can... then take it a little farther.&lt;br /&gt;&lt;br /&gt;How? Anyone have ideas?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28383337-1162681679595079120?l=hartsock.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/KbOyU/~4/K-PZOYgGVnA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://hartsock.blogspot.com/feeds/1162681679595079120/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=28383337&amp;postID=1162681679595079120" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/1162681679595079120?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/1162681679595079120?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/KbOyU/~3/K-PZOYgGVnA/qrcode-linkulator-interesting-bit.html" title="QRCode Linkulator the interesting bit." /><author><name>Shawn Hartsock</name><uri>http://www.blogger.com/profile/07041739178513685832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_Y1izti3dd0w/SRtSwklBY9I/AAAAAAAAAR0/FYJePOEOrtQ/s1600-R/5d0da4a7693ba9c2edf0e82e4106f5e9%3Fs%3D80" /></author><thr:total>3</thr:total><feedburner:origLink>http://hartsock.blogspot.com/2010/03/qrcode-linkulator-interesting-bit.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUMEQXc4fSp7ImA9WxFbFUQ.&quot;"><id>tag:blogger.com,1999:blog-28383337.post-5836562219785872216</id><published>2010-03-28T13:47:00.005-04:00</published><updated>2010-07-08T09:56:40.935-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-08T09:56:40.935-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="qrcode" /><category scheme="http://www.blogger.com/atom/ns#" term="gaelyk" /><category scheme="http://www.blogger.com/atom/ns#" term="groovy" /><title>QRCode Linkulator speaking Gaelyk</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/wqcYy14PK0nRBje3UOp-mSnFD6I/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wqcYy14PK0nRBje3UOp-mSnFD6I/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/wqcYy14PK0nRBje3UOp-mSnFD6I/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wqcYy14PK0nRBje3UOp-mSnFD6I/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;I've just written my first application using &lt;a href="http://gaelyk.appspot.com/"&gt;Gaelyk&lt;/a&gt; a &lt;a href="http://groovy.codehaus.org/"&gt;Groovy&lt;/a&gt; based framework for &lt;a href="http://code.google.com/appengine/"&gt;Google App Engine&lt;/a&gt;. I ported the &lt;a href="http://grails.org/plugin/qrcode"&gt;qrcode plugin&lt;/a&gt; I had written for &lt;a href="http://grails.org/"&gt;Grails&lt;/a&gt; over to &lt;a href="http://gaelyk.appspot.com/"&gt;Gaelyk&lt;/a&gt; in a matter of hours.&lt;br /&gt;&lt;br /&gt;This isn't really an application for iPhone or Android but it relies on the &lt;a href="http://zxing.googlecode.com/files/BarcodeScanner3.21.apk"&gt;Barcode Scanner&lt;/a&gt; on Android or an app like &lt;br /&gt;         &lt;a href="http://phobos.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=292197557&amp;mt=8"&gt;Barcodes&lt;/a&gt; on the iTunes AppStore for iPhone. Combined with a tiny "bookmarklet" I found the result is quite useful for moving a link between my desktop and my phone. I made a &lt;a href="http://www.youtube.com/watch?v=5ex8sPrVeLQ"&gt;demonstration video&lt;/a&gt; since this can be a little hard to explain.&lt;br /&gt;&lt;br /&gt;You can get a gander at the app here: &lt;a href="http://qrcodelinkulator.appspot.com/"&gt;QRCode Linkulator&lt;/a&gt;. I make use of the HTTP referer header property to determine where you came from so if you were to click &lt;a href="http://qrcodelinkulator.appspot.com/300"&gt;http://qrcodelinkulator.appspot.com/300&lt;/a&gt; for example then you would get a QRCode for the URL you were at *before* you clicked the link. The error mode (should you have no "referer" associated with your browser (for example if you were to right-click the link and open it in a new window) is just the logo for the app.&lt;br /&gt;&lt;br /&gt;You might notice I tested out this feature in my blog. When you hit a given page in my blog there will be a QRCode for the URL you are currently looking at embedded in the page. This is done with simple image tags and no javascript.&lt;br /&gt;&lt;br /&gt;Right now, I'm just hosting the app on the free AppEngine account and hoping that is enough CPU + Bandwidth for the application.  I'm also hoping to stress-test the app a little to get a feel for how things scale. So far &lt;a href="http://gaelyk.appspot.com/"&gt;Gaelyk&lt;/a&gt; is running error free. I'm quite pleased with the simplicity of the framework and the price is right for App Engine hosting.&lt;br /&gt;&lt;br /&gt;I doubt I'll get enough traffic to have to worry about paying for the service if the app gets that popular I'll have to figure out how to get it to pay for itself. Any ideas?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28383337-5836562219785872216?l=hartsock.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/KbOyU/~4/cE_DX8ni0tA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://hartsock.blogspot.com/feeds/5836562219785872216/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=28383337&amp;postID=5836562219785872216" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/5836562219785872216?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/5836562219785872216?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/KbOyU/~3/cE_DX8ni0tA/qrcode-linkulator-speaking-gaelyk.html" title="QRCode Linkulator speaking Gaelyk" /><author><name>Shawn Hartsock</name><uri>http://www.blogger.com/profile/07041739178513685832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_Y1izti3dd0w/SRtSwklBY9I/AAAAAAAAAR0/FYJePOEOrtQ/s1600-R/5d0da4a7693ba9c2edf0e82e4106f5e9%3Fs%3D80" /></author><thr:total>2</thr:total><feedburner:origLink>http://hartsock.blogspot.com/2010/03/qrcode-linkulator-speaking-gaelyk.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEEEQH0yfSp7ImA9WxBbF0k.&quot;"><id>tag:blogger.com,1999:blog-28383337.post-5195129786310190047</id><published>2010-03-16T08:30:00.002-04:00</published><updated>2010-03-16T08:30:01.395-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-16T08:30:01.395-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="DSL" /><title>Domain Specific Languages @ TriJUG</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/T7QYwfA7QWbpFEdMSW5YeMH_86c/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/T7QYwfA7QWbpFEdMSW5YeMH_86c/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/T7QYwfA7QWbpFEdMSW5YeMH_86c/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/T7QYwfA7QWbpFEdMSW5YeMH_86c/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;&lt;iframe src="http://docs.google.com/present/embed?id=ajj7hrpdn7tk_30qn8nmbg9" frameborder="0" width="410" height="342"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;This version of my DSL talk focused on architectural implications of Domain Specific Languages. Less time is spent on language details and I dive right into creating the language.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28383337-5195129786310190047?l=hartsock.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/KbOyU/~4/Yy-x9yHP7dU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://hartsock.blogspot.com/feeds/5195129786310190047/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=28383337&amp;postID=5195129786310190047" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/5195129786310190047?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/5195129786310190047?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/KbOyU/~3/Yy-x9yHP7dU/domain-specific-languages-trijug.html" title="Domain Specific Languages @ TriJUG" /><author><name>Shawn Hartsock</name><uri>http://www.blogger.com/profile/07041739178513685832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_Y1izti3dd0w/SRtSwklBY9I/AAAAAAAAAR0/FYJePOEOrtQ/s1600-R/5d0da4a7693ba9c2edf0e82e4106f5e9%3Fs%3D80" /></author><thr:total>2</thr:total><feedburner:origLink>http://hartsock.blogspot.com/2010/03/domain-specific-languages-trijug.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU8BSXw8fCp7ImA9WxBUFUk.&quot;"><id>tag:blogger.com,1999:blog-28383337.post-3989554451824658552</id><published>2010-03-02T11:36:00.001-05:00</published><updated>2010-03-02T11:37:38.274-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-02T11:37:38.274-05:00</app:edited><title>Speaking at TriJUG</title><content type="html">
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/zbCTV1KwF9bpFFjcmoLfEc-ami8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zbCTV1KwF9bpFFjcmoLfEc-ami8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/zbCTV1KwF9bpFFjcmoLfEc-ami8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/zbCTV1KwF9bpFFjcmoLfEc-ami8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;I'll be giving a version of my DSL talk at &lt;a href="http://trijug.org/"&gt;TriJUG&lt;/a&gt; coming up March 15th.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/28383337-3989554451824658552?l=hartsock.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/blogspot/KbOyU/~4/rvni1e2Nq1c" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://hartsock.blogspot.com/feeds/3989554451824658552/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=28383337&amp;postID=3989554451824658552" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/3989554451824658552?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/28383337/posts/default/3989554451824658552?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/blogspot/KbOyU/~3/rvni1e2Nq1c/speaking-at-trijug.html" title="Speaking at TriJUG" /><author><name>Shawn Hartsock</name><uri>http://www.blogger.com/profile/07041739178513685832</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="http://1.bp.blogspot.com/_Y1izti3dd0w/SRtSwklBY9I/AAAAAAAAAR0/FYJePOEOrtQ/s1600-R/5d0da4a7693ba9c2edf0e82e4106f5e9%3Fs%3D80" /></author><thr:total>0</thr:total><feedburner:origLink>http://hartsock.blogspot.com/2010/03/speaking-at-trijug.html</feedburner:origLink></entry></feed>

